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     if (fm->fd == NGX_INVALID_FILE) {
0624         ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
0625                       ngx_open_file_n " \"%s\" failed", fm->name);
0626         return NGX_ERROR;
0627     }
0628 
0629     if (ftruncate(fm->fd, fm->size) == -1) {
0630         ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
0631                       "ftruncate() \"%s\" failed", fm->name);
0632         goto failed;
0633     }
0634 
0635     fm->addr = mmap(NULL, fm->size, PROT_READ|PROT_WRITE, MAP_SHARED,
0636                     fm->fd, 0);
0637     if (fm->addr != MAP_FAILED) {
0638         return NGX_OK;
0639     }
0640 
0641     ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
0642                   "mmap(%uz) \"%s\" failed", fm->size, fm->name);
0643 
0644 failed:
0645 
0646     if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
0647         ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
0648                       ngx_close_file_n " \"%s\" failed", fm->name);
0649     }
0650 
0651     return NGX_ERROR;
0652 }
0653 
0654 
0655 void
0656 ngx_close_file_mapping(ngx_file_mapping_t *fm)
0657 {
0658     if (munmap(fm->addr, fm->size) == -1) {
0659         ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
0660                       "munmap(%uz) \"%s\" failed", fm->size, fm->name);
0661     }
0662 
0663     if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
0664         ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
0665                       ngx_close_file_n " \"%s\" failed", fm->name);
0666     }
0667 }
0668 
0669 
0670 ngx_int_t
0671 ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
0672 {
0673     dir->dir = opendir((const char *) name->data);
0674 
0675     if (dir->dir == NULL) {
0676         return NGX_ERROR;
0677     }
0678 
0679     dir->valid_info = 0;
0680 
0681     return NGX_OK;
0682 }
0683 
0684 
0685 ngx_int_t
0686 ngx_read_dir(ngx_dir_t *dir)
0687 {
0688     dir->de = readdir(dir->dir);
0689 
0690     if (dir->de) {
0691 #if (NGX_HAVE_D_TYPE)
0692         dir->type = dir->de->d_type;
0693 #else
0694         dir->type = 0;
0695 #endif
0696         return NGX_OK;
0697     }
0698 
0699     return NGX_ERROR;
0700 }
0701 
0702 
0703 ngx_int_t
0704 ngx_open_glob(ngx_glob_t *gl)
0705 {
0706     int  n;
0707 
0708     n = glob((char *) gl->pattern, 0, NULL, &gl->pglob);
0709 
0710     if (n == 0) {
0711         return NGX_OK;
0712     }
0713 
0714 #ifdef GLOB_NOMATCH
0715 
0716     if (n == GLOB_NOMATCH && gl->test) {
0717         return NGX_OK;
0718     }
0719 
0720 #endif
0721 
0722     return NGX_ERROR;
0723 }
0724 
0725 
0726 ngx_int_t
0727 ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
0728 {
0729     size_t  count;
0730 
0731 #ifdef GLOB_NOMATCH
0732     count = (size_t) gl->pglob.gl_pathc;
0733 #else
0734     count = (size_t) gl->pglob.gl_matchc;
0735 #endif
0736 
0737     if (gl->n < count) {
0738 
0739         name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
0740         name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
0741         gl->n++;
0742 
0743         return NGX_OK;
0744     }
0745 
0746     return NGX_DONE;
0747 }
0748 
0749 
0750 void
0751 ngx_close_glob(ngx_glob_t *gl)
0752 {
0753     globfree(&gl->pglob);
0754 }
0755 
0756 
0757 ngx_err_t
0758 ngx_trylock_fd(ngx_fd_t fd)
0759 {
0760     struct flock  fl;
0761 
0762     ngx_memzero(&fl, sizeof(struct flock));
0763     fl.l_type = F_WRLCK;
0764     fl.l_whence = SEEK_SET;
0765 
0766     if (fcntl(fd, F_SETLK, &fl) == -1) {
0767         return ngx_errno;
0768     }
0769 
0770     return 0;
0771 }
0772 
0773 
0774 ngx_err_t
0775 ngx_lock_fd(ngx_fd_t fd)
0776 {
0777     struct flock  fl;
0778 
0779     ngx_memzero(&fl, sizeof(struct flock));
0780     fl.l_type = F_WRLCK;
0781     fl.l_whence = SEEK_SET;
0782 
0783     if (fcntl(fd, F_SETLKW, &fl) == -1) {
0784         return ngx_errno;
0785     }
0786 
0787     return 0;
0788 }
0789 
0790 
0791 ngx_err_t
0792 ngx_unlock_fd(ngx_fd_t fd)
0793 {
0794     struct flock  fl;
0795 
0796     ngx_memzero(&fl, sizeof(struct flock));
0797     fl.l_type = F_UNLCK;
0798     fl.l_whence = SEEK_SET;
0799 
0800     if (fcntl(fd, F_SETLK, &fl) == -1) {
0801         return  ngx_errno;
0802     }
0803 
0804     return 0;
0805 }
0806 
0807 
0808 #if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD)
0809 
0810 ngx_int_t
0811 ngx_read_ahead(ngx_fd_t fd, size_t n)
0812 {
0813     int  err;
0814 
0815     err = posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
0816 
0817     if (err == 0) {
0818         return 0;
0819     }
0820 
0821     ngx_set_errno(err);
0822     return NGX_FILE_ERROR;
0823 }
0824 
0825 #endif
0826 
0827 
0828 #if (NGX_HAVE_O_DIRECT)
0829 
0830 ngx_int_t
0831 ngx_directio_on(ngx_fd_t fd)
0832 {
0833     int  flags;
0834 
0835     flags = fcntl(fd, F_GETFL);
0836 
0837     if (flags == -1) {
0838         return NGX_FILE_ERROR;
0839     }
0840 
0841     return fcntl(fd, F_SETFL, flags | O_DIRECT);
0842 }
0843 
0844 
0845 ngx_int_t
0846 ngx_directio_off(ngx_fd_t fd)
0847 {
0848     int  flags;
0849 
0850     flags = fcntl(fd, F_GETFL);
0851 
0852     if (flags == -1) {
0853         return NGX_FILE_ERROR;
0854     }
0855 
0856     return fcntl(fd, F_SETFL, flags & ~O_DIRECT);
0857 }
0858 
0859 #endif
0860 
0861 
0862 #if (NGX_HAVE_STATFS)
0863 
0864 size_t
0865 ngx_fs_bsize(u_char *name)
0866 {
0867     struct statfs  fs;
0868 
0869     if (statfs((char *) name, &fs) == -1) {
0870         return 512;
0871     }
0872 
0873     if ((fs.f_bsize % 512) != 0) {
0874         return 512;
0875     }
0876 
0877     return (size_t) fs.f_bsize;
0878 }
0879 
0880 #elif (NGX_HAVE_STATVFS)
0881 
0882 size_t
0883 ngx_fs_bsize(u_char *name)
0884 {
0885     struct statvfs  fs;
0886 
0887     if (statvfs((char *) name, &fs) == -1) {
0888         return 512;
0889     }
0890 
0891     if ((fs.f_frsize % 512) != 0) {
0892         return 512;
0893     }
0894 
0895     return (size_t) fs.f_frsize;
0896 }
0897 
0898 #else
0899 
0900 size_t
0901 ngx_fs_bsize(u_char *name)
0902 {
0903     return 512;
0904 }
0905 
0906 #endif