diff options
author | shishir gowda <shishirng@gluster.com> | 2011-11-03 14:47:01 +0530 |
---|---|---|
committer | Vijay Bellur <vijay@gluster.com> | 2011-11-08 22:12:09 -0800 |
commit | fc9fbbc35efaa84e68e108895ad64b062feed280 (patch) | |
tree | 8020b68edb20d4df12920ca5f08e9298e296626f | |
parent | 3200a2be434c462b43bf3ffe0343ddc8900c5d88 (diff) |
stripe readv_cbk: Fix stat return values
Workaround -
If the read request, does not fall to the subvolume with the largest
file size set, then we never return the correct size. This leads to
clients seeing a truncated file error.
The work around is to wipe stat being returned as part of read call.
Problem -
We were passing the stbuf returned by the first child/index, which
can be different to the size/blocks returned by stat. This led to
applications viewing the file as being truncated.
The stbuf size needs to be the largest of all results, and blocks
the aggregation from all subvolumes. (similar to stat)
BUG: 3774
Change-Id: I46c53c18b2b42b1f5b86b05555bbab73bf993476
Reviewed-on: http://review.gluster.com/666
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Amar Tumballi <amar@gluster.com>
-rw-r--r-- | libglusterfs/src/common-utils.h | 2 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 1 | ||||
-rw-r--r-- | xlators/cluster/stripe/src/stripe.c | 7 |
3 files changed, 9 insertions, 1 deletions
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 6c83a100427..d17573e2da6 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -72,6 +72,8 @@ void trap (void); #define GEOREP "geo-replication" #define GHADOOP "glusterfs-hadoop" +#define WIPE(statp) do { typeof(*statp) z = {0,}; if (statp) *statp = z; } while (0) + enum _gf_boolean { _gf_false = 0, diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 5d921239ef4..d79ed955697 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -219,7 +219,6 @@ struct dht_disk_layout { }; typedef struct dht_disk_layout dht_disk_layout_t; -#define WIPE(statp) do { typeof(*statp) z = {0,}; if (statp) *statp = z; } while (0) #define ENTRY_MISSING(op_ret, op_errno) (op_ret == -1 && op_errno == ENOENT) diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index bef1eb7495d..1bea7a73382 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -3556,6 +3556,9 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, mlocal->replies[index].stbuf = *stbuf; mlocal->replies[index].count = count; mlocal->replies[index].vector = iov_dup (vector, count); + if (local->stbuf_size < stbuf->ia_size) + local->stbuf_size = stbuf->ia_size; + local->stbuf_blocks += stbuf->ia_blocks; if (!mlocal->iobref) mlocal->iobref = iobref_new (); @@ -3613,11 +3616,15 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, * cause any bugs at higher levels */ memcpy (&tmp_stbuf, &mlocal->replies[0].stbuf, sizeof (struct iatt)); + tmp_stbuf.ia_size = local->stbuf_size; + tmp_stbuf.ia_blocks = local->stbuf_blocks; done: /* */ GF_FREE (mlocal->replies); tmp_iobref = mlocal->iobref; + /* work around for nfs truncated read. Bug 3774 */ + WIPE (&tmp_stbuf); STRIPE_STACK_UNWIND (readv, mframe, op_ret, op_errno, final_vec, final_count, &tmp_stbuf, tmp_iobref); |