diff options
author | Amar Tumballi <amarts@redhat.com> | 2013-09-06 14:50:35 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-01-27 07:50:21 -0800 |
commit | 0d739e788dddd591a015921991c3112400f3d3a1 (patch) | |
tree | ccc92a3957d0ea6f6b4404dced654525be85d4c2 /xlators | |
parent | 3744b1dfe3baedfd2f210edd7680454a5e32296f (diff) |
gfid-access: do chown() after creating the new entries.
changing the 'frame->root->uid' on the fly is not a good idea as
posix-acl xlator on brick process would fail the op.
Change-Id: I996b43e4ce6efb04f52949976339dad6eb89bede
Signed-off-by: Amar Tumballi <amarts@redhat.com>
BUG: 847839
Reviewed-on: http://review.gluster.org/5833
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Reviewed-on: http://review.gluster.org/6801
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/features/gfid-access/src/gfid-access.c | 73 | ||||
-rw-r--r-- | xlators/features/gfid-access/src/gfid-access.h | 8 |
2 files changed, 73 insertions, 8 deletions
diff --git a/xlators/features/gfid-access/src/gfid-access.c b/xlators/features/gfid-access/src/gfid-access.c index da0ba7e5046..1566278efe3 100644 --- a/xlators/features/gfid-access/src/gfid-access.c +++ b/xlators/features/gfid-access/src/gfid-access.c @@ -346,6 +346,31 @@ ga_heal_cbk (call_frame_t *frame, void *cookie, xlator_t *this, return 0; } +static int32_t +ga_newentry_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *statpre, + struct iatt *statpost, + dict_t *xdata) +{ + ga_local_t *local = NULL; + + local = frame->local; + frame->local = NULL; + + /* don't worry about inode linking and other stuff. They'll happen on + * the next lookup. + */ + STACK_DESTROY (frame->root); + + STACK_UNWIND_STRICT (setxattr, local->orig_frame, op_ret, + op_errno, xdata); + + loc_wipe (&local->loc); + mem_put (local); + + return 0; +} + static int ga_newentry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, @@ -353,17 +378,35 @@ ga_newentry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { - call_frame_t *orig_frame = NULL; + ga_local_t *local = NULL; + struct iatt temp_stat = {0,}; - orig_frame = frame->local; - frame->local = NULL; + local = frame->local; + + if (!local->uid && !local->gid) + goto done; + + temp_stat.ia_uid = local->uid; + temp_stat.ia_gid = local->gid; + + STACK_WIND (frame, ga_newentry_setattr_cbk, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->setattr, &local->loc, &temp_stat, + (GF_SET_ATTR_UID | GF_SET_ATTR_GID), xdata); + return 0; + +done: /* don't worry about inode linking and other stuff. They'll happen on * the next lookup. */ + frame->local = NULL; STACK_DESTROY (frame->root); - STACK_UNWIND_STRICT (setxattr, orig_frame, op_ret, op_errno, xdata); + STACK_UNWIND_STRICT (setxattr, local->orig_frame, op_ret, + op_errno, xdata); + + loc_wipe (&local->loc); + mem_put (local); return 0; } @@ -377,6 +420,7 @@ ga_new_entry (call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *data, loc_t tmp_loc = {0,}; call_frame_t *new_frame = NULL; mode_t mode = 0; + ga_local_t *local = NULL; args = ga_newfile_parse_args (this, data); if (!args) @@ -393,10 +437,16 @@ ga_new_entry (call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *data, new_frame = copy_frame (frame); if (!new_frame) goto out; - new_frame->local = (void *)frame; - new_frame->root->uid = args->uid; - new_frame->root->gid = args->gid; + local = mem_get0 (this->local_pool); + local->orig_frame = frame; + + local->uid = args->uid; + local->gid = args->gid; + + loc_copy (&local->loc, &tmp_loc); + + new_frame->local = local; if (S_ISDIR (args->st_mode)) { STACK_WIND (new_frame, ga_newentry_cbk, @@ -411,7 +461,7 @@ ga_new_entry (call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *data, } else { /* use 07777 (4 7s) for considering the Sticky bits etc) */ mode = (S_IFMT & args->st_mode) | - (07777 | args->args.mknod.mode);; + (07777 & args->args.mknod.mode);; STACK_WIND (new_frame, ga_newentry_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, @@ -1106,6 +1156,13 @@ init (xlator_t *this) if (!priv->heal_args_pool) goto out; + this->local_pool = mem_pool_new (ga_local_t, 16); + if (!this->local_pool) { + gf_log (this->name, GF_LOG_ERROR, + "failed to create local_t's memory pool"); + goto out; + } + this->private = priv; ret = 0; diff --git a/xlators/features/gfid-access/src/gfid-access.h b/xlators/features/gfid-access/src/gfid-access.h index e13c9b7240b..3b74ce1121a 100644 --- a/xlators/features/gfid-access/src/gfid-access.h +++ b/xlators/features/gfid-access/src/gfid-access.h @@ -125,4 +125,12 @@ struct ga_private { }; typedef struct ga_private ga_private_t; +struct __ga_local { + call_frame_t *orig_frame; + unsigned int uid; + unsigned int gid; + loc_t loc; +}; +typedef struct __ga_local ga_local_t; + #endif /* __GFID_ACCESS_H__ */ |