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/<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.

Change-Id: Ic0749ee471432caeb8ded3152a07de6e64d8538d
BUG: 1265148
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Reviewed-on: http://review.gluster.org/12206
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Aravinda VK <avishwan@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Venky Shankar <vshankar@redhat.com>
This commit is contained in:
Kotresh HR 2015-09-15 16:56:01 +05:30 committed by Venky Shankar
parent 4ac2ff18db
commit c0522295f4
2 changed files with 3 additions and 45 deletions

View File

@ -16,6 +16,7 @@ TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0 --aux-gfid-mount
# create file with specific gfid
uuid=`uuidgen`
TEST chown 10:10 $M0
EXPECT "File creation OK" $PYTHON $(dirname $0)/../../utils/gfid-access.py \
$M0 ROOT file0 $uuid file 10 10 0644

View File

@ -392,33 +392,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,
@ -427,24 +400,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.
*/
@ -536,12 +494,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,