diff options
author | Lubomir Rintel <lubo.rintel@gooddata.com> | 2011-11-03 08:51:50 +0100 |
---|---|---|
committer | Anand Avati <avati@gluster.com> | 2012-01-12 09:11:54 -0800 |
commit | 8a78d969ee8b7c284751364d72496eec84c7290b (patch) | |
tree | 399baa6bf71bd27d28667be62f56aa161f961b8a /xlators/mount/fuse | |
parent | 169c73f28dae61236de54889edcaa8236d91da59 (diff) |
fuse-bridge: preserve original mode and umask
FUSE used to interpret the umask itself. That was a bad idea, since
there are cases where umask is not applied, such as when extended POSIX
ACLs are present and default ACLs are set on parent directory.
Thus, FUSE was changed to pass umask to operation handler itself in case
the fuse server is initialized with FUSE_DONT_MASK. In case FUSE
supports it, gluster client sends mode unmasked and umask separately (
masked mode is still sent, for compatibility with old servers).
the mode as-is for compatibility with older clients.
Change-Id: I55862b39a25261446f18ba0b3c03f85b41c4d722
Signed-off-by: Lubomir Rintel <lubo.rintel@gooddata.com>
Tested-by: Lubomir Rintel <lubo.rintel@gooddata.com>
BUG: 765508
Reviewed-on: http://review.gluster.com/667
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@gluster.com>
Diffstat (limited to 'xlators/mount/fuse')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 5b3845919aa..32c80075356 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -1233,6 +1233,40 @@ fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg) state->mode = fmi->mode; state->rdev = fmi->rdev; + priv = this->private; +#if FUSE_KERNEL_MINOR_VERSION >=12 + if (priv->proto_minor >= 12) + state->mode &= ~fmi->umask; + if (priv->proto_minor >= 12 && priv->acl) { + state->dict = dict_new (); + if (!state->dict) { + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "MKNOD Failed to allocate a param dictionary"); + send_fuse_err (this, finh, ENOMEM); + free_fuse_state (state); + return; + } + ret = dict_set_int16 (state->dict, "umask", fmi->umask); + if (ret < 0) { + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "MKNOD Failed adding umask to request"); + dict_destroy (state->dict); + send_fuse_err (this, finh, ENOMEM); + free_fuse_state (state); + return; + } + ret = dict_set_int16 (state->dict, "mode", fmi->mode); + if (ret < 0) { + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "MKNOD Failed adding mode to request"); + dict_destroy (state->dict); + send_fuse_err (this, finh, ENOMEM); + free_fuse_state (state); + return; + } + } +#endif + uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); state->resolve.bname = gf_strdup (name); state->resolve.path = gf_strdup (state->loc.path); @@ -1273,6 +1307,7 @@ fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg) { struct fuse_mkdir_in *fmi = msg; char *name = (char *)(fmi + 1); + fuse_private_t *priv = NULL; fuse_state_t *state; int32_t ret = -1; @@ -1293,6 +1328,40 @@ fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg) state->mode = fmi->mode; + priv = this->private; +#if FUSE_KERNEL_MINOR_VERSION >=12 + if (priv->proto_minor >= 12) + state->mode &= ~fmi->umask; + if (priv->proto_minor >= 12 && priv->acl) { + state->dict = dict_new (); + if (!state->dict) { + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "MKDIR Failed to allocate a param dictionary"); + send_fuse_err (this, finh, ENOMEM); + free_fuse_state (state); + return; + } + ret = dict_set_int16 (state->dict, "umask", fmi->umask); + if (ret < 0) { + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "MKDIR Failed adding umask to request"); + dict_destroy (state->dict); + send_fuse_err (this, finh, ENOMEM); + free_fuse_state (state); + return; + } + ret = dict_set_int16 (state->dict, "mode", fmi->mode); + if (ret < 0) { + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "MKDIR Failed adding mode to request"); + dict_destroy (state->dict); + send_fuse_err (this, finh, ENOMEM); + free_fuse_state (state); + return; + } + } +#endif + uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); state->resolve.bname = gf_strdup (name); state->resolve.path = gf_strdup (state->loc.path); @@ -1798,6 +1867,40 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg) state->mode = fci->mode; state->flags = fci->flags; + priv = this->private; +#if FUSE_KERNEL_MINOR_VERSION >=12 + if (priv->proto_minor >= 12) + state->mode &= ~fci->umask; + if (priv->proto_minor >= 12 && priv->acl) { + state->dict = dict_new (); + if (!state->dict) { + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "CREATE Failed to allocate a param dictionary"); + send_fuse_err (this, finh, ENOMEM); + free_fuse_state (state); + return; + } + ret = dict_set_int16 (state->dict, "umask", fci->umask); + if (ret < 0) { + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "CREATE Failed adding umask to request"); + dict_destroy (state->dict); + send_fuse_err (this, finh, ENOMEM); + free_fuse_state (state); + return; + } + ret = dict_set_int16 (state->dict, "mode", fci->mode); + if (ret < 0) { + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "CREATE Failed adding mode to request"); + dict_destroy (state->dict); + send_fuse_err (this, finh, ENOMEM); + free_fuse_state (state); + return; + } + } +#endif + uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); state->resolve.bname = gf_strdup (name); state->resolve.path = gf_strdup (state->loc.path); @@ -3131,6 +3234,13 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg) fino.max_readahead = 1 << 17; fino.max_write = 1 << 17; fino.flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS; +#if FUSE_KERNEL_MINOR_VERSION >= 12 + if (fini->minor >= 12) { + /* let fuse leave the umask processing to us, so that it does not + * break extended POSIX ACL defaults on server */ + fino.flags |= FUSE_DONT_MASK; + } +#endif #if FUSE_KERNEL_MINOR_VERSION >= 9 if (fini->minor >= 6 /* fuse_init_in has flags */ && fini->flags & FUSE_BIG_WRITES) { |