summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/bugs/shard/bug-1259651.t41
-rw-r--r--xlators/features/shard/src/shard.c10
2 files changed, 49 insertions, 2 deletions
diff --git a/tests/bugs/shard/bug-1259651.t b/tests/bugs/shard/bug-1259651.t
new file mode 100644
index 00000000000..a1742dea7dd
--- /dev/null
+++ b/tests/bugs/shard/bug-1259651.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 start $V0
+
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0
+
+TEST mkdir $M0/dir
+TEST touch $M0/dir/file_plain
+
+# Create "file_plain" with holes.
+TEST truncate -s 12M $M0/dir/file_plain
+
+# Perform writes on it that would create holes.
+TEST dd if=/dev/zero of=$M0/dir/file_plain bs=1024 seek=10240 count=1024 conv=notrunc
+
+md5sum_file_plain=$(md5sum $M0/dir/file_plain | awk '{print $1}')
+
+# Now enable sharding on the volume.
+TEST $CLI volume set $V0 features.shard on
+TEST $CLI volume set $V0 performance.strict-write-ordering on
+
+# Create a sharded file called "file_sharded"
+TEST touch $M0/dir/file_sharded
+
+# Truncate it to make it sparse
+TEST truncate -s 12M $M0/dir/file_sharded
+
+# Perform writes on it that would create holes in block-0 and block-1.
+TEST dd if=/dev/zero of=$M0/dir/file_sharded bs=1024 seek=10240 count=1024 conv=notrunc
+
+# If this bug is fixed, md5sum of file_sharded and file_plain should be same.
+EXPECT "$md5sum_file_plain" echo `md5sum $M0/dir/file_sharded | awk '{print $1}'`
+
+cleanup
diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c
index 8b784eca1a8..74d75758f59 100644
--- a/xlators/features/shard/src/shard.c
+++ b/xlators/features/shard/src/shard.c
@@ -2362,6 +2362,12 @@ shard_readv_do_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
+ /* If shard has already seen a failure here before, there is no point
+ * in aggregating subsequent reads, so just go to out.
+ */
+ if (local->op_ret < 0)
+ goto out;
+
if (op_ret < 0) {
local->op_ret = op_ret;
local->op_errno = op_errno;
@@ -2408,8 +2414,8 @@ out:
if (xdata)
local->xattr_rsp = dict_ref (xdata);
vec.iov_base = local->iobuf->ptr;
- vec.iov_len = local->op_ret;
- SHARD_STACK_UNWIND (readv, frame, local->op_ret,
+ vec.iov_len = local->total_size;
+ SHARD_STACK_UNWIND (readv, frame, local->total_size,
local->op_errno, &vec, 1,
&local->prebuf, local->iobref,
local->xattr_rsp);