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 bc5252ee9cd..cc3691cc273 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);  | 
