[PATCH] erofs: mark fileio folios uptodate based on the number of bytes read
Sheng Yong
shengyong2021 at gmail.com
Thu Feb 26 20:09:46 AEDT 2026
From: Sheng Yong <shengyong1 at xiaomi.com>
For file-backed mount, IO requests are handled by vfs_iocb_iter_read().
However, it can be interrupted by SIGKILL, returning the number of
bytes actually copied. Although unused folios are zero filled, they
are unexpectedly marked as uptodate.
This patch addresses this by setting folios uptodate based on the actual
number of bytes read for the plain backing file. And for the compressed
backing file, there may not have sufficient data for decompression,
in such case, the bio is marked with an error directly.
Fixes: ce63cb62d794 ("erofs: support unencoded inodes for fileio")
Reported-by: chenguanyou <chenguanyou at xiaomi.com>
Signed-off-by: Yunlei He <heyunlei at xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1 at xiaomi.com>
---
fs/erofs/fileio.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/erofs/fileio.c b/fs/erofs/fileio.c
index abe873f01297..172444ae4ede 100644
--- a/fs/erofs/fileio.c
+++ b/fs/erofs/fileio.c
@@ -24,18 +24,30 @@ static void erofs_fileio_ki_complete(struct kiocb *iocb, long ret)
struct erofs_fileio_rq *rq =
container_of(iocb, struct erofs_fileio_rq, iocb);
struct folio_iter fi;
+ bool bio_advanced = false;
if (ret >= 0 && ret != rq->bio.bi_iter.bi_size) {
bio_advance(&rq->bio, ret);
zero_fill_bio(&rq->bio);
+ bio_advanced = true;
}
if (!rq->bio.bi_end_io) {
bio_for_each_folio_all(fi, &rq->bio) {
DBG_BUGON(folio_test_uptodate(fi.folio));
- erofs_onlinefolio_end(fi.folio, ret < 0, false);
+ if (likely(!bio_advanced ||
+ ret >= (long)folio_size(fi.folio))) {
+ erofs_onlinefolio_end(fi.folio, 0, false);
+ ret -= folio_size(fi.folio);
+ } else {
+ erofs_onlinefolio_end(fi.folio, -EIO, false);
+ }
}
} else if (ret < 0 && !rq->bio.bi_status) {
rq->bio.bi_status = errno_to_blk_status(ret);
+ } else if (bio_advanced &&
+ ret + iocb->ki_pos < i_size_read(file_inode(iocb->ki_filp))) {
+ /* may not have sufficient data for decompression */
+ rq->bio.bi_status = -EIO;
}
bio_endio(&rq->bio);
bio_uninit(&rq->bio);
--
2.43.0
More information about the Linux-erofs
mailing list