Commit 1ccbad9f authored by Peng Tao's avatar Peng Tao Committed by Trond Myklebust

nfs: fix DIO good bytes calculation

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: default avatarJean Spector <jean@primarydata.com>
Cc: <stable@vger.kernel.org> # v3.19+
Signed-off-by: default avatarPeng Tao <tao.peng@primarydata.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent ea96d1ec
...@@ -131,12 +131,16 @@ nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr) ...@@ -131,12 +131,16 @@ nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr)
WARN_ON_ONCE(hdr->pgio_mirror_idx >= dreq->mirror_count); WARN_ON_ONCE(hdr->pgio_mirror_idx >= dreq->mirror_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; count = dreq->mirrors[hdr->pgio_mirror_idx].count;
if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) { if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) {
count = hdr->io_start + hdr->good_bytes - dreq->io_start; count = hdr->io_start + hdr->good_bytes - dreq->io_start;
dreq->mirrors[hdr->pgio_mirror_idx].count = count; dreq->mirrors[hdr->pgio_mirror_idx].count = count;
} }
/* update the dreq->count by finding the minimum agreed count from all /* update the dreq->count by finding the minimum agreed count from all
* mirrors */ * mirrors */
count = dreq->mirrors[0].count; count = dreq->mirrors[0].count;
...@@ -145,6 +149,7 @@ nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr) ...@@ -145,6 +149,7 @@ nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr)
count = min(count, dreq->mirrors[i].count); count = min(count, dreq->mirrors[i].count);
dreq->count = count; dreq->count = count;
}
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment