Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Peng Tao and committed by
Trond Myklebust
1ccbad9f ea96d1ec

+18 -13
+18 -13
fs/nfs/direct.c
··· 131 131 132 132 WARN_ON_ONCE(hdr->pgio_mirror_idx >= dreq->mirror_count); 133 133 134 - count = dreq->mirrors[hdr->pgio_mirror_idx].count; 135 - if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) { 136 - count = hdr->io_start + hdr->good_bytes - dreq->io_start; 137 - dreq->mirrors[hdr->pgio_mirror_idx].count = count; 134 + if (dreq->mirror_count == 1) { 135 + dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes; 136 + dreq->count += hdr->good_bytes; 137 + } else { 138 + /* mirrored writes */ 139 + count = dreq->mirrors[hdr->pgio_mirror_idx].count; 140 + if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) { 141 + count = hdr->io_start + hdr->good_bytes - dreq->io_start; 142 + dreq->mirrors[hdr->pgio_mirror_idx].count = count; 143 + } 144 + /* update the dreq->count by finding the minimum agreed count from all 145 + * mirrors */ 146 + count = dreq->mirrors[0].count; 147 + 148 + for (i = 1; i < dreq->mirror_count; i++) 149 + count = min(count, dreq->mirrors[i].count); 150 + 151 + dreq->count = count; 138 152 } 139 - 140 - /* update the dreq->count by finding the minimum agreed count from all 141 - * mirrors */ 142 - count = dreq->mirrors[0].count; 143 - 144 - for (i = 1; i < dreq->mirror_count; i++) 145 - count = min(count, dreq->mirrors[i].count); 146 - 147 - dreq->count = count; 148 153 } 149 154 150 155 /*