Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 
0011 
0012 #if (NGX_THREADS)
0013 #include <ngx_thread_pool.h>
0014 static void ngx_thread_read_handler(void *data, ngx_log_t *log);
0015 static void ngx_thread_write_chain_to_file_handler(void *data, ngx_log_t *log);
0016 #endif
0017 
0018 static ngx_chain_t *ngx_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *cl);
0019 static ssize_t ngx_writev_file(ngx_file_t *file, ngx_iovec_t *vec,
0020     off_t offset);
0021 
0022 
0023 #if (NGX_HAVE_FILE_AIO)
0024 
0025 ngx_uint_t  ngx_file_aio = 1;
0026 
0027 #endif
0028 
0029 
0030 ssize_t
0031 ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
0032 {
0033     ssize_t  n;
0034 
0035     ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
0036                    "read: %d, %p, %uz, %O", file->fd, buf, size, offset);
0037 
0038 #if (NGX_HAVE_PREAD)
0039 
0040     n = pread(file->fd, buf, size, offset);
0041 
0042     if (n == -1) {
0043         ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
0044                       "pread() \"%s\" failed", file->name.data);
0045         return NGX_ERROR;
0046     }
0047 
0048 #else
0049 
0050     if (file->sys_offset != offset) {
0051         if (lseek(file->fd, offset, SEEK_SET) == -1) {
0052             ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
0053                           "lseek() \"%s\" failed", file->name.data);
0054             return NGX_ERROR;
0055         }
0056 
0057         file->sys_offset = offset;
0058     }
0059 
0060     n = read(file->fd, buf, size);
0061 
0062     if (n == -1) {
0063         ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
0064                       "read() \"%s\" failed", file->name.data);
0065         return NGX_ERROR;
0066     }
0067 
0068     file->sys_offset += n;
0069 
0070 #endif
0071 
0072     file->offset += n;
0073 
0074     return n;
0075 }
0076 
0077 
0078 #if (NGX_THREADS)
0079 
0080 typedef struct {
0081     ngx_fd_t       fd;
0082     ngx_uint_t     write;   /* unsigned  write:1; */
0083 
0084     u_char        *buf;
0085     size_t         size;
0086     ngx_chain_t   *chain;
0087     off_t          offset;
0088 
0089     size_t         nbytes;
0090     ngx_err_t      err;
0091 } ngx_thread_file_ctx_t;
0092 
0093 
0094 ssize_t
0095 ngx_thread_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
0096     ngx_pool_t *pool)
0097 {
0098     ngx_thread_task_t      *task;
0099     ngx_thread_file_ctx_t  *ctx;
0100 
0101     ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
0102                    "thread read: %d, %p, %uz, %O",
0103                    file->fd, buf, size, offset);
0104 
0105     task = file->thread_task;
0106 
0107     if (task == NULL) {
0108         task = ngx_thread_task_alloc(pool, sizeof(ngx_thread_file_ctx_t));
0109         if (task == NULL) {
0110             return NGX_ERROR;
0111         }
0112 
0113         file->thread_task = task;
0114     }
0115 
0116     ctx = task->ctx;
0117 
0118     if (task->event.complete) {
0119         task->event.complete = 0;
0120 
0121         if (ctx->write) {
0122             ngx_log_error(NGX_LOG_ALERT, file->log, 0,
0123                           "invalid thread call, read instead of write");
0124             return NGX_ERROR;
0125         }
0126 
0127         if (ctx->err) {
0128             ngx_log_error(NGX_LOG_CRIT, file->log, ctx->err,
0129                           "pread() \"%s\" failed", file->name.data);
0130             return NGX_ERROR;
0131         }
0132 
0133         return ctx->nbytes;
0134     }
0135 
0136     task->handler = ngx_thread_read_handler;
0137 
0138     ctx->write = 0;
0139 
0140     ctx->fd = file->fd;
0141     ctx->buf = buf;
0142     ctx->size = size;
0143     ctx->offset = offset;
0144 
0145     if (file->thread_handler(task, file) != NGX_OK) {
0146         return NGX_ERROR;
0147     }
0148 
0149     return NGX_AGAIN;
0150 }
0151 
0152 
0153 #if (NGX_HAVE_PREAD)
0154 
0155 static void
0156 ngx_thread_read_handler(void *data, ngx_log_t *log)
0157 {
0158     ngx_thread_file_ctx_t *ctx = data;
0159 
0160     ssize_t  n;
0161 
0162     ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "thread read handler");
0163 
0164     n = pread(ctx->fd, ctx->buf, ctx->size, ctx->offset);
0165 
0166     if (n == -1) {
0167         ctx->err = ngx_errno;
0168 
0169     } else {
0170         ctx->nbytes = n;
0171         ctx->err = 0;
0172     }
0173 
0174 #if 0
0175     ngx_time_update();
0176 #endif
0177 
0178     ngx_log_debug4(NGX_LOG_DEBUG_CORE, log, 0,
0179                    "pread: %z (err: %d) of %uz @%O",
0180                    n, ctx->err, ctx->size, ctx->offset);
0181 }
0182 
0183 #else
0184 
0185 #error pread() is required!
0186 
0187 #endif
0188 
0189 #endif /* NGX_THREADS */
0190 
0191 
0192 ssize_t
0193 ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
0194 {
0195     ssize_t    n, written;
0196     ngx_err_t  err;
0197 
0198     ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
0199                    "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
0200 
0201     written = 0;
0202 
0203 #if (NGX_HAVE_PWRITE)
0204 
0205     for ( ;; ) {
0206         n = pwrite(file->fd, buf + written, size, offset);
0207 
0208         if (n == -1) {
0209             err = ngx_errno;
0210 
0211             if (err == NGX_EINTR) {
0212                 ngx_log_debug0(NGX_LOG_DEBUG_CORE, file->log, err,
0213                                "pwrite() was interrupted");
0214                 continue;
0215             }
0216 
0217             ngx_log_error(NGX_LOG_CRIT, file->log, err,
0218                           "pwrite() \"%s\" failed", file->name.data);
0219             return NGX_ERROR;
0220         }
0221 
0222         file->offset += n;
0223         written += n;
0224 
0225         if ((size_t) n == size) {
0226             return written;
0227         }
0228 
0229         offset += n;
0230         size -= n;
0231     }
0232 
0233 #else
0234 
0235     if (file->sys_offset != offset) {
0236         if (lseek(file->fd, offset, SEEK_SET) == -1) {
0237             ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
0238                           "lseek() \"%s\" failed", file->name.data);
0239             return NGX_ERROR;
0240         }
0241 
0242         file->sys_offset = offset;
0243     }
0244 
0245     for ( ;; ) {
0246         n = write(file->fd, buf + written, size);
0247 
0248         if (n == -1) {
0249             err = ngx_errno;
0250 
0251             if (err == NGX_EINTR) {
0252                 ngx_log_debug0(NGX_LOG_DEBUG_CORE, file->log, err,
0253                                "write() was interrupted");
0254                 continue;
0255             }
0256 
0257             ngx_log_error(NGX_LOG_CRIT, file->log, err,
0258                           "write() \"%s\" failed", file->name.data);
0259             return NGX_ERROR;
0260         }
0261 
0262         file->sys_offset += n;
0263         file->offset += n;
0264         written += n;
0265 
0266         if ((size_t) n == size) {
0267             return written;
0268         }
0269 
0270         size -= n;
0271     }
0272 #endif
0273 }
0274 
0275 
0276 ngx_fd_t
0277 ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access)
0278 {
0279     ngx_fd_t  fd;
0280 
0281     fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR,
0282               access ? access : 0600);
0283 
0284     if (fd != -1 && !persistent) {
0285         (void) unlink((const char *) name);
0286     }
0287 
0288     return fd;
0289 }
0290 
0291 
0292 ssize_t
0293 ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
0294     ngx_pool_t *pool)
0295 {
0296     ssize_t        total, n;
0297     ngx_iovec_t    vec;
0298     struct iovec   iovs[NGX_IOVS_PREALLOCATE];
0299 
0300     /* use pwrite() if there is the only buf in a chain */
0301 
0302     if (cl->next == NULL) {
0303         return ngx_write_file(file, cl->buf->pos,
0304                               (size_t) (cl->buf->last - cl->buf->pos),
0305                               offset);
0306     }
0307 
0308     total = 0;
0309 
0310     vec.iovs = iovs;
0311     vec.nalloc = NGX_IOVS_PREALLOCATE;
0312 
0313     do {
0314         /* create the iovec and coalesce the neighbouring bufs */
0315         cl = ngx_chain_to_iovec(&vec, cl);
0316 
0317         /* use pwrite() if there is the only iovec buffer */
0318 
0319         if (vec.count == 1) {
0320             n = ngx_write_file(file, (u_char *) iovs[0].iov_base,
0321                                iovs[0].iov_len, offset);
0322 
0323             if (n == NGX_ERROR) {
0324                 return n;
0325             }
0326 
0327             return total + n;
0328         }
0329 
0330         n = ngx_writev_file(file, &vec, offset);
0331 
0332         if (n == NGX_ERROR) {
0333             return n;
0334         }
0335 
0336         offset += n;
0337         total += n;
0338 
0339     } while (cl);
0340 
0341     return total;
0342 }
0343 
0344 
0345 static ngx_chain_t *
0346 ngx_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *cl)
0347 {
0348     size_t         total, size;
0349     u_char        *prev;
0350     ngx_uint_t     n;
0351     struct iovec  *iov;
0352 
0353     iov = NULL;
0354     prev = NULL;
0355     total = 0;
0356     n = 0;
0357 
0358     for ( /* void */ ; cl; cl = cl->next) {
0359 
0360         if (ngx_buf_special(cl->buf)) {
0361             continue;
0362         }
0363 
0364         size = cl->buf->last - cl->buf->pos;
0365 
0366         if (prev == cl->buf->pos) {
0367             iov->iov_len += size;
0368 
0369         } else {
0370             if (n == vec->nalloc) {
0371                 break;
0372             }
0373 
0374             iov = &vec->iovs[n++];
0375 
0376             iov->iov_base = (void *) cl->buf->pos;
0377             iov->iov_len = size;
0378         }
0379 
0380         prev = cl->buf->pos + size;
0381         total += size;
0382     }
0383 
0384     vec->count = n;
0385     vec->size = total;
0386 
0387     return cl;
0388 }
0389 
0390 
0391 static ssize_t
0392 ngx_writev_file(ngx_file_t *file, ngx_iovec_t *vec, off_t offset)
0393 {
0394     ssize_t    n;
0395     ngx_err_t  err;
0396 
0397     ngx_log_debug3(NGX_LOG_DEBUG_CORE, file->log, 0,
0398                    "writev: %d, %uz, %O", file->fd, vec->size, offset);
0399 
0400 #if (NGX_HAVE_PWRITEV)
0401 
0402 eintr:
0403 
0404     n = pwritev(file->fd, vec->iovs, vec->count, offset);
0405 
0406     if (n == -1) {
0407         err = ngx_errno;
0408 
0409         if (err == NGX_EINTR) {
0410             ngx_log_debug0(NGX_LOG_DEBUG_CORE, file->log, err,
0411                            "pwritev() was interrupted");
0412             goto eintr;
0413         }
0414 
0415         ngx_log_error(NGX_LOG_CRIT, file->log, err,
0416                       "pwritev() \"%s\" failed", file->name.data);
0417         return NGX_ERROR;
0418     }
0419 
0420     if ((size_t) n != vec->size) {
0421         ngx_log_error(NGX_LOG_CRIT, file->log, 0,
0422                       "pwritev() \"%s\" has written only %z of %uz",
0423                       file->name.data, n, vec->size);
0424         return NGX_ERROR;
0425     }
0426 
0427 #else
0428 
0429     if (file->sys_offset != offset) {
0430         if (lseek(file->fd, offset, SEEK_SET) == -1) {
0431             ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
0432                           "lseek() \"%s\" failed", file->name.data);
0433             return NGX_ERROR;
0434         }
0435 
0436         file->sys_offset = offset;
0437     }
0438 
0439 eintr:
0440 
0441     n = writev(file->fd, vec->iovs, vec->count);
0442 
0443     if (n == -1) {
0444         err = ngx_errno;
0445 
0446         if (err == NGX_EINTR) {
0447             ngx_log_debug0(NGX_LOG_DEBUG_CORE, file->log, err,
0448                            "writev() was interrupted");
0449             goto eintr;
0450         }
0451 
0452         ngx_log_error(NGX_LOG_CRIT, file->log, err,
0453                       "writev() \"%s\" failed", file->name.data);
0454         return NGX_ERROR;
0455     }
0456 
0457     if ((size_t) n != vec->size) {
0458         ngx_log_error(NGX_LOG_CRIT, file->log, 0,
0459                       "writev() \"%s\" has written only %z of %uz",
0460                       file->name.data, n, vec->size);
0461         return NGX_ERROR;
0462     }
0463 
0464     file->sys_offset += n;
0465 
0466 #endif
0467 
0468     file->offset += n;
0469 
0470     return n;
0471 }
0472 
0473 
0474 #if (NGX_THREADS)
0475 
0476 ssize_t
0477 ngx_thread_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
0478     ngx_pool_t *pool)
0479 {
0480     ngx_thread_task_t      *task;
0481     ngx_thread_file_ctx_t  *ctx;
0482 
0483     ngx_log_debug3(NGX_LOG_DEBUG_CORE, file->log, 0,
0484                    "thread write chain: %d, %p, %O",
0485                    file->fd, cl, offset);
0486 
0487     task = file->thread_task;
0488 
0489     if (task == NULL) {
0490         task = ngx_thread_task_alloc(pool,
0491                                      sizeof(ngx_thread_file_ctx_t));
0492         if (task == NULL) {
0493             return NGX_ERROR;
0494         }
0495 
0496         file->thread_task = task;
0497     }
0498 
0499     ctx = task->ctx;
0500 
0501     if (task->event.complete) {
0502         task->event.complete = 0;
0503 
0504         if (!ctx->write) {
0505             ngx_log_error(NGX_LOG_ALERT, file->log, 0,
0506                           "invalid thread call, write instead of read");
0507             return NGX_ERROR;
0508         }
0509 
0510         if (ctx->err || ctx->nbytes == 0) {
0511             ngx_log_error(NGX_LOG_CRIT, file->log, ctx->err,
0512                           "pwritev() \"%s\" failed", file->name.data);
0513             return NGX_ERROR;
0514         }
0515 
0516         file->offset += ctx->nbytes;
0517         return ctx->nbytes;
0518     }
0519 
0520     task->handler = ngx_thread_write_chain_to_file_handler;
0521 
0522     ctx->write = 1;
0523 
0524     ctx->fd = file->fd;
0525     ctx->chain = cl;
0526     ctx->offset = offset;
0527 
0528     if (file->thread_handler(task, file) != NGX_OK) {
0529         return NGX_ERROR;
0530     }
0531 
0532     return NGX_AGAIN;
0533 }
0534 
0535 
0536 static void
0537 ngx_thread_write_chain_to_file_handler(void *data, ngx_log_t *log)
0538 {
0539     ngx_thread_file_ctx_t *ctx = data;
0540 
0541 #if (NGX_HAVE_PWRITEV)
0542 
0543     off_t          offset;
0544     ssize_t        n;
0545     ngx_err_t      err;
0546     ngx_chain_t   *cl;
0547     ngx_iovec_t    vec;
0548     struct iovec   iovs[NGX_IOVS_PREALLOCATE];
0549 
0550     vec.iovs = iovs;
0551     vec.nalloc = NGX_IOVS_PREALLOCATE;
0552 
0553     cl = ctx->chain;
0554     offset = ctx->offset;
0555 
0556     ctx->nbytes = 0;
0557     ctx->err = 0;
0558 
0559     do {
0560         /* create the iovec and coalesce the neighbouring bufs */
0561         cl = ngx_chain_to_iovec(&vec, cl);
0562 
0563 eintr:
0564 
0565         n = pwritev(ctx->fd, iovs, vec.count, offset);
0566 
0567         if (n == -1) {
0568             err = ngx_errno;
0569 
0570             if (err == NGX_EINTR) {
0571                 ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, err,
0572                                "pwritev() was interrupted");
0573                 goto eintr;
0574             }
0575 
0576             ctx->err = err;
0577             return;
0578         }
0579 
0580         if ((size_t) n != vec.size) {
0581             ctx->nbytes = 0;
0582             return;
0583         }
0584 
0585         ctx->nbytes += n;
0586         offset += n;
0587     } while (cl);
0588 
0589 #else
0590 
0591     ctx->err = NGX_ENOSYS;
0592     return;
0593 
0594 #endif
0595 }
0596 
0597 #endif /* NGX_THREADS */
0598 
0599 
0600 ngx_int_t
0601 ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
0602 {
0603     struct timeval  tv[2];
0604 
0605     tv[0].tv_sec = ngx_time();
0606     tv[0].tv_usec = 0;
0607     tv[1].tv_sec = s;
0608     tv[1].tv_usec = 0;
0609 
0610     if (utimes((char *) name, tv) != -1) {
0611         return NGX_OK;
0612     }
0613 
0614     return NGX_ERROR;
0615 }
0616 
0617 
0618 ngx_int_t
0619 ngx_create_file_mapping(ngx_file_mapping_t *fm)
0620 {
0621     fm->fd = ngx_open_file(fm->name, NGX_FILE_RDWR, NGX_FILE_TRUNCATE,
0622                            NGX_FILE_DEFAULT_ACCESS);
0623 
0624     if (fm->fd == NGX_INVALID_FILE) {
0625         ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
0626                       ngx_open_file_n " \"%s\" failed", fm->name);
0627         return NGX_ERROR;
0628     }
0629 
0630     if (ftruncate(fm->fd, fm->size) == -1) {
0631         ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
0632                       "ftruncate() \"%s\" failed", fm->name);
0633         goto failed;
0634     }
0635 
0636     fm->addr = mmap(NULL, fm->size, PROT_READ|PROT_WRITE, MAP_SHARED,
0637                     fm->fd, 0);
0638     if (fm->addr != MAP_FAILED) {
0639         return NGX_OK;
0640     }
0641 
0642     ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
0643                   "mmap(%uz) \"%s\" failed", fm->size, fm->name);
0644 
0645 failed:
0646 
0647     if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
0648         ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
0649                       ngx_close_file_n " \"%s\" failed", fm->name);
0650     }
0651 
0652     return NGX_ERROR;
0653 }
0654 
0655 
0656 void
0657 ngx_close_file_mapping(ngx_file_mapping_t *fm)
0658 {
0659     if (munmap(fm->addr, fm->size) == -1) {
0660         ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
0661                       "munmap(%uz) \"%s\" failed", fm->size, fm->name);
0662     }
0663 
0664     if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
0665         ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
0666                       ngx_close_file_n " \"%s\" failed", fm->name);
0667     }
0668 }
0669 
0670 
0671 ngx_int_t
0672 ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
0673 {
0674     dir->dir = opendir((const char *) name->data);
0675 
0676     if (dir->dir == NULL) {
0677         return NGX_ERROR;
0678     }
0679 
0680     dir->valid_info = 0;
0681 
0682     return NGX_OK;
0683 }
0684 
0685 
0686 ngx_int_t
0687 ngx_read_dir(ngx_dir_t *dir)
0688 {
0689     dir->de = readdir(dir->dir);
0690 
0691     if (dir->de) {
0692 #if (NGX_HAVE_D_TYPE)
0693         dir->type = dir->de->d_type;
0694 #else
0695         dir->type = 0;
0696 #endif
0697         return NGX_OK;
0698     }
0699 
0700     return NGX_ERROR;
0701 }
0702 
0703 
0704 ngx_int_t
0705 ngx_open_glob(ngx_glob_t *gl)
0706 {
0707     int  n;
0708 
0709     n = glob((char *) gl->pattern, 0, NULL, &gl->pglob);
0710 
0711     if (n == 0) {
0712         return NGX_OK;
0713     }
0714 
0715 #ifdef GLOB_NOMATCH
0716 
0717     if (n == GLOB_NOMATCH && gl->test) {
0718         return NGX_OK;
0719     }
0720 
0721 #endif
0722 
0723     return NGX_ERROR;
0724 }
0725 
0726 
0727 ngx_int_t
0728 ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
0729 {
0730     size_t  count;
0731 
0732 #ifdef GLOB_NOMATCH
0733     count = (size_t) gl->pglob.gl_pathc;
0734 #else
0735     count = (size_t) gl->pglob.gl_matchc;
0736 #endif
0737 
0738     if (gl->n < count) {
0739 
0740         name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
0741         name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
0742         gl->n++;
0743 
0744         return NGX_OK;
0745     }
0746 
0747     return NGX_DONE;
0748 }
0749 
0750 
0751 void
0752 ngx_close_glob(ngx_glob_t *gl)
0753 {
0754     globfree(&gl->pglob);
0755 }
0756 
0757 
0758 ngx_err_t
0759 ngx_trylock_fd(ngx_fd_t fd)
0760 {
0761     struct flock  fl;
0762 
0763     ngx_memzero(&fl, sizeof(struct flock));
0764     fl.l_type = F_WRLCK;
0765     fl.l_whence = SEEK_SET;
0766 
0767     if (fcntl(fd, F_SETLK, &fl) == -1) {
0768         return ngx_errno;
0769     }
0770 
0771     return 0;
0772 }
0773 
0774 
0775 ngx_err_t
0776 ngx_lock_fd(ngx_fd_t fd)
0777 {
0778     struct flock  fl;
0779 
0780     ngx_memzero(&fl, sizeof(struct flock));
0781     fl.l_type = F_WRLCK;
0782     fl.l_whence = SEEK_SET;
0783 
0784     if (fcntl(fd, F_SETLKW, &fl) == -1) {
0785         return ngx_errno;
0786     }
0787 
0788     return 0;
0789 }
0790 
0791 
0792 ngx_err_t
0793 ngx_unlock_fd(ngx_fd_t fd)
0794 {
0795     struct flock  fl;
0796 
0797     ngx_memzero(&fl, sizeof(struct flock));
0798     fl.l_type = F_UNLCK;
0799     fl.l_whence = SEEK_SET;
0800 
0801     if (fcntl(fd, F_SETLK, &fl) == -1) {
0802         return  ngx_errno;
0803     }
0804 
0805     return 0;
0806 }
0807 
0808 
0809 #if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD)
0810 
0811 ngx_int_t
0812 ngx_read_ahead(ngx_fd_t fd, size_t n)
0813 {
0814     int  err;
0815 
0816     err = posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
0817 
0818     if (err == 0) {
0819         return 0;
0820     }
0821 
0822     ngx_set_errno(err);
0823     return NGX_FILE_ERROR;
0824 }
0825 
0826 #endif
0827 
0828 
0829 #if (NGX_HAVE_O_DIRECT)
0830 
0831 ngx_int_t
0832 ngx_directio_on(ngx_fd_t fd)
0833 {
0834     int  flags;
0835 
0836     flags = fcntl(fd, F_GETFL);
0837 
0838     if (flags == -1) {
0839         return NGX_FILE_ERROR;
0840     }
0841 
0842     return fcntl(fd, F_SETFL, flags | O_DIRECT);
0843 }
0844 
0845 
0846 ngx_int_t
0847 ngx_directio_off(ngx_fd_t fd)
0848 {
0849     int  flags;
0850 
0851     flags = fcntl(fd, F_GETFL);
0852 
0853     if (flags == -1) {
0854         return NGX_FILE_ERROR;
0855     }
0856 
0857     return fcntl(fd, F_SETFL, flags & ~O_DIRECT);
0858 }
0859 
0860 #endif
0861 
0862 
0863 #if (NGX_HAVE_STATFS)
0864 
0865 size_t
0866 ngx_fs_bsize(u_char *name)
0867 {
0868     struct statfs  fs;
0869 
0870     if (statfs((char *) name, &fs) == -1) {
0871         return 512;
0872     }
0873 
0874     if ((fs.f_bsize % 512) != 0) {
0875         return 512;
0876     }
0877 
0878     return (size_t) fs.f_bsize;
0879 }
0880 
0881 #elif (NGX_HAVE_STATVFS)
0882 
0883 size_t
0884 ngx_fs_bsize(u_char *name)
0885 {
0886     struct statvfs  fs;
0887 
0888     if (statvfs((char *) name, &fs) == -1) {
0889         return 512;
0890     }
0891 
0892     if ((fs.f_frsize % 512) != 0) {
0893         return 512;
0894     }
0895 
0896     return (size_t) fs.f_frsize;
0897 }
0898 
0899 #else
0900 
0901 size_t
0902 ngx_fs_bsize(u_char *name)
0903 {
0904     return 512;
0905 }
0906 
0907 #endif