features/bitrot: Fail node-uuid getxattr if file is marked bad

If xattr is node-uuid and the inode is marked bad, fail getxattr
and fgetxattr with EIO. Returning EIO would result in AFR to
choose correct node-uuid coresponding to the subvolume where
the good copy of the file resides.

Change-Id: I45a42ca38f8322d2b10f3c4c48dc504521162b42
BUG: 1294786
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Reviewed-on: http://review.gluster.org/13116
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Venky Shankar <vshankar@redhat.com>
This commit is contained in:
Kotresh HR 2015-12-30 15:25:30 +05:30 committed by Venky Shankar
parent 33ca7a7384
commit b9d2a383a2
3 changed files with 97 additions and 0 deletions

View File

@ -0,0 +1,68 @@
#!/bin/bash
. $(dirname $0)/../include.rc
. $(dirname $0)/../volume.rc
. $(dirname $0)/../cluster.rc
function get_bitd_count_1 {
ps auxww | grep glusterfs | grep bitd.pid | grep -v grep | grep $H1 | wc -l
}
function get_bitd_count_2 {
ps auxww | grep glusterfs | grep bitd.pid | grep -v grep | grep $H2 | wc -l
}
function get_node_uuid {
getfattr -n trusted.glusterfs.node-uuid --only-values $M0/FILE 2>/dev/null
}
cleanup;
TEST launch_cluster 2
TEST $CLI_1 peer probe $H2;
EXPECT_WITHIN $PROBE_TIMEOUT 1 peer_count;
TEST $CLI_1 volume create $V0 replica 2 $H1:$B1 $H2:$B2
EXPECT 'Created' volinfo_field_1 $V0 'Status';
TEST $CLI_1 volume start $V0
EXPECT 'Started' volinfo_field_1 $V0 'Status';
uuid1=$($CLI_1 system:: uuid get | awk '{print $2}')
uuid2=$($CLI_2 system:: uuid get | awk '{print $2}')
##Mount $V0
TEST $GFS --volfile-id=$V0 --volfile-server=$H1 $M0
#Enable bitrot
TEST $CLI_1 volume bitrot $V0 enable
EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count_1
EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count_2
#Create sample file
TEST `echo "1234" > $M0/FILE`
EXPECT "$uuid1" get_node_uuid;
#Corrupt file from back-end
TEST stat $B1/FILE
echo "Corrupted data" >> $B1/FILE
#Manually set bad-file xattr since we can't wait for an hour for scrubber.
TEST setfattr -n trusted.bit-rot.bad-file -v 0x3100 $B1/FILE
TEST $CLI_1 volume stop $V0
TEST $CLI_1 volume start $V0
EXPECT 'Started' volinfo_field_1 $V0 'Status';
EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status_1 $V0 $H1 $B1
EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status_1 $V0 $H2 $B2
EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0
EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1
EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count_1
EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count_2
#Trigger lookup so that bitrot xlator marks file as bad in its inode context.
TEST stat $M0/FILE
EXPECT "$uuid2" get_node_uuid;
cleanup;

View File

@ -170,3 +170,10 @@ function volinfo_field_2()
$CLI_2 volume info $vol | grep "^$field: " | sed 's/.*: //';
}
function brick_up_status_1 {
local vol=$1
local host=$2
local brick=$3
$CLI_1 volume status $vol $host:$brick --xml | sed -ne 's/.*<status>\([01]\)<\/status>/\1/p'
}

View File

@ -1605,6 +1605,17 @@ br_stub_getxattr (call_frame_t *frame, xlator_t *this,
goto wind;
}
/**
* If xattr is node-uuid and the inode is marked bad, return EIO.
* Returning EIO would result in AFR to choose correct node-uuid
* coresponding to the subvolume * where the good copy of the
* file resides.
*/
if (IA_ISREG (loc->inode->ia_type) && XATTR_IS_NODE_UUID (name) &&
br_stub_check_bad_object (this, loc->inode, &op_ret, &op_errno)) {
goto unwind;
}
if (br_stub_is_internal_xattr (name))
goto unwind;
@ -1668,6 +1679,17 @@ br_stub_fgetxattr (call_frame_t *frame, xlator_t *this,
goto wind;
}
/**
* If xattr is node-uuid and the inode is marked bad, return EIO.
* Returning EIO would result in AFR to choose correct node-uuid
* coresponding to the subvolume * where the good copy of the
* file resides.
*/
if (IA_ISREG (fd->inode->ia_type) && XATTR_IS_NODE_UUID (name) &&
br_stub_check_bad_object (this, fd->inode, &op_ret, &op_errno)) {
goto unwind;
}
if (br_stub_is_internal_xattr (name))
goto unwind;