summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorLubomir Rintel <lubo.rintel@gooddata.com>2011-11-03 08:51:50 +0100
committerAnand Avati <avati@gluster.com>2012-01-12 09:11:54 -0800
commit8a78d969ee8b7c284751364d72496eec84c7290b (patch)
tree399baa6bf71bd27d28667be62f56aa161f961b8a /xlators
parent169c73f28dae61236de54889edcaa8236d91da59 (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')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c110
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) {