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,  | 
