| From 1ccbad9f9f9bd36db26a10f0b17fbaf12b3ae93a Mon Sep 17 00:00:00 2001 |
| From: Peng Tao <tao.peng@primarydata.com> |
| Date: Thu, 9 Apr 2015 23:02:16 +0800 |
| Subject: nfs: fix DIO good bytes calculation |
| |
| From: Peng Tao <tao.peng@primarydata.com> |
| |
| commit 1ccbad9f9f9bd36db26a10f0b17fbaf12b3ae93a upstream. |
| |
| For direct read that has IO size larger than rsize, we'll split |
| it into several READ requests and nfs_direct_good_bytes() would |
| count completed bytes incorrectly by eating last zero count reply. |
| |
| Fix it by handling mirror and non-mirror cases differently such that |
| we only count mirrored writes differently. |
| |
| This fixes 5fadeb47("nfs: count DIO good bytes correctly with mirroring"). |
| |
| Reported-by: Jean Spector <jean@primarydata.com> |
| Signed-off-by: Peng Tao <tao.peng@primarydata.com> |
| Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/nfs/direct.c | 29 +++++++++++++++++------------ |
| 1 file changed, 17 insertions(+), 12 deletions(-) |
| |
| --- a/fs/nfs/direct.c |
| +++ b/fs/nfs/direct.c |
| @@ -131,20 +131,25 @@ nfs_direct_good_bytes(struct nfs_direct_ |
| |
| WARN_ON_ONCE(hdr->pgio_mirror_idx >= dreq->mirror_count); |
| |
| - count = dreq->mirrors[hdr->pgio_mirror_idx].count; |
| - if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) { |
| - count = hdr->io_start + hdr->good_bytes - dreq->io_start; |
| - dreq->mirrors[hdr->pgio_mirror_idx].count = count; |
| - } |
| - |
| - /* update the dreq->count by finding the minimum agreed count from all |
| - * mirrors */ |
| - count = dreq->mirrors[0].count; |
| + if (dreq->mirror_count == 1) { |
| + dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes; |
| + dreq->count += hdr->good_bytes; |
| + } else { |
| + /* mirrored writes */ |
| + count = dreq->mirrors[hdr->pgio_mirror_idx].count; |
| + if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) { |
| + count = hdr->io_start + hdr->good_bytes - dreq->io_start; |
| + dreq->mirrors[hdr->pgio_mirror_idx].count = count; |
| + } |
| + /* update the dreq->count by finding the minimum agreed count from all |
| + * mirrors */ |
| + count = dreq->mirrors[0].count; |
| |
| - for (i = 1; i < dreq->mirror_count; i++) |
| - count = min(count, dreq->mirrors[i].count); |
| + for (i = 1; i < dreq->mirror_count; i++) |
| + count = min(count, dreq->mirrors[i].count); |
| |
| - dreq->count = count; |
| + dreq->count = count; |
| + } |
| } |
| |
| /* |