diff options
-rw-r--r-- | tests/bugs/bitrot/bug-1288490.t | 48 | ||||
-rw-r--r-- | tests/volume.rc | 8 | ||||
-rw-r--r-- | xlators/features/bit-rot/src/stub/bit-rot-stub.c | 63 |
3 files changed, 87 insertions, 32 deletions
diff --git a/tests/bugs/bitrot/bug-1288490.t b/tests/bugs/bitrot/bug-1288490.t new file mode 100644 index 00000000000..1d5e913cd59 --- /dev/null +++ b/tests/bugs/bitrot/bug-1288490.t @@ -0,0 +1,48 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd + +TEST $CLI volume create $V0 replica 2 $H0:$B0/brick{0,1} +TEST $CLI volume start $V0 + +TEST $CLI volume bitrot $V0 enable +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count + +TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0 +TEST dd if=/dev/urandom of=$M0/FILE bs=1024 count=1 + +# corrupt data -- append 2 bytes +echo -n "~~" >> $B0/brick0/FILE +# manually set bad-file xattr +TEST setfattr -n trusted.bit-rot.bad-file -v 0x3100 $B0/brick0/FILE + +TEST $CLI volume stop $V0 +TEST $CLI volume start $V0 +EXPECT 'Started' volinfo_field $V0 'Status'; +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" brick_up_status $V0 $H0 $B0/brick0 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" brick_up_status $V0 $H0 $B0/brick1 +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 + +# trigger lookup +TEST stat $M0/FILE + +# extend the file +TEST dd if=/dev/urandom of=$M0/FILE bs=1024 count=1 oflag=append conv=notrunc + +# check backend file size +EXPECT "1026" stat -c "%s" $B0/brick0/FILE +EXPECT "2048" stat -c "%s" $B0/brick1/FILE + +# check file size on mount +EXPECT "2048" stat -c "%s" $M0/FILE + +TEST umount $M0 +cleanup diff --git a/tests/volume.rc b/tests/volume.rc index 15037059deb..8724c08d249 100644 --- a/tests/volume.rc +++ b/tests/volume.rc @@ -19,6 +19,14 @@ function online_brick_count () pgrep glusterfsd | wc -l } +function brick_up_status { + local vol=$1 + local host=$2 + local brick=$3 + brick_pid=$(get_brick_pid $vol $host $brick) + gluster volume status | grep $brick_pid | awk '{print $4}' +} + function volume_option() { local vol=$1 diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.c b/xlators/features/bit-rot/src/stub/bit-rot-stub.c index d082817c67e..5b2d5d70698 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c @@ -2768,53 +2768,51 @@ br_stub_lookup (call_frame_t *frame, /** {{{ */ -/* fstat() */ -int br_stub_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf, - dict_t *xdata) +/* stat */ +int +br_stub_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { + int32_t ret = 0; + int32_t op_ret = -1; + int32_t op_errno = EINVAL; - int ret = 0; - br_stub_local_t *local = NULL; - inode_t *inode = NULL; + if (!IA_ISREG (loc->inode->ia_type)) + goto wind; - local = frame->local; - frame->local = NULL; - inode = local->u.context.inode; + ret = br_stub_check_bad_object (this, loc->inode, &op_ret, &op_errno); + if (ret) + goto unwind; - ret = br_stub_mark_xdata_bad_object (this, inode, xdata); - if (ret) { - op_ret = -1; - op_errno = EIO; - } + wind: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->stat, loc, xdata); + return 0; - br_stub_cleanup_local(local); - br_stub_dealloc_local(local); - STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata); +unwind: + STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, NULL, NULL); return 0; } +/* fstat */ int br_stub_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { - br_stub_local_t *local = NULL; - int32_t op_ret = -1; - int32_t op_errno = EINVAL; + int32_t ret = 0; + int32_t op_ret = -1; + int32_t op_errno = EINVAL; - local = br_stub_alloc_local (this); - if (!local) { - op_ret = -1; - op_errno = ENOMEM; - goto unwind; - } + if (!IA_ISREG (fd->inode->ia_type)) + goto wind; - br_stub_fill_local (local, NULL, fd, fd->inode, fd->inode->gfid, - BR_STUB_NO_VERSIONING, 0); - frame->local = local; + ret = br_stub_check_bad_object (this, fd->inode, &op_ret, &op_errno); + if (ret) + goto unwind; - STACK_WIND (frame, br_stub_fstat_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fstat, fd, xdata); + wind: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; + unwind: STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, NULL, NULL); return 0; @@ -3098,6 +3096,7 @@ unblock: struct xlator_fops fops = { .lookup = br_stub_lookup, + .stat = br_stub_stat, .fstat = br_stub_fstat, .open = br_stub_open, .create = br_stub_create, |