features/gfid-access: Fix entry operations

Problem:
When more than one aux-mounts are performing rmdir .gfid/<pargfid>/dir
simultaneously, then sometimes a hang is observed.  In gfid-access xlator When
virtual parent/inode are replaced with real parent/inode in loc, virtual
pargfid/gfid are not replaced with real pargfid/gfid respectively. Afr is using
parent_loc->gfids to order the entry locks. But parent_loc->gfid contains
random/virtual gfid generated by gfid-access xlator. Entrylk in client xlator
is using loc->inod->gfid for sending entrylk which has 'real' gfid. Because the
ordering is happening based on random gfids, One mount orders the locks as (L1,
L2) where as the other orders them as (L2, L1) leading to a dead-lock thus
a hang.

Fix:
Replace virtual pargfid/gfid with real pargfid/gfid when virtual-inodes are
replaced with real-inodes in loc.

BUG: 1114501
Change-Id: Ie94e816122ef9e7aad51605adbf49291de60827e
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: http://review.gluster.org/8204
Reviewed-by: Kotresh HR <khiremat@redhat.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Tested-by: Vijay Bellur <vbellur@redhat.com>
This commit is contained in:
Pranith Kumar K 2014-07-03 06:50:56 +05:30 committed by Vijay Bellur
parent 83c09b75a8
commit 8202705f98
2 changed files with 24 additions and 7 deletions

View File

@ -36,6 +36,24 @@ TEST chmod 0777 $M0/.gfid/$a_gfid_str
EXPECT "777" stat -c "%a" $M0/a
EXPECT "777" stat -c "%a" $M0/.gfid/$a_gfid_str
#Entry operations on directory
#Test that virtual directories are not allowed to be deleted.
TEST ! mkdir $M0/.gfid
TEST ! rmdir $M0/.gfid
TEST ! touch $M0/.gfid
TEST ! rm -f $M0/.gfid
TEST ! mv $M0/.gfid $M0/dont-rename
TEST ! ln -s $M0/symlink $M0/.gfid
TEST ! ln $M0/.gfid $M0/hlink
TEST ! mknod $M0/.gfid b 0 0
#Test that first level directory/file creations inside .gfid are not allowed.
TEST ! mkdir $M0/.gfid/a
TEST ! touch $M0/.gfid/a
TEST ! mv /etc/passwd $M0/.gfid
TEST ! mv $M0/a $M0/.gfid
TEST ! mknod $M0/.gfid/b b 0 0
#Operations on File
TEST setfattr -n trusted.abc -v abc $M0/b
EXPECT "abc" echo $(getfattr -n trusted.abc $M0/b)

View File

@ -30,6 +30,9 @@ ga_valid_inode_loc_copy (loc_t *dst, loc_t *src, xlator_t *this)
if (ret < 0)
goto out;
/*
* Change ALL virtual inodes with real-inodes in loc
*/
if (dst->parent) {
ret = inode_ctx_get (dst->parent, this, &value);
if (ret < 0) {
@ -38,14 +41,9 @@ ga_valid_inode_loc_copy (loc_t *dst, loc_t *src, xlator_t *this)
}
inode_unref (dst->parent);
dst->parent = inode_ref ((inode_t*)value);
/* if parent is virtual, no need to handle */
/* loc->inode */
goto out;
uuid_copy (dst->pargfid, dst->parent->gfid);
}
/* if its an inode operation, on the virtual */
/* directory inode itself, we need to handle */
/* it properly */
if (dst->inode) {
ret = inode_ctx_get (dst->inode, this, &value);
if (ret < 0) {
@ -54,9 +52,10 @@ ga_valid_inode_loc_copy (loc_t *dst, loc_t *src, xlator_t *this)
}
inode_unref (dst->inode);
dst->inode = inode_ref ((inode_t*)value);
goto out;
uuid_copy (dst->gfid, dst->inode->gfid);
}
out:
return ret;
}