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