Mercurial > hg > nginx-vendor-current
comparison src/core/ngx_file.c @ 514:43cc6f0b77ce NGINX_0_8_9
nginx 0.8.9
*) Feature: now the start cache loader runs in a separate process; this
should improve large caches handling.
*) Feature: now temporarily files and permanent storage area may reside
at different file systems.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 17 Aug 2009 00:00:00 +0400 |
parents | f39b9e29530d |
children | 7efcdb937752 |
comparison
equal
deleted
inserted
replaced
513:16d97d9e72b7 | 514:43cc6f0b77ce |
---|---|
97 if (err == NGX_EEXIST) { | 97 if (err == NGX_EEXIST) { |
98 n = (uint32_t) ngx_next_temp_number(1); | 98 n = (uint32_t) ngx_next_temp_number(1); |
99 continue; | 99 continue; |
100 } | 100 } |
101 | 101 |
102 if ((path->level[0] == 0) | 102 if ((path->level[0] == 0) || (err != NGX_ENOPATH)) { |
103 || (err != NGX_ENOENT | |
104 #if (NGX_WIN32) | |
105 && err != NGX_ENOTDIR | |
106 #endif | |
107 )) | |
108 { | |
109 ngx_log_error(NGX_LOG_CRIT, file->log, err, | 103 ngx_log_error(NGX_LOG_CRIT, file->log, err, |
110 ngx_open_tempfile_n " \"%s\" failed", | 104 ngx_open_tempfile_n " \"%s\" failed", |
111 file->name.data); | 105 file->name.data); |
112 return NGX_ERROR; | 106 return NGX_ERROR; |
113 } | 107 } |
262 if (ngx_conf_full_name(cf->cycle, &path->name, 0) != NGX_OK) { | 256 if (ngx_conf_full_name(cf->cycle, &path->name, 0) != NGX_OK) { |
263 return NULL; | 257 return NULL; |
264 } | 258 } |
265 | 259 |
266 path->len = 0; | 260 path->len = 0; |
267 path->manager = (ngx_path_manager_pt) cmd->post; | 261 path->manager = NULL; |
262 path->loader = NULL; | |
268 path->conf_file = cf->conf_file->file.name.data; | 263 path->conf_file = cf->conf_file->file.name.data; |
269 path->line = cf->conf_file->line; | 264 path->line = cf->conf_file->line; |
270 | 265 |
271 for (i = 0, n = 2; n < cf->args->nelts; i++, n++) { | 266 for (i = 0, n = 2; n < cf->args->nelts; i++, n++) { |
272 level = ngx_atoi(value[n].data, value[n].len); | 267 level = ngx_atoi(value[n].data, value[n].len); |
323 (*path)->len = init->level[0] + (init->level[0] ? 1 : 0) | 318 (*path)->len = init->level[0] + (init->level[0] ? 1 : 0) |
324 + init->level[1] + (init->level[1] ? 1 : 0) | 319 + init->level[1] + (init->level[1] ? 1 : 0) |
325 + init->level[2] + (init->level[2] ? 1 : 0); | 320 + init->level[2] + (init->level[2] ? 1 : 0); |
326 | 321 |
327 (*path)->manager = NULL; | 322 (*path)->manager = NULL; |
323 (*path)->loader = NULL; | |
328 (*path)->conf_file = NULL; | 324 (*path)->conf_file = NULL; |
329 | 325 |
330 if (ngx_add_path(cf, path) != NGX_OK) { | 326 if (ngx_add_path(cf, path) != NGX_OK) { |
331 return NGX_CONF_ERROR; | 327 return NGX_CONF_ERROR; |
332 } | 328 } |
526 | 522 |
527 | 523 |
528 ngx_int_t | 524 ngx_int_t |
529 ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext) | 525 ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext) |
530 { | 526 { |
531 ngx_err_t err; | 527 u_char *name; |
528 ngx_err_t err; | |
529 ngx_copy_file_t cf; | |
532 | 530 |
533 #if !(NGX_WIN32) | 531 #if !(NGX_WIN32) |
534 | 532 |
535 if (ext->access) { | 533 if (ext->access) { |
536 if (ngx_change_file_access(src->data, ext->access) == NGX_FILE_ERROR) { | 534 if (ngx_change_file_access(src->data, ext->access) == NGX_FILE_ERROR) { |
556 return NGX_OK; | 554 return NGX_OK; |
557 } | 555 } |
558 | 556 |
559 err = ngx_errno; | 557 err = ngx_errno; |
560 | 558 |
561 if (err | 559 if (err == NGX_ENOPATH) { |
562 #if (NGX_WIN32) | 560 |
563 == ERROR_PATH_NOT_FOUND | |
564 #else | |
565 == NGX_ENOENT | |
566 #endif | |
567 ) | |
568 { | |
569 if (!ext->create_path) { | 561 if (!ext->create_path) { |
570 goto failed; | 562 goto failed; |
571 } | 563 } |
572 | 564 |
573 err = ngx_create_full_path(to->data, ngx_dir_access(ext->path_access)); | 565 err = ngx_create_full_path(to->data, ngx_dir_access(ext->path_access)); |
603 } | 595 } |
604 } | 596 } |
605 | 597 |
606 #endif | 598 #endif |
607 | 599 |
600 if (err == NGX_EXDEV) { | |
601 | |
602 cf.size = -1; | |
603 cf.buf_size = 0; | |
604 cf.access = ext->access; | |
605 cf.time = ext->time; | |
606 cf.log = ext->log; | |
607 | |
608 name = ngx_alloc(to->len + 1 + 10, ext->log); | |
609 if (name == NULL) { | |
610 return NGX_ERROR; | |
611 } | |
612 | |
613 (void) ngx_sprintf(name, "%*s.%010uD%Z", to->len - 1, to->data, | |
614 (uint32_t) ngx_next_temp_number(0)); | |
615 | |
616 if (ngx_copy_file(src->data, name, &cf) == NGX_OK) { | |
617 | |
618 if (ngx_rename_file(name, to->data) == NGX_FILE_ERROR) { | |
619 ngx_free(name); | |
620 goto failed; | |
621 } | |
622 | |
623 ngx_free(name); | |
624 | |
625 if (ngx_delete_file(src->data) == NGX_FILE_ERROR) { | |
626 ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno, | |
627 ngx_delete_file_n " \"%s\" failed", src->data); | |
628 | |
629 return NGX_ERROR; | |
630 } | |
631 | |
632 return NGX_OK; | |
633 } | |
634 | |
635 ngx_free(name); | |
636 } | |
637 | |
608 failed: | 638 failed: |
609 | 639 |
610 if (ext->delete_file) { | 640 if (ext->delete_file) { |
611 if (ngx_delete_file(src->data) == NGX_FILE_ERROR) { | 641 if (ngx_delete_file(src->data) == NGX_FILE_ERROR) { |
612 ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno, | 642 ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno, |
613 ngx_delete_file_n " \"%s\" failed", src->data); | 643 ngx_delete_file_n " \"%s\" failed", src->data); |
614 } | 644 } |
615 } | 645 } |
616 | 646 |
617 if (err && ext->log_rename_error) { | 647 if (err) { |
618 ngx_log_error(NGX_LOG_CRIT, ext->log, err, | 648 ngx_log_error(NGX_LOG_CRIT, ext->log, err, |
619 ngx_rename_file_n " \"%s\" to \"%s\" failed", | 649 ngx_rename_file_n " \"%s\" to \"%s\" failed", |
620 src->data, to->data); | 650 src->data, to->data); |
621 } | 651 } |
622 | 652 |
623 ext->rename_error = err; | |
624 | |
625 return NGX_ERROR; | 653 return NGX_ERROR; |
654 } | |
655 | |
656 | |
657 ngx_int_t | |
658 ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf) | |
659 { | |
660 char *buf; | |
661 off_t size; | |
662 size_t len; | |
663 ssize_t n; | |
664 ngx_fd_t fd, nfd; | |
665 ngx_int_t rc; | |
666 ngx_file_info_t fi; | |
667 | |
668 rc = NGX_ERROR; | |
669 buf = NULL; | |
670 nfd = NGX_INVALID_FILE; | |
671 | |
672 fd = ngx_open_file(from, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0); | |
673 | |
674 if (fd == NGX_INVALID_FILE) { | |
675 ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno, | |
676 ngx_open_file_n " \"%s\" failed", from); | |
677 goto failed; | |
678 } | |
679 | |
680 if (cf->size != -1) { | |
681 size = cf->size; | |
682 | |
683 } else { | |
684 if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) { | |
685 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, | |
686 ngx_fd_info_n " \"%s\" failed", from); | |
687 | |
688 goto failed; | |
689 } | |
690 | |
691 size = ngx_file_size(&fi); | |
692 } | |
693 | |
694 len = cf->buf_size ? cf->buf_size : 65536; | |
695 | |
696 if ((off_t) len > size) { | |
697 len = (size_t) size; | |
698 } | |
699 | |
700 buf = ngx_alloc(len, cf->log); | |
701 if (buf == NULL) { | |
702 goto failed; | |
703 } | |
704 | |
705 nfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN, | |
706 cf->access); | |
707 | |
708 if (nfd == NGX_INVALID_FILE) { | |
709 ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno, | |
710 ngx_open_file_n " \"%s\" failed", to); | |
711 goto failed; | |
712 } | |
713 | |
714 while (size > 0) { | |
715 | |
716 if ((off_t) len > size) { | |
717 len = (size_t) size; | |
718 } | |
719 | |
720 n = ngx_read_fd(fd, buf, len); | |
721 | |
722 if (n == NGX_FILE_ERROR) { | |
723 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, | |
724 ngx_read_fd_n " \"%s\" failed", from); | |
725 goto failed; | |
726 } | |
727 | |
728 if ((size_t) n != len) { | |
729 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, | |
730 ngx_read_fd_n " has read only %z of %uz from %s", | |
731 n, size, from); | |
732 goto failed; | |
733 } | |
734 | |
735 n = ngx_write_fd(nfd, buf, len); | |
736 | |
737 if (n == NGX_FILE_ERROR) { | |
738 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, | |
739 ngx_write_fd_n " \"%s\" failed", to); | |
740 goto failed; | |
741 } | |
742 | |
743 if ((size_t) n != len) { | |
744 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, | |
745 ngx_write_fd_n " has written only %z of %uz to %s", | |
746 n, size, to); | |
747 goto failed; | |
748 } | |
749 | |
750 size -= n; | |
751 } | |
752 | |
753 if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) { | |
754 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, | |
755 ngx_set_file_time_n " \"%s\" failed", to); | |
756 goto failed; | |
757 } | |
758 | |
759 rc = NGX_OK; | |
760 | |
761 failed: | |
762 | |
763 if (nfd != NGX_INVALID_FILE) { | |
764 if (ngx_close_file(nfd) == NGX_FILE_ERROR) { | |
765 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, | |
766 ngx_close_file_n " \"%s\" failed", to); | |
767 } | |
768 } | |
769 | |
770 if (fd != NGX_INVALID_FILE) { | |
771 if (ngx_close_file(fd) == NGX_FILE_ERROR) { | |
772 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, | |
773 ngx_close_file_n " \"%s\" failed", from); | |
774 } | |
775 } | |
776 | |
777 if (buf) { | |
778 ngx_free(buf); | |
779 } | |
780 | |
781 return rc; | |
626 } | 782 } |
627 | 783 |
628 | 784 |
629 /* | 785 /* |
630 * ctx->init_handler() - see ctx->alloc | 786 * ctx->init_handler() - see ctx->alloc |