]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
f2fs: Convert f2fs_write_begin() to use a folio
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 11 Jul 2024 20:58:06 +0000 (16:58 -0400)
committerChristian Brauner <brauner@kernel.org>
Wed, 7 Aug 2024 09:32:00 +0000 (11:32 +0200)
Fetch a folio from the page cache instead of a page and use it
throughout.  We still have to convert back to a page for calling
internal f2fs functions, but hopefully they will be converted soon.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/f2fs/data.c

index 58ac23e124a5890bb9fb459bb3113e70e70ea3f8..9a45f9fb8a6414ece52a8ecf7e46db44cc7d1170 100644 (file)
@@ -3556,8 +3556,8 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
 {
        struct inode *inode = mapping->host;
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-       struct page *page = NULL;
-       pgoff_t index = ((unsigned long long) pos) >> PAGE_SHIFT;
+       struct folio *folio;
+       pgoff_t index = pos >> PAGE_SHIFT;
        bool need_balance = false;
        bool use_cow = false;
        block_t blkaddr = NULL_ADDR;
@@ -3573,7 +3573,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
        /*
         * We should check this at this moment to avoid deadlock on inode page
         * and #0 page. The locking rule for inline_data conversion should be:
-        * lock_page(page #0) -> lock_page(inode_page)
+        * folio_lock(folio #0) -> folio_lock(inode_page)
         */
        if (index != 0) {
                err = f2fs_convert_inline_inode(inode);
@@ -3603,81 +3603,85 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
 
 repeat:
        /*
-        * Do not use grab_cache_page_write_begin() to avoid deadlock due to
-        * wait_for_stable_page. Will wait that below with our IO control.
+        * Do not use FGP_STABLE to avoid deadlock.
+        * Will wait that below with our IO control.
         */
-       page = f2fs_pagecache_get_page(mapping, index,
+       folio = __filemap_get_folio(mapping, index,
                                FGP_LOCK | FGP_WRITE | FGP_CREAT, GFP_NOFS);
-       if (!page) {
-               err = -ENOMEM;
+       if (IS_ERR(folio)) {
+               err = PTR_ERR(folio);
                goto fail;
        }
 
        /* TODO: cluster can be compressed due to race with .writepage */
 
-       *pagep = page;
+       *pagep = &folio->page;
 
        if (f2fs_is_atomic_file(inode))
-               err = prepare_atomic_write_begin(sbi, page, pos, len,
+               err = prepare_atomic_write_begin(sbi, &folio->page, pos, len,
                                        &blkaddr, &need_balance, &use_cow);
        else
-               err = prepare_write_begin(sbi, page, pos, len,
+               err = prepare_write_begin(sbi, &folio->page, pos, len,
                                        &blkaddr, &need_balance);
        if (err)
-               goto fail;
+               goto put_folio;
 
        if (need_balance && !IS_NOQUOTA(inode) &&
                        has_not_enough_free_secs(sbi, 0, 0)) {
-               unlock_page(page);
+               folio_unlock(folio);
                f2fs_balance_fs(sbi, true);
-               lock_page(page);
-               if (page->mapping != mapping) {
-                       /* The page got truncated from under us */
-                       f2fs_put_page(page, 1);
+               folio_lock(folio);
+               if (folio->mapping != mapping) {
+                       /* The folio got truncated from under us */
+                       folio_unlock(folio);
+                       folio_put(folio);
                        goto repeat;
                }
        }
 
-       f2fs_wait_on_page_writeback(page, DATA, false, true);
+       f2fs_wait_on_page_writeback(&folio->page, DATA, false, true);
 
-       if (len == PAGE_SIZE || PageUptodate(page))
+       if (len == folio_size(folio) || folio_test_uptodate(folio))
                return 0;
 
        if (!(pos & (PAGE_SIZE - 1)) && (pos + len) >= i_size_read(inode) &&
            !f2fs_verity_in_progress(inode)) {
-               zero_user_segment(page, len, PAGE_SIZE);
+               folio_zero_segment(folio, len, PAGE_SIZE);
                return 0;
        }
 
        if (blkaddr == NEW_ADDR) {
-               zero_user_segment(page, 0, PAGE_SIZE);
-               SetPageUptodate(page);
+               folio_zero_segment(folio, 0, folio_size(folio));
+               folio_mark_uptodate(folio);
        } else {
                if (!f2fs_is_valid_blkaddr(sbi, blkaddr,
                                DATA_GENERIC_ENHANCE_READ)) {
                        err = -EFSCORRUPTED;
-                       goto fail;
+                       goto put_folio;
                }
                err = f2fs_submit_page_read(use_cow ?
-                               F2FS_I(inode)->cow_inode : inode, page,
+                               F2FS_I(inode)->cow_inode : inode, &folio->page,
                                blkaddr, 0, true);
                if (err)
-                       goto fail;
+                       goto put_folio;
 
-               lock_page(page);
-               if (unlikely(page->mapping != mapping)) {
-                       f2fs_put_page(page, 1);
+               folio_lock(folio);
+               if (unlikely(folio->mapping != mapping)) {
+                       folio_unlock(folio);
+                       folio_put(folio);
                        goto repeat;
                }
-               if (unlikely(!PageUptodate(page))) {
+               if (unlikely(!folio_test_uptodate(folio))) {
                        err = -EIO;
-                       goto fail;
+                       goto put_folio;
                }
        }
        return 0;
 
+put_folio:
+       folio_unlock(folio);
+       folio_put(folio);
 fail:
-       f2fs_put_page(page, 1);
        f2fs_write_failed(inode, pos + len);
        return err;
 }