Previously, the GC (Garbage Collection) logic for performing I/O and
marking folios dirty only supported order-0 folios and lacked awareness
of higher-order folios. To enable GC to correctly handle higher-order
folios, we made two changes:

- In `move_data_page`, we now use `f2fs_iomap_set_range_dirty` to mark
  only the sub-part of the folio corresponding to `bidx` as dirty,
  instead of the entire folio.

- The `f2fs_submit_page_read` function has been augmented with an
  `index` parameter, allowing it to precisely identify which sub-page
  of the current folio is being submitted.

Signed-off-by: Nanzhe Zhao <nzz...@126.com>
---
 fs/f2fs/data.c | 13 +++++++------
 fs/f2fs/gc.c   | 37 +++++++++++++++++++++++--------------
 2 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index b7bef2a28c8e..5ecd08a3dd0b 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1096,7 +1096,7 @@ static struct bio *f2fs_grab_read_bio(struct inode 
*inode, block_t blkaddr,
 /* This can handle encryption stuffs */
 static int f2fs_submit_page_read(struct inode *inode, struct folio *folio,
                                 block_t blkaddr, blk_opf_t op_flags,
-                                bool for_write)
+                                pgoff_t index, bool for_write)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct bio *bio;
@@ -1109,7 +1109,8 @@ static int f2fs_submit_page_read(struct inode *inode, 
struct folio *folio,
        /* wait for GCed page writeback via META_MAPPING */
        f2fs_wait_on_block_writeback(inode, blkaddr);
 
-       if (!bio_add_folio(bio, folio, PAGE_SIZE, 0)) {
+       if (!bio_add_folio(bio, folio, PAGE_SIZE,
+                          (index - folio->index) << PAGE_SHIFT)) {
                iostat_update_and_unbind_ctx(bio);
                if (bio->bi_private)
                        mempool_free(bio->bi_private, bio_post_read_ctx_pool);
@@ -1276,8 +1277,8 @@ struct folio *f2fs_get_read_data_folio(struct inode 
*inode, pgoff_t index,
                return folio;
        }
 
-       err = f2fs_submit_page_read(inode, folio, dn.data_blkaddr,
-                                               op_flags, for_write);
+       err = f2fs_submit_page_read(inode, folio, dn.data_blkaddr, op_flags,
+                                   index, for_write);
        if (err)
                goto put_err;
        return folio;
@@ -3651,8 +3652,8 @@ static int f2fs_write_begin(const struct kiocb *iocb,
                        goto put_folio;
                }
                err = f2fs_submit_page_read(use_cow ?
-                               F2FS_I(inode)->cow_inode : inode,
-                               folio, blkaddr, 0, true);
+                       F2FS_I(inode)->cow_inode : inode, folio,
+                       blkaddr, 0, folio->index, true);
                if (err)
                        goto put_folio;
 
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 098e9f71421e..6d28f01bec42 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1475,22 +1475,31 @@ static int move_data_page(struct inode *inode, block_t 
bidx, int gc_type,
                        err = -EAGAIN;
                        goto out;
                }
-               folio_mark_dirty(folio);
                folio_set_f2fs_gcing(folio);
+#ifdef CONFIG_F2FS_IOMAP_FOLIO_STATE
+               if (!folio_test_large(folio)) {
+                       folio_mark_dirty(folio);
+               } else {
+                       f2fs_iomap_set_range_dirty(folio, (bidx - folio->index) 
<< PAGE_SHIFT,
+                               PAGE_SIZE);
+               }
+#else
+               folio_mark_dirty(folio);
+#endif
        } else {
-               struct f2fs_io_info fio = {
-                       .sbi = F2FS_I_SB(inode),
-                       .ino = inode->i_ino,
-                       .type = DATA,
-                       .temp = COLD,
-                       .op = REQ_OP_WRITE,
-                       .op_flags = REQ_SYNC,
-                       .old_blkaddr = NULL_ADDR,
-                       .folio = folio,
-                       .encrypted_page = NULL,
-                       .need_lock = LOCK_REQ,
-                       .io_type = FS_GC_DATA_IO,
-               };
+               struct f2fs_io_info fio = { .sbi = F2FS_I_SB(inode),
+                                           .ino = inode->i_ino,
+                                           .type = DATA,
+                                           .temp = COLD,
+                                           .op = REQ_OP_WRITE,
+                                           .op_flags = REQ_SYNC,
+                                           .old_blkaddr = NULL_ADDR,
+                                           .folio = folio,
+                                           .encrypted_page = NULL,
+                                           .need_lock = LOCK_REQ,
+                                           .io_type = FS_GC_DATA_IO,
+                                           .idx = bidx - folio->index,
+                                           .cnt = 1 };
                bool is_dirty = folio_test_dirty(folio);
 
 retry:
-- 
2.34.1



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to