[PATCH] implemented hardlink option in DAV module
Maxim Dounin
mdounin at mdounin.ru
Mon Oct 15 15:33:50 UTC 2012
Hello!
On Mon, Oct 15, 2012 at 03:40:44PM +0400, Roman Arutyunyan wrote:
>
> Модуль WebDAV на текущий момент не поддерживает хардлинки.
> Я реализовал эту поддержку, патч прилагается. Буду очень признателен,
> если патч будет включен в следующие версии nginx.
>
> Добавлена директива 'hardlink on|off', по умолчанию off.
> Когда опция включена, делается попытка создать хардлинк при копировании
> файла. В случае ошибки выполняется обычное копирование.
А use case какой? Потому как в общем случае делать хардлинки
вместо копирования - это, скажем так, опасная операция.
По реализации комментарии ниже.
> index dbb17ac..e9e0623 100644
> --- a/src/http/modules/ngx_http_dav_module.c
> +++ b/src/http/modules/ngx_http_dav_module.c
> @@ -25,6 +25,7 @@ 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;
>
>
> @@ -106,6 +107,13 @@ static ngx_command_t ngx_http_dav_commands[] = {
> offsetof(ngx_http_dav_loc_conf_t, access),
> NULL },
>
> + { ngx_string("hardlink"),
> + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
> + ngx_conf_set_flag_slot,
> + NGX_HTTP_LOC_CONF_OFFSET,
> + offsetof(ngx_http_dav_loc_conf_t, hardlink),
> + NULL },
> +
Название директивы получилось черезчур общим, IMHO.
> ngx_null_command
> };
>
> @@ -813,6 +821,15 @@ overwrite_done:
>
> dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
>
> + if (dlcf->hardlink) {
> + if (ngx_hardlink_file(path.data, copy.path.data) == NGX_OK) {
> + return NGX_HTTP_NO_CONTENT;
> + }
> +
> + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, ngx_errno,
> + "hardlink error: \"%s\"", copy.path.data);
> + }
> +
> cf.size = ngx_file_size(&fi);
> cf.buf_size = 0;
> cf.access = dlcf->access;
А реализацию, наверно, имеет смысл как раз более общей, перетащив
соответствующий код в ngx_copy_file(). Аналогично тому, как
ngx_move_file() сначала пытается сделать rename(), а если не
получилось - то копирует.
> @@ -1096,6 +1113,7 @@ ngx_http_dav_create_loc_conf(ngx_conf_t *cf)
> conf->min_delete_depth = NGX_CONF_UNSET_UINT;
> conf->access = NGX_CONF_UNSET_UINT;
> conf->create_full_put_path = NGX_CONF_UNSET;
> + conf->hardlink = NGX_CONF_UNSET;
>
> return conf;
> }
> @@ -1118,6 +1136,8 @@ ngx_http_dav_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
> ngx_conf_merge_value(conf->create_full_put_path,
> prev->create_full_put_path, 0);
>
> + ngx_conf_merge_value(conf->hardlink, prev->hardlink, 0);
> +
> return NGX_CONF_OK;
> }
>
> diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
> index 9c97e2b..826960b 100644
> --- a/src/os/unix/ngx_files.h
> +++ b/src/os/unix/ngx_files.h
> @@ -157,6 +157,10 @@ ngx_write_fd(ngx_fd_t fd, void *buf, size_t n)
> #define ngx_rename_file_n "rename()"
>
>
> +#define ngx_hardlink_file(o, n) link((const char *) o, (const char *) n)
> +#define ngx_hardlink_file_n "link()"
> +
> +
> #define ngx_change_file_access(n, a) chmod((const char *) n, a)
> #define ngx_change_file_access_n "chmod()"
>
> --
> 1.7.1
И где-то тут ещё должна быть обработка для win32 (или просто код
убран под #if).
--
Maxim Dounin
http://nginx.com/support.html
Подробная информация о списке рассылки nginx-ru