Mercurial > hg > nginx-vendor-current
comparison src/core/ngx_open_file_cache.c @ 664:f5b859b2f097 NGINX_1_1_16
nginx 1.1.16
*) Change: the simultaneous subrequest limit has been raised to 200.
*) Feature: the "from" parameter of the "disable_symlinks" directive.
*) Feature: the "return" and "error_page" directives can be used to
return 307 redirections.
*) Bugfix: a segmentation fault might occur in a worker process if the
"resolver" directive was used and there was no "error_log" directive
specified at global level.
Thanks to Roman Arutyunyan.
*) Bugfix: a segmentation fault might occur in a worker process if the
"proxy_http_version 1.1" or "fastcgi_keep_conn on" directives were
used.
*) Bugfix: memory leaks.
Thanks to Lanshun Zhou.
*) Bugfix: in the "disable_symlinks" directive.
*) Bugfix: on ZFS filesystem disk cache size might be calculated
incorrectly; the bug had appeared in 1.0.1.
*) Bugfix: nginx could not be built by the icc 12.1 compiler.
*) Bugfix: nginx could not be built by gcc on Solaris; the bug had
appeared in 1.1.15.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 29 Feb 2012 00:00:00 +0400 |
parents | e5fa0a4a7d27 |
children |
comparison
equal
deleted
inserted
replaced
663:dd668cf20818 | 664:f5b859b2f097 |
---|---|
227 || (file->event == NULL | 227 || (file->event == NULL |
228 && (of->uniq == 0 || of->uniq == file->uniq) | 228 && (of->uniq == 0 || of->uniq == file->uniq) |
229 && now - file->created < of->valid | 229 && now - file->created < of->valid |
230 #if (NGX_HAVE_OPENAT) | 230 #if (NGX_HAVE_OPENAT) |
231 && of->disable_symlinks == file->disable_symlinks | 231 && of->disable_symlinks == file->disable_symlinks |
232 && of->disable_symlinks_from == file->disable_symlinks_from | |
232 #endif | 233 #endif |
233 )) | 234 )) |
234 { | 235 { |
235 if (file->err == 0) { | 236 if (file->err == 0) { |
236 | 237 |
393 | 394 |
394 file->fd = of->fd; | 395 file->fd = of->fd; |
395 file->err = of->err; | 396 file->err = of->err; |
396 #if (NGX_HAVE_OPENAT) | 397 #if (NGX_HAVE_OPENAT) |
397 file->disable_symlinks = of->disable_symlinks; | 398 file->disable_symlinks = of->disable_symlinks; |
399 file->disable_symlinks_from = of->disable_symlinks_from; | |
398 #endif | 400 #endif |
399 | 401 |
400 if (of->err == 0) { | 402 if (of->err == 0) { |
401 file->uniq = of->uniq; | 403 file->uniq = of->uniq; |
402 file->mtime = of->mtime; | 404 file->mtime = of->mtime; |
502 * symlink during openat() or not). | 504 * symlink during openat() or not). |
503 */ | 505 */ |
504 | 506 |
505 fd = ngx_openat_file(at_fd, name, mode, create, access); | 507 fd = ngx_openat_file(at_fd, name, mode, create, access); |
506 | 508 |
507 if (fd == NGX_FILE_ERROR) { | 509 if (fd == NGX_INVALID_FILE) { |
508 return NGX_FILE_ERROR; | 510 return NGX_INVALID_FILE; |
509 } | 511 } |
510 | 512 |
511 if (ngx_file_at_info(at_fd, name, &atfi, AT_SYMLINK_NOFOLLOW) | 513 if (ngx_file_at_info(at_fd, name, &atfi, AT_SYMLINK_NOFOLLOW) |
512 == NGX_FILE_ERROR) | 514 == NGX_FILE_ERROR) |
513 { | 515 { |
563 #else | 565 #else |
564 | 566 |
565 u_char *p, *cp, *end; | 567 u_char *p, *cp, *end; |
566 ngx_fd_t at_fd; | 568 ngx_fd_t at_fd; |
567 ngx_str_t at_name; | 569 ngx_str_t at_name; |
568 ngx_file_info_t fi; | |
569 | 570 |
570 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) { | 571 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) { |
571 fd = ngx_open_file(name->data, mode, create, access); | 572 fd = ngx_open_file(name->data, mode, create, access); |
572 | 573 |
573 if (fd == NGX_INVALID_FILE) { | 574 if (fd == NGX_INVALID_FILE) { |
580 } | 581 } |
581 | 582 |
582 p = name->data; | 583 p = name->data; |
583 end = p + name->len; | 584 end = p + name->len; |
584 | 585 |
585 at_fd = AT_FDCWD; | |
586 at_name = *name; | 586 at_name = *name; |
587 | 587 |
588 if (p[0] == '/') { | 588 if (of->disable_symlinks_from) { |
589 at_fd = ngx_openat_file(at_fd, "/", | 589 |
590 NGX_FILE_RDONLY|NGX_FILE_NONBLOCK, | 590 cp = p + of->disable_symlinks_from; |
591 NGX_FILE_OPEN, 0); | 591 |
592 | 592 *cp = '\0'; |
593 if (at_fd == NGX_FILE_ERROR) { | 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) { | |
594 of->err = ngx_errno; | 615 of->err = ngx_errno; |
595 of->failed = ngx_openat_file_n; | 616 of->failed = ngx_openat_file_n; |
596 return NGX_FILE_ERROR; | 617 return NGX_INVALID_FILE; |
597 } | 618 } |
598 | 619 |
599 at_name.len = 1; | 620 at_name.len = 1; |
600 p++; | 621 p++; |
622 | |
623 } else { | |
624 at_fd = NGX_AT_FDCWD; | |
601 } | 625 } |
602 | 626 |
603 for ( ;; ) { | 627 for ( ;; ) { |
604 cp = ngx_strlchr(p, end, '/'); | 628 cp = ngx_strlchr(p, end, '/'); |
605 if (cp == NULL) { | 629 if (cp == NULL) { |
613 | 637 |
614 *cp = '\0'; | 638 *cp = '\0'; |
615 | 639 |
616 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) { | 640 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) { |
617 fd = ngx_openat_file_owner(at_fd, p, | 641 fd = ngx_openat_file_owner(at_fd, p, |
618 NGX_FILE_RDONLY|NGX_FILE_NONBLOCK, | 642 NGX_FILE_SEARCH|NGX_FILE_NONBLOCK, |
619 NGX_FILE_OPEN, 0, log); | 643 NGX_FILE_OPEN, 0, log); |
620 | 644 |
621 } else { | 645 } else { |
622 fd = ngx_openat_file(at_fd, p, | 646 fd = ngx_openat_file(at_fd, p, |
623 NGX_FILE_RDONLY|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW, | 647 NGX_FILE_SEARCH|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW, |
624 NGX_FILE_OPEN, 0); | 648 NGX_FILE_OPEN, 0); |
625 } | 649 } |
626 | 650 |
627 *cp = '/'; | 651 *cp = '/'; |
628 | 652 |
630 of->err = ngx_errno; | 654 of->err = ngx_errno; |
631 of->failed = ngx_openat_file_n; | 655 of->failed = ngx_openat_file_n; |
632 goto failed; | 656 goto failed; |
633 } | 657 } |
634 | 658 |
635 if (at_fd != AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) { | 659 if (at_fd != NGX_AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) { |
636 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | 660 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, |
637 ngx_close_file_n " \"%V\" failed", at_name); | 661 ngx_close_file_n " \"%V\" failed", &at_name); |
638 } | 662 } |
639 | 663 |
640 p = cp + 1; | 664 p = cp + 1; |
641 at_fd = fd; | 665 at_fd = fd; |
642 at_name.len = cp - at_name.data; | 666 at_name.len = cp - at_name.data; |
643 } | 667 } |
644 | 668 |
645 if (p == end && at_fd != AT_FDCWD) { | 669 if (p == end) { |
646 | 670 |
647 /* | 671 /* |
648 * If pathname ends with a trailing slash, check if last path | 672 * If pathname ends with a trailing slash, assume the last path |
649 * component is a directory; if not, fail with ENOTDIR as per | 673 * component is a directory and reopen it with requested flags; |
650 * POSIX. | 674 * if not, fail with ENOTDIR as per POSIX. |
651 * | 675 * |
652 * We use separate check instead of O_DIRECTORY in the loop above, | 676 * We cannot rely on O_DIRECTORY in the loop above to check |
653 * as O_DIRECTORY doesn't work on FreeBSD 8. | 677 * that the last path component is a directory because |
654 * | 678 * O_DIRECTORY doesn't work on FreeBSD 8. Fortunately, by |
655 * Note this returns already opened file descriptor, with different | 679 * reopening a directory, we don't depend on it at all. |
656 * mode/create/access. This is believed to be safe as we don't | |
657 * use this codepath to create directories. | |
658 */ | 680 */ |
659 | 681 |
660 if (ngx_fd_info(at_fd, &fi) == NGX_FILE_ERROR) { | 682 fd = ngx_openat_file(at_fd, ".", mode, create, access); |
661 of->err = ngx_errno; | 683 goto done; |
662 of->failed = ngx_fd_info_n; | 684 } |
663 fd = NGX_INVALID_FILE; | 685 |
664 | 686 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER |
665 goto failed; | 687 && !(create & (NGX_FILE_CREATE_OR_OPEN|NGX_FILE_TRUNCATE))) |
666 } | 688 { |
667 | |
668 if (ngx_is_dir(&fi)) { | |
669 return at_fd; | |
670 } | |
671 | |
672 of->err = ENOTDIR; | |
673 of->failed = ngx_openat_file_n; | |
674 fd = NGX_INVALID_FILE; | |
675 | |
676 goto failed; | |
677 } | |
678 | |
679 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) { | |
680 fd = ngx_openat_file_owner(at_fd, p, mode, create, access, log); | 689 fd = ngx_openat_file_owner(at_fd, p, mode, create, access, log); |
681 | 690 |
682 } else { | 691 } else { |
683 fd = ngx_openat_file(at_fd, p, mode|NGX_FILE_NOFOLLOW, create, access); | 692 fd = ngx_openat_file(at_fd, p, mode|NGX_FILE_NOFOLLOW, create, access); |
684 } | 693 } |
694 | |
695 done: | |
685 | 696 |
686 if (fd == NGX_INVALID_FILE) { | 697 if (fd == NGX_INVALID_FILE) { |
687 of->err = ngx_errno; | 698 of->err = ngx_errno; |
688 of->failed = ngx_openat_file_n; | 699 of->failed = ngx_openat_file_n; |
689 } | 700 } |
690 | 701 |
691 failed: | 702 failed: |
692 | 703 |
693 if (at_fd != AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) { | 704 if (at_fd != NGX_AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) { |
694 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | 705 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, |
695 ngx_close_file_n " \"%V\" failed", at_name); | 706 ngx_close_file_n " \"%V\" failed", &at_name); |
696 } | 707 } |
697 | 708 |
698 return fd; | 709 return fd; |
699 #endif | 710 #endif |
700 } | 711 } |
1129 continue; | 1140 continue; |
1130 } | 1141 } |
1131 | 1142 |
1132 /* hash == node->key */ | 1143 /* hash == node->key */ |
1133 | 1144 |
1134 do { | 1145 file = (ngx_cached_open_file_t *) node; |
1135 file = (ngx_cached_open_file_t *) node; | 1146 |
1136 | 1147 rc = ngx_strcmp(name->data, file->name); |
1137 rc = ngx_strcmp(name->data, file->name); | 1148 |
1138 | 1149 if (rc == 0) { |
1139 if (rc == 0) { | 1150 return file; |
1140 return file; | 1151 } |
1141 } | 1152 |
1142 | 1153 node = (rc < 0) ? node->left : node->right; |
1143 node = (rc < 0) ? node->left : node->right; | |
1144 | |
1145 } while (node != sentinel && hash == node->key); | |
1146 | |
1147 break; | |
1148 } | 1154 } |
1149 | 1155 |
1150 return NULL; | 1156 return NULL; |
1151 } | 1157 } |
1152 | 1158 |