~ubuntu-branches/ubuntu/trusty/nginx/trusty-proposed

« back to all changes in this revision

Viewing changes to src/core/ngx_open_file_cache.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2013-04-25 12:51:45 UTC
  • mfrom: (1.3.28)
  • mto: (1.3.29) (15.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: package-import@ubuntu.com-20130425125145-ugl0wor6bq0u5eae
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
3
 * Copyright (C) Igor Sysoev
 
4
 * Copyright (C) Nginx, Inc.
4
5
 */
5
6
 
6
7
 
17
18
 */
18
19
 
19
20
 
 
21
#define NGX_MIN_READ_AHEAD  (128 * 1024)
 
22
 
 
23
 
20
24
static void ngx_open_file_cache_cleanup(void *data);
21
 
static ngx_int_t ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of,
22
 
    ngx_log_t *log);
 
25
#if (NGX_HAVE_OPENAT)
 
26
static ngx_fd_t ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
 
27
    ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log);
 
28
#endif
 
29
static ngx_fd_t ngx_open_file_wrapper(ngx_str_t *name,
 
30
    ngx_open_file_info_t *of, ngx_int_t mode, ngx_int_t create,
 
31
    ngx_int_t access, ngx_log_t *log);
 
32
static ngx_int_t ngx_file_info_wrapper(ngx_str_t *name,
 
33
    ngx_open_file_info_t *of, ngx_file_info_t *fi, ngx_log_t *log);
 
34
static ngx_int_t ngx_open_and_stat_file(ngx_str_t *name,
 
35
    ngx_open_file_info_t *of, ngx_log_t *log);
23
36
static void ngx_open_file_add_event(ngx_open_file_cache_t *cache,
24
37
    ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log);
25
38
static void ngx_open_file_cleanup(void *data);
130
143
    time_t                          now;
131
144
    uint32_t                        hash;
132
145
    ngx_int_t                       rc;
 
146
    ngx_file_info_t                 fi;
133
147
    ngx_pool_cleanup_t             *cln;
134
148
    ngx_cached_open_file_t         *file;
135
149
    ngx_pool_cleanup_file_t        *clnf;
136
150
    ngx_open_file_cache_cleanup_t  *ofcln;
137
151
 
 
152
    of->fd = NGX_INVALID_FILE;
138
153
    of->err = 0;
139
154
 
140
155
    if (cache == NULL) {
141
156
 
 
157
        if (of->test_only) {
 
158
 
 
159
            if (ngx_file_info_wrapper(name, of, &fi, pool->log)
 
160
                == NGX_FILE_ERROR)
 
161
            {
 
162
                return NGX_ERROR;
 
163
            }
 
164
 
 
165
            of->uniq = ngx_file_uniq(&fi);
 
166
            of->mtime = ngx_file_mtime(&fi);
 
167
            of->size = ngx_file_size(&fi);
 
168
            of->fs_size = ngx_file_fs_size(&fi);
 
169
            of->is_dir = ngx_is_dir(&fi);
 
170
            of->is_file = ngx_is_file(&fi);
 
171
            of->is_link = ngx_is_link(&fi);
 
172
            of->is_exec = ngx_is_exec(&fi);
 
173
 
 
174
            return NGX_OK;
 
175
        }
 
176
 
142
177
        cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t));
143
178
        if (cln == NULL) {
144
179
            return NGX_ERROR;
145
180
        }
146
181
 
147
 
        rc = ngx_open_and_stat_file(name->data, of, pool->log);
 
182
        rc = ngx_open_and_stat_file(name, of, pool->log);
148
183
 
149
184
        if (rc == NGX_OK && !of->is_dir) {
150
185
            cln->handler = ngx_pool_cleanup_file;
179
214
 
180
215
            /* file was not used often enough to keep open */
181
216
 
182
 
            rc = ngx_open_and_stat_file(name->data, of, pool->log);
 
217
            rc = ngx_open_and_stat_file(name, of, pool->log);
183
218
 
184
219
            if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
185
220
                goto failed;
188
223
            goto add_event;
189
224
        }
190
225
 
191
 
        if ((file->event && file->use_event)
192
 
            || (file->event == NULL && now - file->created < of->valid))
 
226
        if (file->use_event
 
227
            || (file->event == NULL
 
228
                && (of->uniq == 0 || of->uniq == file->uniq)
 
229
                && now - file->created < of->valid
 
230
#if (NGX_HAVE_OPENAT)
 
231
                && of->disable_symlinks == file->disable_symlinks
 
232
                && of->disable_symlinks_from == file->disable_symlinks_from
 
233
#endif
 
234
            ))
193
235
        {
194
236
            if (file->err == 0) {
195
237
 
202
244
                of->is_file = file->is_file;
203
245
                of->is_link = file->is_link;
204
246
                of->is_exec = file->is_exec;
 
247
                of->is_directio = file->is_directio;
205
248
 
206
249
                if (!file->is_dir) {
207
250
                    file->count++;
210
253
 
211
254
            } else {
212
255
                of->err = file->err;
 
256
#if (NGX_HAVE_OPENAT)
 
257
                of->failed = file->disable_symlinks ? ngx_openat_file_n
 
258
                                                    : ngx_open_file_n;
 
259
#else
 
260
                of->failed = ngx_open_file_n;
 
261
#endif
213
262
            }
214
263
 
215
264
            goto found;
230
279
            of->test_dir = 1;
231
280
        }
232
281
 
233
 
        rc = ngx_open_and_stat_file(name->data, of, pool->log);
 
282
        of->fd = file->fd;
 
283
        of->uniq = file->uniq;
 
284
 
 
285
        rc = ngx_open_and_stat_file(name, of, pool->log);
234
286
 
235
287
        if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
236
288
            goto failed;
250
302
                goto add_event;
251
303
            }
252
304
 
253
 
            if (of->uniq == file->uniq
254
 
                && of->mtime == file->mtime
255
 
                && of->size == file->size)
256
 
            {
257
 
                if (ngx_close_file(of->fd) == NGX_FILE_ERROR) {
258
 
                    ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
259
 
                                  ngx_close_file_n " \"%s\" failed",
260
 
                                  name->data);
261
 
                }
262
 
 
263
 
                of->fd = file->fd;
264
 
                file->count++;
 
305
            if (of->uniq == file->uniq) {
265
306
 
266
307
                if (file->event) {
267
308
                    file->use_event = 1;
268
 
                    goto renew;
269
309
                }
270
310
 
271
 
                ngx_open_file_add_event(cache, file, of, pool->log);
 
311
                of->is_directio = file->is_directio;
272
312
 
273
 
                goto renew;
 
313
                goto update;
274
314
            }
275
315
 
276
316
            /* file was changed */
290
330
 
291
331
            if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
292
332
                ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
293
 
                              ngx_close_file_n " \"%s\" failed",
294
 
                              name->data);
 
333
                              ngx_close_file_n " \"%V\" failed", name);
295
334
            }
296
335
 
297
336
            goto add_event;
308
347
 
309
348
    /* not found */
310
349
 
311
 
    rc = ngx_open_and_stat_file(name->data, of, pool->log);
 
350
    rc = ngx_open_and_stat_file(name, of, pool->log);
312
351
 
313
352
    if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
314
353
        goto failed;
355
394
 
356
395
    file->fd = of->fd;
357
396
    file->err = of->err;
 
397
#if (NGX_HAVE_OPENAT)
 
398
    file->disable_symlinks = of->disable_symlinks;
 
399
    file->disable_symlinks_from = of->disable_symlinks_from;
 
400
#endif
358
401
 
359
402
    if (of->err == 0) {
360
403
        file->uniq = of->uniq;
367
410
        file->is_file = of->is_file;
368
411
        file->is_link = of->is_link;
369
412
        file->is_exec = of->is_exec;
 
413
        file->is_directio = of->is_directio;
370
414
 
371
415
        if (!of->is_dir) {
372
416
            file->count++;
373
417
        }
374
418
    }
375
419
 
376
 
renew:
377
 
 
378
420
    file->created = now;
379
421
 
380
422
found:
432
474
    if (of->fd != NGX_INVALID_FILE) {
433
475
        if (ngx_close_file(of->fd) == NGX_FILE_ERROR) {
434
476
            ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
435
 
                          ngx_close_file_n " \"%s\" failed", name->data);
 
477
                          ngx_close_file_n " \"%V\" failed", name);
436
478
        }
437
479
    }
438
480
 
440
482
}
441
483
 
442
484
 
443
 
static ngx_int_t
444
 
ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
 
485
#if (NGX_HAVE_OPENAT)
 
486
 
 
487
static ngx_fd_t
 
488
ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
 
489
    ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log)
 
490
{
 
491
    ngx_fd_t         fd;
 
492
    ngx_err_t        err;
 
493
    ngx_file_info_t  fi, atfi;
 
494
 
 
495
    /*
 
496
     * To allow symlinks with the same owner, use openat() (followed
 
497
     * by fstat()) and fstatat(AT_SYMLINK_NOFOLLOW), and then compare
 
498
     * uids between fstat() and fstatat().
 
499
     *
 
500
     * As there is a race between openat() and fstatat() we don't
 
501
     * know if openat() in fact opened symlink or not.  Therefore,
 
502
     * we have to compare uids even if fstatat() reports the opened
 
503
     * component isn't a symlink (as we don't know whether it was
 
504
     * symlink during openat() or not).
 
505
     */
 
506
 
 
507
    fd = ngx_openat_file(at_fd, name, mode, create, access);
 
508
 
 
509
    if (fd == NGX_INVALID_FILE) {
 
510
        return NGX_INVALID_FILE;
 
511
    }
 
512
 
 
513
    if (ngx_file_at_info(at_fd, name, &atfi, AT_SYMLINK_NOFOLLOW)
 
514
        == NGX_FILE_ERROR)
 
515
    {
 
516
        err = ngx_errno;
 
517
        goto failed;
 
518
    }
 
519
 
 
520
    if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
 
521
        err = ngx_errno;
 
522
        goto failed;
 
523
    }
 
524
 
 
525
    if (fi.st_uid != atfi.st_uid) {
 
526
        err = NGX_ELOOP;
 
527
        goto failed;
 
528
    }
 
529
 
 
530
    return fd;
 
531
 
 
532
failed:
 
533
 
 
534
    if (ngx_close_file(fd) == NGX_FILE_ERROR) {
 
535
        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
 
536
                      ngx_close_file_n " \"%V\" failed", name);
 
537
    }
 
538
 
 
539
    ngx_set_errno(err);
 
540
 
 
541
    return NGX_INVALID_FILE;
 
542
}
 
543
 
 
544
#endif
 
545
 
 
546
 
 
547
static ngx_fd_t
 
548
ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
 
549
    ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log)
 
550
{
 
551
    ngx_fd_t  fd;
 
552
 
 
553
#if !(NGX_HAVE_OPENAT)
 
554
 
 
555
    fd = ngx_open_file(name->data, mode, create, access);
 
556
 
 
557
    if (fd == NGX_INVALID_FILE) {
 
558
        of->err = ngx_errno;
 
559
        of->failed = ngx_open_file_n;
 
560
        return NGX_INVALID_FILE;
 
561
    }
 
562
 
 
563
    return fd;
 
564
 
 
565
#else
 
566
 
 
567
    u_char           *p, *cp, *end;
 
568
    ngx_fd_t          at_fd;
 
569
    ngx_str_t         at_name;
 
570
 
 
571
    if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
 
572
        fd = ngx_open_file(name->data, mode, create, access);
 
573
 
 
574
        if (fd == NGX_INVALID_FILE) {
 
575
            of->err = ngx_errno;
 
576
            of->failed = ngx_open_file_n;
 
577
            return NGX_INVALID_FILE;
 
578
        }
 
579
 
 
580
        return fd;
 
581
    }
 
582
 
 
583
    p = name->data;
 
584
    end = p + name->len;
 
585
 
 
586
    at_name = *name;
 
587
 
 
588
    if (of->disable_symlinks_from) {
 
589
 
 
590
        cp = p + of->disable_symlinks_from;
 
591
 
 
592
        *cp = '\0';
 
593
 
 
594
        at_fd = ngx_open_file(p, NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
 
595
                              NGX_FILE_OPEN, 0);
 
596
 
 
597
        *cp = '/';
 
598
 
 
599
        if (at_fd == NGX_INVALID_FILE) {
 
600
            of->err = ngx_errno;
 
601
            of->failed = ngx_open_file_n;
 
602
            return NGX_INVALID_FILE;
 
603
        }
 
604
 
 
605
        at_name.len = of->disable_symlinks_from;
 
606
        p = cp + 1;
 
607
 
 
608
    } else if (*p == '/') {
 
609
 
 
610
        at_fd = ngx_open_file("/",
 
611
                              NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
 
612
                              NGX_FILE_OPEN, 0);
 
613
 
 
614
        if (at_fd == NGX_INVALID_FILE) {
 
615
            of->err = ngx_errno;
 
616
            of->failed = ngx_openat_file_n;
 
617
            return NGX_INVALID_FILE;
 
618
        }
 
619
 
 
620
        at_name.len = 1;
 
621
        p++;
 
622
 
 
623
    } else {
 
624
        at_fd = NGX_AT_FDCWD;
 
625
    }
 
626
 
 
627
    for ( ;; ) {
 
628
        cp = ngx_strlchr(p, end, '/');
 
629
        if (cp == NULL) {
 
630
            break;
 
631
        }
 
632
 
 
633
        if (cp == p) {
 
634
            p++;
 
635
            continue;
 
636
        }
 
637
 
 
638
        *cp = '\0';
 
639
 
 
640
        if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) {
 
641
            fd = ngx_openat_file_owner(at_fd, p,
 
642
                                       NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
 
643
                                       NGX_FILE_OPEN, 0, log);
 
644
 
 
645
        } else {
 
646
            fd = ngx_openat_file(at_fd, p,
 
647
                           NGX_FILE_SEARCH|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW,
 
648
                           NGX_FILE_OPEN, 0);
 
649
        }
 
650
 
 
651
        *cp = '/';
 
652
 
 
653
        if (fd == NGX_INVALID_FILE) {
 
654
            of->err = ngx_errno;
 
655
            of->failed = ngx_openat_file_n;
 
656
            goto failed;
 
657
        }
 
658
 
 
659
        if (at_fd != NGX_AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) {
 
660
            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
 
661
                          ngx_close_file_n " \"%V\" failed", &at_name);
 
662
        }
 
663
 
 
664
        p = cp + 1;
 
665
        at_fd = fd;
 
666
        at_name.len = cp - at_name.data;
 
667
    }
 
668
 
 
669
    if (p == end) {
 
670
 
 
671
        /*
 
672
         * If pathname ends with a trailing slash, assume the last path
 
673
         * component is a directory and reopen it with requested flags;
 
674
         * if not, fail with ENOTDIR as per POSIX.
 
675
         *
 
676
         * We cannot rely on O_DIRECTORY in the loop above to check
 
677
         * that the last path component is a directory because
 
678
         * O_DIRECTORY doesn't work on FreeBSD 8.  Fortunately, by
 
679
         * reopening a directory, we don't depend on it at all.
 
680
         */
 
681
 
 
682
        fd = ngx_openat_file(at_fd, ".", mode, create, access);
 
683
        goto done;
 
684
    }
 
685
 
 
686
    if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER
 
687
        && !(create & (NGX_FILE_CREATE_OR_OPEN|NGX_FILE_TRUNCATE)))
 
688
    {
 
689
        fd = ngx_openat_file_owner(at_fd, p, mode, create, access, log);
 
690
 
 
691
    } else {
 
692
        fd = ngx_openat_file(at_fd, p, mode|NGX_FILE_NOFOLLOW, create, access);
 
693
    }
 
694
 
 
695
done:
 
696
 
 
697
    if (fd == NGX_INVALID_FILE) {
 
698
        of->err = ngx_errno;
 
699
        of->failed = ngx_openat_file_n;
 
700
    }
 
701
 
 
702
failed:
 
703
 
 
704
    if (at_fd != NGX_AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) {
 
705
        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
 
706
                      ngx_close_file_n " \"%V\" failed", &at_name);
 
707
    }
 
708
 
 
709
    return fd;
 
710
#endif
 
711
}
 
712
 
 
713
 
 
714
static ngx_int_t
 
715
ngx_file_info_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
 
716
    ngx_file_info_t *fi, ngx_log_t *log)
 
717
{
 
718
    ngx_int_t  rc;
 
719
 
 
720
#if !(NGX_HAVE_OPENAT)
 
721
 
 
722
    rc = ngx_file_info(name->data, fi);
 
723
 
 
724
    if (rc == NGX_FILE_ERROR) {
 
725
        of->err = ngx_errno;
 
726
        of->failed = ngx_file_info_n;
 
727
        return NGX_FILE_ERROR;
 
728
    }
 
729
 
 
730
    return rc;
 
731
 
 
732
#else
 
733
 
 
734
    ngx_fd_t  fd;
 
735
 
 
736
    if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
 
737
 
 
738
        rc = ngx_file_info(name->data, fi);
 
739
 
 
740
        if (rc == NGX_FILE_ERROR) {
 
741
            of->err = ngx_errno;
 
742
            of->failed = ngx_file_info_n;
 
743
            return NGX_FILE_ERROR;
 
744
        }
 
745
 
 
746
        return rc;
 
747
    }
 
748
 
 
749
    fd = ngx_open_file_wrapper(name, of, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
 
750
                               NGX_FILE_OPEN, 0, log);
 
751
 
 
752
    if (fd == NGX_INVALID_FILE) {
 
753
        return NGX_FILE_ERROR;
 
754
    }
 
755
 
 
756
    rc = ngx_fd_info(fd, fi);
 
757
 
 
758
    if (rc == NGX_FILE_ERROR) {
 
759
        of->err = ngx_errno;
 
760
        of->failed = ngx_fd_info_n;
 
761
    }
 
762
 
 
763
    if (ngx_close_file(fd) == NGX_FILE_ERROR) {
 
764
        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
 
765
                      ngx_close_file_n " \"%V\" failed", name);
 
766
    }
 
767
 
 
768
    return rc;
 
769
#endif
 
770
}
 
771
 
 
772
 
 
773
static ngx_int_t
 
774
ngx_open_and_stat_file(ngx_str_t *name, ngx_open_file_info_t *of,
 
775
    ngx_log_t *log)
445
776
{
446
777
    ngx_fd_t         fd;
447
778
    ngx_file_info_t  fi;
448
779
 
449
 
    of->fd = NGX_INVALID_FILE;
450
 
 
451
 
    if (of->test_dir) {
452
 
 
453
 
        if (ngx_file_info(name, &fi) == -1) {
454
 
            of->err = ngx_errno;
455
 
 
456
 
            return NGX_ERROR;
457
 
        }
458
 
 
459
 
        of->uniq = ngx_file_uniq(&fi);
460
 
        of->mtime = ngx_file_mtime(&fi);
461
 
        of->size = ngx_file_size(&fi);
462
 
        of->is_dir = ngx_is_dir(&fi);
463
 
        of->is_file = ngx_is_file(&fi);
464
 
        of->is_link = ngx_is_link(&fi);
465
 
        of->is_exec = ngx_is_exec(&fi);
466
 
 
467
 
        if (of->is_dir) {
468
 
            return NGX_OK;
469
 
        }
470
 
    }
471
 
 
472
 
    fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
 
780
    if (of->fd != NGX_INVALID_FILE) {
 
781
 
 
782
        if (ngx_file_info_wrapper(name, of, &fi, log) == NGX_FILE_ERROR) {
 
783
            of->fd = NGX_INVALID_FILE;
 
784
            return NGX_ERROR;
 
785
        }
 
786
 
 
787
        if (of->uniq == ngx_file_uniq(&fi)) {
 
788
            goto done;
 
789
        }
 
790
 
 
791
    } else if (of->test_dir) {
 
792
 
 
793
        if (ngx_file_info_wrapper(name, of, &fi, log) == NGX_FILE_ERROR) {
 
794
            of->fd = NGX_INVALID_FILE;
 
795
            return NGX_ERROR;
 
796
        }
 
797
 
 
798
        if (ngx_is_dir(&fi)) {
 
799
            goto done;
 
800
        }
 
801
    }
 
802
 
 
803
    if (!of->log) {
 
804
 
 
805
        /*
 
806
         * Use non-blocking open() not to hang on FIFO files, etc.
 
807
         * This flag has no effect on a regular files.
 
808
         */
 
809
 
 
810
        fd = ngx_open_file_wrapper(name, of, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
 
811
                                   NGX_FILE_OPEN, 0, log);
 
812
 
 
813
    } else {
 
814
        fd = ngx_open_file_wrapper(name, of, NGX_FILE_APPEND,
 
815
                                   NGX_FILE_CREATE_OR_OPEN,
 
816
                                   NGX_FILE_DEFAULT_ACCESS, log);
 
817
    }
473
818
 
474
819
    if (fd == NGX_INVALID_FILE) {
475
 
        of->err = ngx_errno;
 
820
        of->fd = NGX_INVALID_FILE;
476
821
        return NGX_ERROR;
477
822
    }
478
823
 
479
824
    if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
480
825
        ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
481
 
                      ngx_fd_info_n " \"%s\" failed", name);
 
826
                      ngx_fd_info_n " \"%V\" failed", name);
482
827
 
483
828
        if (ngx_close_file(fd) == NGX_FILE_ERROR) {
484
829
            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
485
 
                          ngx_close_file_n " \"%s\" failed", name);
 
830
                          ngx_close_file_n " \"%V\" failed", name);
486
831
        }
487
832
 
 
833
        of->fd = NGX_INVALID_FILE;
 
834
 
488
835
        return NGX_ERROR;
489
836
    }
490
837
 
491
838
    if (ngx_is_dir(&fi)) {
492
839
        if (ngx_close_file(fd) == NGX_FILE_ERROR) {
493
840
            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
494
 
                          ngx_close_file_n " \"%s\" failed", name);
495
 
        }
496
 
 
497
 
        fd = NGX_INVALID_FILE;
 
841
                          ngx_close_file_n " \"%V\" failed", name);
 
842
        }
 
843
 
 
844
        of->fd = NGX_INVALID_FILE;
 
845
 
 
846
    } else {
 
847
        of->fd = fd;
 
848
 
 
849
        if (of->read_ahead && ngx_file_size(&fi) > NGX_MIN_READ_AHEAD) {
 
850
            if (ngx_read_ahead(fd, of->read_ahead) == NGX_ERROR) {
 
851
                ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
 
852
                              ngx_read_ahead_n " \"%V\" failed", name);
 
853
            }
 
854
        }
 
855
 
 
856
        if (of->directio <= ngx_file_size(&fi)) {
 
857
            if (ngx_directio_on(fd) == NGX_FILE_ERROR) {
 
858
                ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
 
859
                              ngx_directio_on_n " \"%V\" failed", name);
 
860
 
 
861
            } else {
 
862
                of->is_directio = 1;
 
863
            }
 
864
        }
498
865
    }
499
866
 
500
 
    of->fd = fd;
 
867
done:
 
868
 
501
869
    of->uniq = ngx_file_uniq(&fi);
502
870
    of->mtime = ngx_file_mtime(&fi);
503
871
    of->size = ngx_file_size(&fi);
 
872
    of->fs_size = ngx_file_fs_size(&fi);
504
873
    of->is_dir = ngx_is_dir(&fi);
505
874
    of->is_file = ngx_is_file(&fi);
506
875
    of->is_link = ngx_is_link(&fi);
530
899
        return;
531
900
    }
532
901
 
 
902
    file->use_event = 0;
 
903
 
533
904
    file->event = ngx_calloc(sizeof(ngx_event_t), log);
534
905
    if (file->event== NULL) {
535
906
        return;
567
938
    }
568
939
 
569
940
    /*
570
 
     * we do not file->use_event here because there may be a race
571
 
     * condition between opening file and adding event, so we rely
572
 
     * upon event notification only after first file revalidation
 
941
     * we do not set file->use_event here because there may be a race
 
942
     * condition: a file may be deleted between opening the file and
 
943
     * adding event, so we rely upon event notification only after
 
944
     * one file revalidation on next file access
573
945
     */
574
946
 
575
947
    return;
770
1142
 
771
1143
        /* hash == node->key */
772
1144
 
773
 
        do {
774
 
            file = (ngx_cached_open_file_t *) node;
775
 
 
776
 
            rc = ngx_strcmp(name->data, file->name);
777
 
 
778
 
            if (rc == 0) {
779
 
                return file;
780
 
            }
781
 
 
782
 
            node = (rc < 0) ? node->left : node->right;
783
 
 
784
 
        } while (node != sentinel && hash == node->key);
785
 
 
786
 
        break;
 
1145
        file = (ngx_cached_open_file_t *) node;
 
1146
 
 
1147
        rc = ngx_strcmp(name->data, file->name);
 
1148
 
 
1149
        if (rc == 0) {
 
1150
            return file;
 
1151
        }
 
1152
 
 
1153
        node = (rc < 0) ? node->left : node->right;
787
1154
    }
788
1155
 
789
1156
    return NULL;
807
1174
 
808
1175
    /* NGX_ONESHOT_EVENT was already deleted */
809
1176
    file->event = NULL;
 
1177
    file->use_event = 0;
810
1178
 
811
1179
    file->close = 1;
812
1180