diff options
-rwxr-xr-x | tests/bugs/bug-915554.t | 75 | ||||
-rw-r--r-- | tests/dht.rc | 13 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-rebalance.c | 6 |
3 files changed, 94 insertions, 0 deletions
diff --git a/tests/bugs/bug-915554.t b/tests/bugs/bug-915554.t new file mode 100755 index 00000000000..a811c18f656 --- /dev/null +++ b/tests/bugs/bug-915554.t @@ -0,0 +1,75 @@ +#!/bin/bash +# +# Bug <915554> +# +# This test checks for a condition where a rebalance migrates a file and does +# not preserve the original file size. This can occur due to hole preservation +# logic in the file migration code. If a file size is aligned to a disk sector +# boundary (512b) and the tail portion of the file is zero-filled, the file +# may end up truncated to the end of the last data region in the file. +# +### + +. $(dirname $0)/../include.rc +. $(dirname $0)/../dht.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd + +BRICK_COUNT=3 +# create, start and mount a two brick DHT volume +TEST $CLI volume create $V0 $H0:$B0/${V0}0 $H0:$B0/${V0}1 $H0:$B0/${V0}2 +TEST $CLI volume start $V0 + +TEST glusterfs --attribute-timeout=0 --entry-timeout=0 --gid-timeout=-1 -s $H0 --volfile-id $V0 $M0; + +i=1 +# Write some data to a file and extend such that the file is sparse to a sector +# aligned boundary. +echo test > $M0/$i +TEST truncate --size=1m $M0/$i + +# cache the original size +SIZE1=`stat -c %s $M0/$i` + +# rename till file gets a linkfile + +while [ $i -ne 0 ] +do + test=`mv $M0/$i $M0/$(( $i+1 )) 2>/dev/null` + if [ $? -ne 0 ] + then + echo "rename failed" + break + fi + let i++ + file_has_linkfile $i + has_link=$? + if [ $has_link -eq 2 ] + then + break; + fi +done + +# start a rebalance (force option to overide checks) to trigger migration of +# file + +TEST $CLI volume rebalance $V0 start force + +# check if rebalance has completed for upto 15 secs + +EXPECT_WITHIN 15 "0" rebalance_completed + +# validate the file size after the migration +SIZE2=`stat -c %s $M0/$i` + +TEST [ $SIZE1 -eq $SIZE2 ] + +TEST rm -f $M0/$i +TEST umount $M0 +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup; diff --git a/tests/dht.rc b/tests/dht.rc index 1c811a63c6e..ee92a47bd62 100644 --- a/tests/dht.rc +++ b/tests/dht.rc @@ -70,3 +70,16 @@ function get_hashed_brick() return $hashed } + + +function rebalance_completed() +{ + val=1 + test=`gluster volume rebalance $V0 status |grep localhost|grep -v "in progress" 2>&1` + if [ $? -eq 0 ] + then + val=0 + fi + + echo $val +} diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c index 0652a7aa713..866e38dc71f 100644 --- a/xlators/cluster/dht/src/dht-rebalance.c +++ b/xlators/cluster/dht/src/dht-rebalance.c @@ -300,6 +300,12 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc goto out; } + ret = syncop_ftruncate (to, fd, stbuf->ia_size); + if (ret < 0) + gf_log (this->name, GF_LOG_ERROR, + "ftruncate failed for %s on %s (%s)", + loc->path, to->name, strerror (errno)); + ret = syncop_fsetattr (to, fd, stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID), NULL, NULL); |