From 0f4bd0b927f90e70252e613c980bb196395db9ea Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Tue, 15 Sep 2015 16:56:01 +0530 Subject: features/gfid-access: Fix entry creation via setxattr for geo-rep GEO-REP INTEROP WITH SHARD FEATURE Problem: Geo-replication uses setxattr interface of gfid-access xlator to create entries and send explicit setattr after entry creation to set uid and gid. But between entry creation and setattr, the inode would not be linked. Hence operation which accesses inode structure during setattr by any the below xlator fails. Solution: Linking inode would seem the obvious solution but, gfid-access xlator cannot link inodes and maintain it as it would result in same inode pointing to two different paths one being virtual .gfid/ path and other being actual path. The solution is to set uid and gid in frame->root->uid and frame->root->gid respectively from which posix extracts and sets. BUG: 1284453 Change-Id: I881c3541f7b056f25ee25b382957d71c821113c1 Signed-off-by: Kotresh HR Reviewed-on: http://review.gluster.org/12206 Tested-by: NetBSD Build System Reviewed-by: Aravinda VK Tested-by: Gluster Build System Reviewed-by: Venky Shankar Reviewed-on: http://review.gluster.org/12731 Reviewed-by: Milind Changire --- xlators/features/gfid-access/src/gfid-access.c | 47 ++------------------------ 1 file changed, 2 insertions(+), 45 deletions(-) (limited to 'xlators') diff --git a/xlators/features/gfid-access/src/gfid-access.c b/xlators/features/gfid-access/src/gfid-access.c index d5054432d76..438fb08aaf1 100644 --- a/xlators/features/gfid-access/src/gfid-access.c +++ b/xlators/features/gfid-access/src/gfid-access.c @@ -400,33 +400,6 @@ 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); - - if (local->xdata) - dict_unref (local->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, @@ -435,24 +408,9 @@ ga_newentry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, dict_t *xdata) { ga_local_t *local = NULL; - struct iatt temp_stat = {0,}; local = frame->local; - /* no need to proceed if things don't look good here */ - if (op_ret == -1) - 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. */ @@ -544,12 +502,11 @@ ga_new_entry (call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *data, 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; + new_frame->root->uid = args->uid; + new_frame->root->gid = args->gid; if (S_ISDIR (args->st_mode)) { STACK_WIND (new_frame, ga_newentry_cbk, -- cgit