summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrutika Dhananjay <kdhananj@redhat.com>2015-08-31 12:43:36 +0530
committerVijay Bellur <vbellur@redhat.com>2015-08-31 08:08:07 -0700
commit7566c94633b602156755297493fad1d24d1ba52f (patch)
treedd99480df28b46085e647aac7fd7d3d64e9d24e6
parentfb8c9b38d8c42ecaf17df6e28c2a97d2cf13fb14 (diff)
features/shard: Fix unlink failure due to non-existent shard(s)
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: I993ff70cab4b22580c772a9c74fc19ac893a03fc BUG: 1258334 Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com> Reviewed-on: http://review.gluster.org/12059 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> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r--tests/bugs/shard/bug-1258334.t41
-rw-r--r--xlators/features/shard/src/shard.c7
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;
}