Since f2fs_io_info (hereafter fio) has been converted to use fio->folio
and fio->page is deprecated, we must now track which sub-part of a
folio is being submitted to a bio in order to support large folios.

To achieve this, we add `idx` and `cnt` fields to the fio struct.
`fio->idx` represents the offset (in pages) within the current folio
for this I/O operation, and `fio->cnt` represents the number of
contiguous blocks being processed.

With the introduction of these two fields, the existing `old_blkaddr`
and `new_blkaddr` fields in fio are reinterpreted. They now represent
the starting old and new block addresses corresponding to `fio->idx`.
Consequently, an fio no longer represents a single mapping from one
old_blkaddr to one new_blkaddr, but rather a range mapping from
[old_blkaddr, old_blkaddr + fio->cnt - 1] to
[new_blkaddr, new_blkaddr + fio->cnt - 1].

In bio submission paths, for cases where `fio->cnt` is not explicitly
initialized, we default it to 1 and `fio->idx` to 0. This ensures
backward compatibility with all existing f2fs logic that operates on
single pages.

Discussion: Now I don't know if it's better to store bytes-unit
logical file offset and LBA length instead of block-unit cnt and
page idx in fio if we are to support BLOCK_SIZE > PAGE_SIZE.
Suggestions are appreciated.

Signed-off-by: Nanzhe Zhao <nzz...@126.com>
---
 fs/f2fs/data.c | 16 ++++++++++------
 fs/f2fs/f2fs.h |  2 ++
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index a9dc2572bdc4..b7bef2a28c8e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -711,7 +711,9 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
 
        f2fs_set_bio_crypt_ctx(bio, fio_folio->mapping->host,
                        fio_folio->index, fio, GFP_NOIO);
-       bio_add_folio_nofail(bio, data_folio, folio_size(data_folio), 0);
+       bio_add_folio_nofail(bio, data_folio,
+                            F2FS_BLK_TO_BYTES(fio->cnt ? fio->cnt : 1),
+                            fio->idx << PAGE_SHIFT);
 
        if (fio->io_wbc && !is_read_io(fio->op))
                wbc_account_cgroup_owner(fio->io_wbc, fio_folio, PAGE_SIZE);
@@ -1010,16 +1012,18 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
                io->fio = *fio;
        }
 
-       if (!bio_add_folio(io->bio, bio_folio, folio_size(bio_folio), 0)) {
+       if (!bio_add_folio(io->bio, bio_folio,
+                          F2FS_BLK_TO_BYTES(fio->cnt ? fio->cnt : 1),
+                          fio->idx << PAGE_SHIFT)) {
                __submit_merged_bio(io);
                goto alloc_new;
        }
 
        if (fio->io_wbc)
                wbc_account_cgroup_owner(fio->io_wbc, fio->folio,
-                               folio_size(fio->folio));
+                                        F2FS_BLK_TO_BYTES(fio->cnt));
 
-       io->last_block_in_bio = fio->new_blkaddr;
+       io->last_block_in_bio = fio->new_blkaddr + fio->cnt - 1;
 
        trace_f2fs_submit_folio_write(fio->folio, fio);
 #ifdef CONFIG_BLK_DEV_ZONED
@@ -2675,7 +2679,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
                set_new_dnode(&dn, inode, NULL, NULL, 0);
 
        if (need_inplace_update(fio) &&
-           f2fs_lookup_read_extent_cache_block(inode, folio->index,
+           f2fs_lookup_read_extent_cache_block(inode, folio->index + fio->idx,
                                                &fio->old_blkaddr)) {
                if (!f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr,
                                                DATA_GENERIC_ENHANCE))
@@ -2690,7 +2694,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
        if (fio->need_lock == LOCK_REQ && !f2fs_trylock_op(fio->sbi))
                return -EAGAIN;
 
-       err = f2fs_get_dnode_of_data(&dn, folio->index, LOOKUP_NODE);
+       err = f2fs_get_dnode_of_data(&dn, folio->index + fio->idx, LOOKUP_NODE);
        if (err)
                goto out;
 
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 9f88be53174b..c6b23fa63588 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1281,6 +1281,8 @@ struct f2fs_io_info {
        blk_opf_t op_flags;     /* req_flag_bits */
        block_t new_blkaddr;    /* new block address to be written */
        block_t old_blkaddr;    /* old block address before Cow */
+       pgoff_t idx; /*start page index within current active folio in this 
fio*/
+       unsigned int cnt; /*block cnts of the active folio, we assume they are 
continuous.*/
        union {
                struct page *page;      /* page to be written */
                struct folio *folio;
-- 
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