From 524f54f56dc506ae7fc2ef29794d399e13f69fb2 Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Wed, 10 Dec 2008 14:53:45 +0000 Subject: [PATCH] use ngx_ext_rename_file() for single file MOVE --- src/core/ngx_file.c | 18 ++++++++++------- src/core/ngx_file.h | 3 +++ src/http/modules/ngx_http_dav_module.c | 28 +++++++++++++++++++++++++- src/http/ngx_http_upstream.c | 2 ++ src/os/unix/ngx_errno.h | 1 + src/os/win32/ngx_errno.h | 9 ++++++--- 6 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c index 28980df85..fdefacf50 100644 --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -487,11 +487,13 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext) #if !(NGX_WIN32) - if (ngx_change_file_access(src->data, ext->access) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno, - ngx_change_file_access_n " \"%s\" failed", src->data); - err = 0; - goto failed; + if (ext->access) { + if (ngx_change_file_access(src->data, ext->access) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno, + ngx_change_file_access_n " \"%s\" failed", src->data); + err = 0; + goto failed; + } } #endif @@ -517,7 +519,7 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext) goto failed; } - err = ngx_create_full_path(to->data, ngx_dir_access(ext->access)); + err = ngx_create_full_path(to->data, ngx_dir_access(ext->path_access)); if (err) { ngx_log_error(NGX_LOG_CRIT, ext->log, err, @@ -561,12 +563,14 @@ failed: } } - if (err) { + if (err && ext->log_rename_error) { ngx_log_error(NGX_LOG_CRIT, ext->log, err, ngx_rename_file_n " \"%s\" to \"%s\" failed", src->data, to->data); } + ext->rename_error = err; + return NGX_ERROR; } diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h index 8e0839829..344da0957 100644 --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -60,11 +60,14 @@ typedef struct { typedef struct { ngx_uint_t access; + ngx_uint_t path_access; time_t time; ngx_fd_t fd; + ngx_err_t rename_error; unsigned create_path:1; unsigned delete_file:1; + unsigned log_rename_error:1; ngx_log_t *log; } ngx_ext_rename_file_t; diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c index 33bb2e9c1..d1dcc229a 100644 --- a/src/http/modules/ngx_http_dav_module.c +++ b/src/http/modules/ngx_http_dav_module.c @@ -246,9 +246,11 @@ ngx_http_dav_put_handler(ngx_http_request_t *r) dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); ext.access = dlcf->access; + ext.path_access = dlcf->access; ext.time = -1; ext.create_path = dlcf->create_full_put_path; ext.delete_file = 1; + ext.log_rename_error = 1; ext.log = r->connection->log; if (r->headers_in.date) { @@ -521,6 +523,7 @@ ngx_http_dav_copy_move_handler(ngx_http_request_t *r) ngx_tree_ctx_t tree; ngx_file_info_t fi; ngx_table_elt_t *dest, *over; + ngx_ext_rename_file_t ext; ngx_http_dav_copy_ctx_t copy; ngx_http_dav_loc_conf_t *dlcf; @@ -781,9 +784,32 @@ overwrite_done: } else { if (r->method == NGX_HTTP_MOVE) { - if (ngx_rename_file(path.data, copy.path.data) != NGX_FILE_ERROR) { + + dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); + + ext.access = 0; + ext.path_access = dlcf->access; + ext.time = -1; + ext.create_path = 1; + ext.delete_file = 0; + ext.log_rename_error = 0; + ext.log = r->connection->log; + + if (ngx_ext_rename_file(&path, ©.path, &ext) == NGX_OK) { return NGX_HTTP_NO_CONTENT; } + + if (ext.rename_error != NGX_EXDEV) { + + if (ext.rename_error) { + ngx_log_error(NGX_LOG_CRIT, r->connection->log, + ext.rename_error, + ngx_rename_file_n " \"%s\" to \"%s\" failed", + path.data, copy.path.data); + } + + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } } dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 840007f7b..ae56c121c 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -2288,9 +2288,11 @@ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u) } ext.access = u->conf->store_access; + ext.path_access = u->conf->store_access; ext.time = -1; ext.create_path = 1; ext.delete_file = 1; + ext.log_rename_error = 1; ext.log = r->connection->log; if (u->headers_in.last_modified) { diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h index c50d7879a..967e15dec 100644 --- a/src/os/unix/ngx_errno.h +++ b/src/os/unix/ngx_errno.h @@ -23,6 +23,7 @@ typedef int ngx_err_t; #define NGX_EACCES EACCES #define NGX_EBUSY EBUSY #define NGX_EEXIST EEXIST +#define NGX_EXDEV EXDEV #define NGX_ENOTDIR ENOTDIR #define NGX_EISDIR EISDIR #define NGX_EINVAL EINVAL diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h index 52d04bc4d..58cbbf402 100644 --- a/src/os/win32/ngx_errno.h +++ b/src/os/win32/ngx_errno.h @@ -23,10 +23,13 @@ typedef DWORD ngx_err_t; #define NGX_ENOENT ERROR_FILE_NOT_FOUND #define NGX_ENOMEM ERROR_NOT_ENOUGH_MEMORY #define NGX_EACCES ERROR_ACCESS_DENIED -#if 0 -#define NGX_EEXIST ERROR_FILE_EXISTS -#endif +/* it's seems that ERROR_FILE_EXISTS is not appropriate error code */ #define NGX_EEXIST ERROR_ALREADY_EXISTS +/* + * could not found cross volume directory move error code, + * so use ERROR_WRONG_DISK as stub one + */ +#define NGX_EXDEV ERROR_WRONG_DISK #define NGX_ENOTDIR ERROR_PATH_NOT_FOUND #define NGX_EISDIR ERROR_CANNOT_MAKE #define NGX_ENOSPC ERROR_DISK_FULL