diff options
authorKrutika Dhananjay <>2015-08-31 12:43:36 +0530
committerKaushal M <>2015-08-31 08:09:47 -0700
commit300a69669aa6e9ebb16e5fc8326ac57c3e2d8937 (patch)
parentd90ed0b9b7160911c3fb8515f2947579d0fd197f (diff)
features/shard: Fix unlink failure due to non-existent shard(s)v3.7.4
Backport of: 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 <> Reviewed-on: Reviewed-by: Pranith Kumar Karampuri <> Tested-by: NetBSD Build System <> Tested-by: Gluster Build System <>
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 0000000..c89caab
--- /dev/null
+++ b/tests/bugs/shard/bug-1258334.t
@@ -0,0 +1,41 @@
+. $(dirname $0)/../../include.rc
+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
diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c
index 6fb5716..8b784ec 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]) {