From 6688c4786c14780af8ab5fdd480c10efc29803c1 Mon Sep 17 00:00:00 2001 From: Stefan Chivu Date: Mon, 28 Nov 2022 17:24:08 +0200 Subject: [PATCH] dokan: Made file/dir access mode configurable By default, when mounting a filesystem using ceph-dokan, the file and directory access modes were hardcoded as 755. Now, both the file and directory access modes are configurable using the --file-mode and --dir-mode optargs, accepting values ranging from 001 to 777. If no value is specified, the default value of 755 will be used. Signed-off-by: Stefan Chivu --- src/dokan/ceph_dokan.cc | 25 +++++++++++++++---------- src/dokan/ceph_dokan.h | 2 ++ src/dokan/options.cc | 21 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/dokan/ceph_dokan.cc b/src/dokan/ceph_dokan.cc index 4a4f78cdb66e8..4738d096ac4ba 100644 --- a/src/dokan/ceph_dokan.cc +++ b/src/dokan/ceph_dokan.cc @@ -111,7 +111,7 @@ static NTSTATUS WinCephCreateDirectory( return 0; } - int ret = ceph_mkdir(cmount, path.c_str(), 0755); + int ret = ceph_mkdir(cmount, path.c_str(), g_cfg->dir_mode); if (ret < 0) { dout(2) << __func__ << " " << path << ": ceph_mkdir failed. Error: " << ret << dendl; @@ -166,13 +166,14 @@ static NTSTATUS WinCephCreateFile( return STATUS_OBJECT_NAME_COLLISION; case TRUNCATE_EXISTING: // open O_TRUNC & return 0 - return do_open_file(path, O_CREAT | O_TRUNC | O_RDWR, 0755, fdc); + return do_open_file(path, O_CREAT | O_TRUNC | O_RDWR, + g_cfg->file_mode, fdc); case OPEN_ALWAYS: // open & return STATUS_OBJECT_NAME_COLLISION if (!WRITE_ACCESS_REQUESTED(AccessMode)) fdc->read_only = 1; if ((st = do_open_file(path, fdc->read_only ? O_RDONLY : O_RDWR, - 0755, fdc))) + g_cfg->file_mode, fdc))) return st; return STATUS_OBJECT_NAME_COLLISION; case OPEN_EXISTING: @@ -180,12 +181,13 @@ static NTSTATUS WinCephCreateFile( if (!WRITE_ACCESS_REQUESTED(AccessMode)) fdc->read_only = 1; if ((st = do_open_file(path, fdc->read_only ? O_RDONLY : O_RDWR, - 0755, fdc))) + g_cfg->file_mode, fdc))) return st; return 0; case CREATE_ALWAYS: // open O_TRUNC & return STATUS_OBJECT_NAME_COLLISION - if ((st = do_open_file(path, O_CREAT | O_TRUNC | O_RDWR, 0755, fdc))) + if ((st = do_open_file(path, O_CREAT | O_TRUNC | O_RDWR, + g_cfg->file_mode, fdc))) return st; return STATUS_OBJECT_NAME_COLLISION; } @@ -204,7 +206,7 @@ static NTSTATUS WinCephCreateFile( return 0; case OPEN_ALWAYS: case OPEN_EXISTING: - return do_open_file(path, O_RDONLY, 0755, fdc); + return do_open_file(path, O_RDONLY, g_cfg->file_mode, fdc); case CREATE_ALWAYS: return STATUS_OBJECT_NAME_COLLISION; } @@ -220,18 +222,21 @@ static NTSTATUS WinCephCreateFile( if ((st = WinCephCreateDirectory(FileName, DokanFileInfo))) return st; // Dokan expects a file handle even when creating new directories. - return do_open_file(path, O_RDONLY, 0755, fdc); + return do_open_file(path, O_RDONLY, g_cfg->file_mode, fdc); } dout(20) << __func__ << " " << path << ". New file." << dendl; switch (CreationDisposition) { case CREATE_NEW: // create & return 0 - return do_open_file(path, O_CREAT | O_RDWR | O_EXCL, 0755, fdc); + return do_open_file(path, O_CREAT | O_RDWR | O_EXCL, + g_cfg->file_mode, fdc); case CREATE_ALWAYS: // create & return 0 - return do_open_file(path, O_CREAT | O_TRUNC | O_RDWR, 0755, fdc); + return do_open_file(path, O_CREAT | O_TRUNC | O_RDWR, + g_cfg->file_mode, fdc); case OPEN_ALWAYS: - return do_open_file(path, O_CREAT | O_RDWR, 0755, fdc); + return do_open_file(path, O_CREAT | O_RDWR, + g_cfg->file_mode, fdc); case OPEN_EXISTING: case TRUNCATE_EXISTING: dout(2) << __func__ << " " << path << ": Not found." << dendl; diff --git a/src/dokan/ceph_dokan.h b/src/dokan/ceph_dokan.h index 489ed6d26872b..5957d4dead11e 100644 --- a/src/dokan/ceph_dokan.h +++ b/src/dokan/ceph_dokan.h @@ -34,6 +34,8 @@ struct Config { std::wstring win_vol_name = L""; unsigned long win_vol_serial = 0; unsigned long max_path_len = 256; + mode_t file_mode = 0755; + mode_t dir_mode = 0755; }; extern Config *g_cfg; diff --git a/src/dokan/options.cc b/src/dokan/options.cc index 27b8569441eef..4cfe08cdbe2ca 100644 --- a/src/dokan/options.cc +++ b/src/dokan/options.cc @@ -7,6 +7,7 @@ * Foundation. See file COPYING. * */ +#include #include "include/compat.h" #include "include/cephfs/libcephfs.h" @@ -41,6 +42,8 @@ Map options: --win-vol-name arg The Windows volume name. Default: Ceph - . --win-vol-serial arg The Windows volume serial number. Default: . --max-path-len The value of the maximum path length. Default: 256. + --file-mode The access mode to be used when creating files. + --dir-mode The access mode to be used when creating directories. Unmap options: -l [ --mountpoint ] arg mountpoint (path or drive letter) (e.g -l x). @@ -87,6 +90,8 @@ int parse_args( std::string win_vol_name; std::string win_vol_serial; std::string max_path_len; + std::string file_mode; + std::string dir_mode; int thread_count; @@ -134,6 +139,22 @@ int parse_args( } cfg->max_path_len = max_path_length; + } else if (ceph_argparse_witharg(args, i, &file_mode, "--file-mode", (char *)NULL)) { + mode_t mode = strtol(file_mode.c_str(), NULL, 8); + if (!std::regex_match(file_mode, std::regex("^[0-7]{3}$")) + || mode < 01 || mode > 0777) { + *err_msg << "ceph-dokan: invalid file access mode"; + return -EINVAL; + } + cfg->file_mode = mode; + } else if (ceph_argparse_witharg(args, i, &dir_mode, "--dir-mode", (char *)NULL)) { + mode_t mode = strtol(dir_mode.c_str(), NULL, 8); + if (!std::regex_match(dir_mode, std::regex("^[0-7]{3}$")) + || mode < 01 || mode > 0777) { + *err_msg << "ceph-dokan: invalid directory access mode"; + return -EINVAL; + } + cfg->dir_mode = mode; } else if (ceph_argparse_flag(args, i, "--current-session-only", (char *)NULL)) { cfg->current_session_only = true; } else if (ceph_argparse_witharg(args, i, &thread_count, -- 2.47.3