From fc9fbbc35efaa84e68e108895ad64b062feed280 Mon Sep 17 00:00:00 2001 From: shishir gowda Date: Thu, 3 Nov 2011 14:47:01 +0530 Subject: 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 Reviewed-by: Amar Tumballi --- xlators/cluster/dht/src/dht-common.h | 1 - xlators/cluster/stripe/src/stripe.c | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'xlators') diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 5d921239e..d79ed9556 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 bef1eb749..1bea7a733 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); -- cgit