From 09cb795587772b60ba102f4369ab3f4501cdc01a Mon Sep 17 00:00:00 2001 From: Subha sree Mohankumar Date: Thu, 2 Nov 2017 15:09:37 +0530 Subject: storage/posix : options to override umask Options "create-mask" and "create-directory-mask" are added to remove the mode bits set on a file or directory when its created. Default value of these options is 0777. Options "force-create-mode" and "force-create-directory" sets the default permission for a file or directory irrespective of the clients umask. Default value of these options is 0000. Command to set option: volume set storage. The valid value range from 0000 to 0777. Updates #301 Change-Id: Ia33d13f2117202ca55a056c747ccc3674eb8bae1 Signed-off-by: Subha sree Mohankumar --- xlators/storage/posix/src/posix.c | 142 ++++++++++++++++++++++++++++++++++---- xlators/storage/posix/src/posix.h | 7 ++ 2 files changed, 137 insertions(+), 12 deletions(-) (limited to 'xlators/storage') diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 0435d7a677f..3b03779f305 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -394,14 +394,27 @@ out: return 0; } +static inline mode_t override_umask (mode_t mode, mode_t mode_bit) +{ + gf_msg_debug ("posix", 0, "The value of mode is %u", mode); + mode = mode >> 9; /* 3x3 (bits for each octal digit)*/ + mode = (mode << 9) | mode_bit; + gf_msg_debug ("posix", 0, "The value of mode is %u", mode); + return mode; +} + static int posix_do_chmod (xlator_t *this, const char *path, struct iatt *stbuf) { int32_t ret = -1; mode_t mode = 0; + mode_t mode_bit = 0; + struct posix_private *priv = NULL; struct stat stat; int is_symlink = 0; + priv = this->private; + VALIDATE_OR_GOTO (priv, out); ret = sys_lstat (path, &stat); if (ret != 0) { gf_msg (this->name, GF_LOG_WARNING, 0, P_MSG_LSTAT_FAILED, @@ -412,7 +425,17 @@ posix_do_chmod (xlator_t *this, const char *path, struct iatt *stbuf) if (S_ISLNK (stat.st_mode)) is_symlink = 1; - mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type); + if (S_ISDIR (stat.st_mode)) { + mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type); + mode_bit = (mode & priv->create_directory_mask) + | priv->force_directory_mode; + mode = override_umask(mode, mode_bit); + } else { + mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type); + mode_bit = (mode & priv->create_mask) + | priv->force_create_mode; + mode = override_umask(mode, mode_bit); + } ret = lchmod (path, mode); if ((ret == -1) && (errno == ENOSYS)) { /* in Linux symlinks are always in mode 0777 and no @@ -633,10 +656,20 @@ int32_t posix_do_fchmod (xlator_t *this, int fd, struct iatt *stbuf) { - mode_t mode = 0; + int32_t ret = -1; + mode_t mode = 0; + mode_t mode_bit = 0; + struct posix_private *priv = NULL; + priv = this->private; + VALIDATE_OR_GOTO (priv, out); mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type); - return sys_fchmod (fd, mode); + mode_bit = (mode & priv->create_mask) + | priv->force_create_mode; + mode = override_umask (mode, mode_bit); + ret = sys_fchmod (fd, mode); +out: + return ret; } static int @@ -1392,6 +1425,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this, gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false; gf_boolean_t linked = _gf_false; gf_loglevel_t level = GF_LOG_NONE; + mode_t mode_bit = 0; DECLARE_OLD_FS_ID_VAR; @@ -1405,11 +1439,13 @@ posix_mknod (call_frame_t *frame, xlator_t *this, out); MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL); + mode_bit = (priv->create_mask & mode) | priv->force_create_mode; + mode = override_umask (mode, mode_bit); + gid = frame->root->gid; SET_FS_ID (frame->root->uid, gid); DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out); - if (!real_path || !par_path) { op_ret = -1; op_errno = ESTALE; @@ -1452,9 +1488,9 @@ posix_mknod (call_frame_t *frame, xlator_t *this, real_op: #ifdef __NetBSD__ - if (S_ISFIFO(mode)) - op_ret = mkfifo (real_path, mode); - else + if (S_ISFIFO(mode)) + op_ret = mkfifo (real_path, mode); + else #endif /* __NetBSD__ */ op_ret = sys_mknod (real_path, mode, dev); @@ -1600,6 +1636,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, char pgfid[GF_UUID_BUF_SIZE] = {0}; char value_buf[4096] = {0,}; gf_boolean_t have_val = _gf_false; + mode_t mode_bit = 0; DECLARE_OLD_FS_ID_VAR; @@ -1643,6 +1680,10 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, SET_FS_ID (frame->root->uid, gid); + mode_bit = (priv->create_directory_mask & mode) + | priv->force_directory_mode; + mode = override_umask (mode, mode_bit); + if (xdata) { op_ret = dict_get_ptr (xdata, "gfid-req", &uuid_req); if (!op_ret && !gf_uuid_compare (stbuf.ia_gfid, uuid_req)) { @@ -3089,6 +3130,7 @@ posix_create (call_frame_t *frame, xlator_t *this, int nlink_samepgfid = 0; char * pgfid_xattr_key = NULL; gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false; + mode_t mode_bit = 0; DECLARE_OLD_FS_ID_VAR; @@ -3143,6 +3185,9 @@ posix_create (call_frame_t *frame, xlator_t *this, if (priv->o_direct) _flags |= O_DIRECT; + + mode_bit = (priv->create_mask & mode) | priv->force_create_mode; + mode = override_umask (mode, mode_bit); _fd = sys_open (real_path, _flags, mode); if (_fd == -1) { @@ -3312,7 +3357,7 @@ posix_open (call_frame_t *frame, xlator_t *this, if (priv->o_direct) flags |= O_DIRECT; - _fd = sys_open (real_path, flags, 0); + _fd = sys_open (real_path, flags, priv->force_create_mode); if (_fd == -1) { op_ret = -1; op_errno = errno; @@ -7176,10 +7221,13 @@ reconfigure (xlator_t *this, dict_t *options) int32_t uid = -1; int32_t gid = -1; char *batch_fsync_mode_str = NULL; - char *gfid2path_sep = NULL; - - priv = this->private; + char *gfid2path_sep = NULL; + int32_t force_create_mode = -1; + int32_t force_directory_mode = -1; + int32_t create_mask = -1; + int32_t create_directory_mask = -1; + priv = this->private; GF_OPTION_RECONF ("brick-uid", uid, options, int32, out); GF_OPTION_RECONF ("brick-gid", gid, options, int32, out); if (uid != -1 || gid != -1) @@ -7258,8 +7306,23 @@ reconfigure (xlator_t *this, dict_t *options) GF_OPTION_RECONF ("shared-brick-count", priv->shared_brick_count, options, int32, out); + GF_OPTION_RECONF ("force-create-mode", force_create_mode, + options, int32, out); + priv->force_create_mode = force_create_mode; + + GF_OPTION_RECONF ("force-directory-mode", force_directory_mode, + options, int32, out); + priv->force_directory_mode = force_directory_mode; + + GF_OPTION_RECONF ("create-mask", create_mask, + options, int32, out); + priv->create_mask = create_mask; - ret = 0; + GF_OPTION_RECONF ("create-directory-mask", create_directory_mask, + options, int32, out); + priv->create_directory_mask = create_directory_mask; + + ret = 0; out: return ret; } @@ -7401,6 +7464,10 @@ init (xlator_t *this) int32_t gid = -1; char *batch_fsync_mode_str; char *gfid2path_sep = NULL; + int force_create = -1; + int force_directory = -1; + int create_mask = -1; + int create_directory_mask = -1; dir_data = dict_get (this->options, "directory"); @@ -7919,6 +7986,19 @@ init (xlator_t *this) GF_OPTION_INIT ("batch-fsync-delay-usec", _private->batch_fsync_delay_usec, uint32, out); + GF_OPTION_INIT ("force-create-mode", force_create, int32, out); + _private->force_create_mode = force_create; + + GF_OPTION_INIT ("force-directory-mode", force_directory, int32, out); + _private->force_directory_mode = force_directory; + + GF_OPTION_INIT ("create-mask", + create_mask, int32, out); + _private->create_mask = create_mask; + + GF_OPTION_INIT ("create-directory-mask", + create_directory_mask, int32, out); + _private->create_directory_mask = create_directory_mask; out: if (ret) { if (_private) { @@ -8190,5 +8270,43 @@ struct volume_options options[] = { " Useful for displaying the proper usable size through statvfs() " "call (df command)", }, + { .key = {"force-create-mode"}, + .type = GF_OPTION_TYPE_INT, + .min = 0000, + .max = 0777, + .default_value = "0000", + .validate = GF_OPT_VALIDATE_MIN, + .validate = GF_OPT_VALIDATE_MAX, + .description = "Mode bit permission that will always be set on a file." + }, + { .key = {"force-directory-mode"}, + .type = GF_OPTION_TYPE_INT, + .min = 0000, + .max = 0777, + .default_value = "0000", + .validate = GF_OPT_VALIDATE_MIN, + .validate = GF_OPT_VALIDATE_MAX, + .description = "Mode bit permission that will be always set on directory" + }, + { .key = {"create-mask"}, + .type = GF_OPTION_TYPE_INT, + .min = 0000, + .max = 0777, + .default_value = "0777", + .validate = GF_OPT_VALIDATE_MIN, + .validate = GF_OPT_VALIDATE_MAX, + .description = "Any bit not set here will be removed from the" + "modes set on a file when it is created" + }, + { .key = {"create-directory-mask"}, + .type = GF_OPTION_TYPE_INT, + .min = 0000, + .max = 0777, + .default_value = "0777", + .validate = GF_OPT_VALIDATE_MIN, + .validate = GF_OPT_VALIDATE_MAX, + .description = "Any bit not set here will be removed from the" + "modes set on a directory when it is created" + }, { .key = {NULL} } }; diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 8db87f1de9f..e2f1dfa2dd1 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -232,6 +232,13 @@ struct posix_private { /* Option to handle the cases of multiple bricks exported from same backend. Very much usable in brick-splitting feature. */ int32_t shared_brick_count; + + /*Option to set mode bit permission that will always be set on + file/directory. */ + mode_t force_create_mode; + mode_t force_directory_mode; + mode_t create_mask; + mode_t create_directory_mask; }; typedef struct { -- cgit