From 05ba01297657deef881aa9cd2770bbe760abf090 Mon Sep 17 00:00:00 2001 From: N Balachandran Date: Mon, 21 Jan 2019 15:15:51 +0530 Subject: cluster/dht: Delete invalid linkto files in rmdir rm -rf fails on dirs which contain linkto files that point to themselves because dht incorrectly thought that they were cached files after looking them up. The fix now treats them as invalid linkto files and deletes them. Change-Id: I376c72a5309714ee339c74485e02cfb4e29be643 fixes: bz#1671611 Signed-off-by: N Balachandran --- tests/bugs/distribute/bug-1667804.t | 63 ++++++++++++++++++++++++++++++++++++ xlators/cluster/dht/src/dht-common.c | 5 ++- 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/bugs/distribute/bug-1667804.t diff --git a/tests/bugs/distribute/bug-1667804.t b/tests/bugs/distribute/bug-1667804.t new file mode 100644 index 00000000000..3f7c43111d7 --- /dev/null +++ b/tests/bugs/distribute/bug-1667804.t @@ -0,0 +1,63 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../dht.rc + +function confirm_all_linkto_files () +{ + inpath=$1 + for infile in $inpath/* + do + echo $infile + ret1=$(is_dht_linkfile $infile) + if [ "$ret1" -eq 0 ]; then + echo "$infile is not a linkto file" + echo 0 + return + fi + done + echo 1 +} + +cleanup; + +#Basic checks +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info + +#Create a distributed volume +TEST $CLI volume create $V0 $H0:$B0/${V0}{1..2}; +TEST $CLI volume start $V0 + +# Mount FUSE +TEST glusterfs -s $H0 --volfile-id $V0 $M0 + +#Create files and rename them in order to create linkto files +TEST mkdir -p $M0/dir0/dir1 +TEST touch $M0/dir0/dir1/file-{1..50} + +for i in {1..50}; do + mv $M0/dir0/dir1/file-$i $M0/dir0/dir1/nfile-$i; +done + +#Remove the second brick to force the creation of linkto files +#on the removed brick + +TEST $CLI volume remove-brick $V0 $H0:$B0/${V0}2 start +EXPECT_WITHIN $REBALANCE_TIMEOUT "completed" remove_brick_status_completed_field "$V0 $H0:$B0/${V0}2" +TEST $CLI volume remove-brick $V0 $H0:$B0/${V0}2 stop + +EXPECT "1" confirm_all_linkto_files $B0/${V0}2/dir0/dir1 + +#Modify the xattrs of the linkto files on the removed brick to point to itself. + +target=$(cat $M0/.meta/graphs/active/$V0-dht/subvolumes/1/name) + +setfattr -n trusted.glusterfs.dht.linkto -v "$target\0" $B0/${V0}2/dir0/dir1/nfile* + + +TEST rm -rf $M0/dir0 + +cleanup; diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 16a4786c12a..583875bcbb4 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -9944,7 +9944,10 @@ dht_rmdir_is_subvol_empty(call_frame_t *frame, xlator_t *this, lookup_local->loc.path, src->name, gfid); subvol = dht_linkfile_subvol(this, NULL, &trav->d_stat, trav->dict); - if (!subvol) { + if (!subvol || (subvol == src)) { + /* we need to delete the linkto file if it does not have a + * valid subvol or it points to itself. + */ gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_INVALID_LINKFILE, "Linkfile does not have link subvolume. " "path = %s, gfid = %s", -- cgit