diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2015-08-31 12:43:36 +0530 |
---|---|---|
committer | Kaushal M <kaushal@redhat.com> | 2015-08-31 08:09:47 -0700 |
commit | 300a69669aa6e9ebb16e5fc8326ac57c3e2d8937 (patch) | |
tree | 94200d708a28cc44e839a5364389006665c97ce7 | |
parent | d90ed0b9b7160911c3fb8515f2947579d0fd197f (diff) |
features/shard: Fix unlink failure due to non-existent shard(s)v3.7.4
Backport of: http://review.gluster.org/#/c/12059/
Unlink of a sharded file with holes was leading to EINVAL errors
because it was being wound on non-existent shards (those blocks that
fall in the hole region). loc->inode was NULL in these cases and
dht_unlink used to fail the FOP with EINVAL for failure to fetch
cached subvol for the inode.
The fix involves winding unlink on only those shards whose corresponding
inodes exist in memory.
Change-Id: I1e5d492a2e60491601da23f64a5d0089e536b305
BUG: 1258353
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-on: http://review.gluster.org/12061
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
-rw-r--r-- | tests/bugs/shard/bug-1258334.t | 41 | ||||
-rw-r--r-- | xlators/features/shard/src/shard.c | 7 |
2 files changed, 44 insertions, 4 deletions
diff --git a/tests/bugs/shard/bug-1258334.t b/tests/bugs/shard/bug-1258334.t new file mode 100644 index 00000000000..c89caaba3f7 --- /dev/null +++ b/tests/bugs/shard/bug-1258334.t @@ -0,0 +1,41 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc + +cleanup + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1} +TEST $CLI volume set $V0 features.shard on +TEST $CLI volume set $V0 performance.strict-write-ordering on +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0 + +TEST mkdir $M0/dir +TEST touch $M0/dir/foo +TEST touch $M0/dir/bar +TEST touch $M0/dir/new + +TEST truncate -s 14M $M0/dir/foo +TEST truncate -s 14M $M0/dir/bar + +# Perform writes that fall on the 2nd block of "foo" (counting from 0) +TEST dd if=/dev/zero of=$M0/dir/foo bs=1024 seek=10240 count=2048 conv=notrunc + +# Perform writes that fall on the 2nd block of "bar" (counting from 0) +TEST dd if=/dev/zero of=$M0/dir/bar bs=1024 seek=10240 count=2048 conv=notrunc + +# Now unlink "foo". If the bug exists, it should fail with EINVAL. +TEST unlink $M0/dir/foo + +# Now rename "new" to "bar". If the bug exists, it should fail with EINVAL. +TEST mv -f $M0/dir/new $M0/dir/bar + +TEST dd if=/dev/zero of=$M0/dir/new bs=1024 count=5120 + +# Now test that this fix does not break unlink of files without holes +TEST unlink $M0/dir/new + +cleanup diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index 6fb57168371..8b784eca1a8 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -1789,13 +1789,12 @@ shard_unlink_shards_do (call_frame_t *frame, xlator_t *this, inode_t *inode) return 0; } + local->call_count = call_count = count; + cur_block = 1; SHARD_SET_ROOT_FS_ID (frame, local); while (cur_block <= last_block) { - /* The base file is unlinked in the end to mark the - * successful completion of the fop. - */ - if (cur_block == 0) { + if (!local->inode_list[cur_block]) { cur_block++; continue; } |