[PATCH] implemented DAV copy hardlinks

Maxim Dounin mdounin at mdounin.ru
Tue Oct 16 15:44:55 UTC 2012


Hello!

On Tue, Oct 16, 2012 at 04:52:06PM +0400, Roman Arutyunyan wrote:

> Новая версия патча. Вроде учел все замечания.
> Опция называется 'dav_copy_hardlink'.
> Если у кого-то есть идеи получше касательно названия, предлагайте.
> ---
>  src/core/ngx_file.c                    |   21 +++++++++++++++++++++
>  src/core/ngx_file.h                    |    2 ++
>  src/http/modules/ngx_http_dav_module.c |   17 +++++++++++++++++
>  3 files changed, 40 insertions(+), 0 deletions(-)
> 
> diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
> index d9b30f8..c960f04 100644
> --- a/src/core/ngx_file.c
> +++ b/src/core/ngx_file.c
> @@ -608,6 +608,7 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
>          cf.access = ext->access;
>          cf.time = ext->time;
>          cf.log = ext->log;
> +        cf.hardlink = 0;
>  
>          name = ngx_alloc(to->len + 1 + 10 + 1, ext->log);
>          if (name == NULL) {
> @@ -681,6 +682,24 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
>      rc = NGX_ERROR;
>      buf = NULL;
>      nfd = NGX_INVALID_FILE;
> +    fd = NGX_INVALID_FILE;
> +
> +#ifndef NGX_WIN32
> +    if (cf->hardlink &&
> +        link((const char *) from, (const char *) to) == NGX_OK)
> +    {

1) Я бы всё-таки сделал wrapper, как в предыдущем патче, с тем 
чтобы можно было дописать потом и для виндов с минимальными 
трудозатратами.

2) Ошибки всё-таки стоит проверять, и наверное копировать только в 
случае NGX_EXDEV.

> +        if (chmod((const char *) to, cf->access) != NGX_OK) {
> +            ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
> +                          "chmod() \"%s\" failed", to);

ngx_change_file_access()

> +
> +            ngx_delete_file(to);
> +
> +            goto failed;
> +        }
> +
> +        goto set_time;

goto done?

> +    }
> +#endif
>  
>      fd = ngx_open_file(from, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
>  
> @@ -763,6 +782,8 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
>          size -= n;
>      }
>  
> +set_time:
> +
>      if (cf->time != -1) {
>          if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) {
>              ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,

Note: под win32 это сломается, т.к. там для ngx_set_file_time() 
требуется файловый дескриптор.

> diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h
> index 7023e67..81c706a 100644
> --- a/src/core/ngx_file.h
> +++ b/src/core/ngx_file.h
> @@ -94,6 +94,8 @@ typedef struct {
>      ngx_uint_t                 access;
>      time_t                     time;
>  
> +    unsigned                   hardlink:1;
> +
>      ngx_log_t                 *log;
>  } ngx_copy_file_t;
>  
> diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
> index dbb17ac..f9e5daf 100644
> --- a/src/http/modules/ngx_http_dav_module.c
> +++ b/src/http/modules/ngx_http_dav_module.c
> @@ -25,12 +25,14 @@ typedef struct {
>      ngx_uint_t  access;
>      ngx_uint_t  min_delete_depth;
>      ngx_flag_t  create_full_put_path;
> +    ngx_flag_t  hardlink;
>  } ngx_http_dav_loc_conf_t;
>  
>  
>  typedef struct {
>      ngx_str_t   path;
>      size_t      len;
> +    unsigned    hardlink:1;
>  } ngx_http_dav_copy_ctx_t;

Может, чтобы два раза не вставать, имеет смысл протащить тут сразу 
указатель на конфигурацию?  Или даже вообще на объект запроса?

[...]

-- 
Maxim Dounin
http://nginx.com/support.html



Подробная информация о списке рассылки nginx-ru