Re: [f2fs-dev] [PATCH] f2fs: account compressed writeback by raw folio type
Chao Yu via Linux-f2fs-devel <[email protected]> Mon, 3 Aug 2026 10:32:56 +0800
| Newsgroups | net.sourceforge.lists.linux-f2fs-devel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 6/16/26 20:52, Wenjie Qi wrote: > Compressed writeback is always charged as F2FS_WB_CP_DATA today because > WB_DATA_TYPE() is called with compressed_page set. That is wrong for > normal compressed file writeback; the CP guarantee belongs to the raw > pagecache folio, not the compressed bounce page. IIUC, I changed compressed writeback guaranteed by checkpoint to avoid compressed cluster corruption when encountering power off recovery after fsync/sync. I didn't get why it's wrong to set F2FS_WB_CP_DATA for compressed page, can you please explain more? Thanks, > > Use the raw folio for the writeback count type. Also keep one raw page > under writeback until the compressed end_io callback is done using sbi, > as normal compressed writeback is no longer protected by the CP-data > counter. > > Signed-off-by: Wenjie Qi <[email protected]> > --- > QEMU/KASAN tested with compress_mode=fs and compress_mode=user, using > concurrent 1MiB compressed writes and a background sync loop. The user > mode case also ran F2FS_IOC_COMPRESS_FILE and fsync. No dmesg splat was > reported and fsck.f2fs passed after unmount. > > fs/f2fs/compress.c | 34 +++++++++++++++++++++++++++------- > fs/f2fs/data.c | 2 +- > 2 files changed, 28 insertions(+), 8 deletions(-) > > diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c > index 91855d91bbdd..be9483b9a401 100644 > --- a/fs/f2fs/compress.c > +++ b/fs/f2fs/compress.c > @@ -1487,9 +1487,19 @@ void f2fs_compress_write_end_io(struct bio *bio, struct folio *folio) > struct page *page = &folio->page; > struct f2fs_sb_info *sbi = bio->bi_private; > struct compress_io_ctx *cic = folio->private; > - enum count_type type = WB_DATA_TYPE(folio, true); > + unsigned int offset = folio->index & (cic->nr_rpages - 1); > + struct page *last_page = NULL; > + enum count_type type; > int i; > > + if (unlikely(!offset || offset >= cic->nr_rpages || > + !cic->rpages[offset])) { > + f2fs_bug_on(sbi, 1); > + type = F2FS_WB_CP_DATA; > + } else { > + type = WB_DATA_TYPE(page_folio(cic->rpages[offset]), false); > + } > + > if (unlikely(bio->bi_status != BLK_STS_OK)) > mapping_set_error(cic->inode->i_mapping, -EIO); > > @@ -1501,21 +1511,31 @@ void f2fs_compress_write_end_io(struct bio *bio, struct folio *folio) > } > > for (i = 0; i < cic->nr_rpages; i++) { > - WARN_ON(!cic->rpages[i]); > + if (WARN_ON(!cic->rpages[i])) > + continue; > + last_page = cic->rpages[i]; > + } > + > + for (i = 0; i < cic->nr_rpages; i++) { > + if (!cic->rpages[i]) > + continue; > clear_page_private_gcing(cic->rpages[i]); > - end_page_writeback(cic->rpages[i]); > + > + if (cic->rpages[i] != last_page) > + end_page_writeback(cic->rpages[i]); > } > > page_array_free(sbi, cic->rpages, cic->nr_rpages); > kmem_cache_free(cic_entry_slab, cic); > > /* > - * Make sure dec_page_count() is the last access to sbi. > - * Once it drops the F2FS_WB_CP_DATA counter to zero, the > - * unmount thread can proceed to destroy sbi and > - * sbi->page_array_slab. > + * Keep all sbi accesses before the last raw page writeback is > + * released, so an unmount thread cannot free sbi while this callback > + * is still using it. > */ > dec_page_count(sbi, type); > + if (last_page) > + end_page_writeback(last_page); > } > > static int f2fs_write_raw_pages(struct compress_ctx *cc, > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c > index a765fda71536..1466a7825dc5 100644 > --- a/fs/f2fs/data.c > +++ b/fs/f2fs/data.c > @@ -1092,7 +1092,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) > /* set submitted = true as a return value */ > fio->submitted = 1; > > - type = WB_DATA_TYPE(bio_folio, fio->compressed_page); > + type = WB_DATA_TYPE(fio->compressed_page ? fio->folio : bio_folio, false); > inc_page_count(sbi, type); > > if (io->bio && > > base-commit: 7cc48ead1a8a96f2dd1eabd87c2f22947dc84cdf _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel