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: Jean Spector <jean@primarydata.com> Cc: <stable@vger.kernel.org> # v3.19+ Signed-off-by: Peng Tao <tao.peng@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
parent
ea96d1ecbe
commit
1ccbad9f9f
@ -131,20 +131,25 @@ 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);
|
||||||
|
|
||||||
count = dreq->mirrors[hdr->pgio_mirror_idx].count;
|
if (dreq->mirror_count == 1) {
|
||||||
if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) {
|
dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes;
|
||||||
count = hdr->io_start + hdr->good_bytes - dreq->io_start;
|
dreq->count += hdr->good_bytes;
|
||||||
dreq->mirrors[hdr->pgio_mirror_idx].count = count;
|
} 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);
|
||||||
|
|
||||||
|
dreq->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);
|
|
||||||
|
|
||||||
dreq->count = count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user