mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
virtio_fs: zero the correct range on a short read reply
virtio_fs_request_complete() zeroes the unfilled tail of a short reply at [len, thislen) within the folio. That is only correct when the read started at the beginning of the folio, which is what the WARN_ON(descs[i].offset) above it documents. The assumption holds on every configuration that exists today. A fuse read covers a sub-range of a folio only when iomap trims it to the blocks of a folio that are not uptodate, which requires the file system block size to be smaller than the folio. virtio-fs is not block backed, so its block size is PAGE_SIZE, an order-0 folio is a single block, and descs[i].offset is always 0. Large folios make i_blocks_per_folio() greater than one and the assumption false. iomap_adjust_read_range() skips the blocks that are already uptodate at the front of the range and hands the position of the first block that has to be read to ->read_folio_range(), both when __iomap_write_begin() fills the blocks around an unaligned write and when a folio that is only partially uptodate is read - in which case one folio can take several reads at different offsets. fuse turns that position into offset_in_folio(folio, iter->pos) and stores it in the descriptor, so the tail that needs zeroing is [offset + len, offset + thislen). Zero that range and drop the WARN_ON(). This is a no-op today and a prerequisite for enabling large folios. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
f7585e1ce3
commit
ad866d756d
|
|
@ -798,9 +798,11 @@ static void virtio_fs_request_complete(struct fuse_req *req,
|
|||
for (i = 0; i < ap->num_folios; i++) {
|
||||
thislen = ap->descs[i].length;
|
||||
if (len < thislen) {
|
||||
WARN_ON(ap->descs[i].offset);
|
||||
unsigned int offset = ap->descs[i].offset;
|
||||
|
||||
folio = ap->folios[i];
|
||||
folio_zero_segment(folio, len, thislen);
|
||||
folio_zero_segment(folio, offset + len,
|
||||
offset + thislen);
|
||||
len = 0;
|
||||
} else {
|
||||
len -= thislen;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user