[PATCH v2 07/15] ubifs: Convert write_begin_slow() to use a folio
Zhihao Cheng
chengzhihao1 at huawei.com
Wed Jan 24 17:46:37 PST 2024
在 2024/1/25 1:52, Matthew Wilcox (Oracle) 写道:
> Update to new APIs, removing several calls to compound_head() and
> including support for large folios.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy at infradead.org>
> ---
> fs/ubifs/file.c | 45 +++++++++++++++++++++++----------------------
> 1 file changed, 23 insertions(+), 22 deletions(-)
>
Reviewed-by: Zhihao Cheng <chengzhihao1 at huawei.com>
> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
> index 3c4a98476c23..cc4d2ec95b70 100644
> --- a/fs/ubifs/file.c
> +++ b/fs/ubifs/file.c
> @@ -222,16 +222,16 @@ static int write_begin_slow(struct address_space *mapping,
> pgoff_t index = pos >> PAGE_SHIFT;
> struct ubifs_budget_req req = { .new_page = 1 };
> int err, appending = !!(pos + len > inode->i_size);
> - struct page *page;
> + struct folio *folio;
>
> dbg_gen("ino %lu, pos %llu, len %u, i_size %lld",
> inode->i_ino, pos, len, inode->i_size);
>
> /*
> - * At the slow path we have to budget before locking the page, because
> - * budgeting may force write-back, which would wait on locked pages and
> - * deadlock if we had the page locked. At this point we do not know
> - * anything about the page, so assume that this is a new page which is
> + * At the slow path we have to budget before locking the folio, because
> + * budgeting may force write-back, which would wait on locked folios and
> + * deadlock if we had the folio locked. At this point we do not know
> + * anything about the folio, so assume that this is a new folio which is
> * written to a hole. This corresponds to largest budget. Later the
> * budget will be amended if this is not true.
> */
> @@ -243,42 +243,43 @@ static int write_begin_slow(struct address_space *mapping,
> if (unlikely(err))
> return err;
>
> - page = grab_cache_page_write_begin(mapping, index);
> - if (unlikely(!page)) {
> + folio = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN,
> + mapping_gfp_mask(mapping));
> + if (IS_ERR(folio)) {
> ubifs_release_budget(c, &req);
> - return -ENOMEM;
> + return PTR_ERR(folio);
> }
>
> - if (!PageUptodate(page)) {
> - if (!(pos & ~PAGE_MASK) && len == PAGE_SIZE)
> - SetPageChecked(page);
> + if (!folio_test_uptodate(folio)) {
> + if (pos == folio_pos(folio) && len >= folio_size(folio))
> + folio_set_checked(folio);
> else {
> - err = do_readpage(page);
> + err = do_readpage(&folio->page);
> if (err) {
> - unlock_page(page);
> - put_page(page);
> + folio_unlock(folio);
> + folio_put(folio);
> ubifs_release_budget(c, &req);
> return err;
> }
> }
> }
>
> - if (PagePrivate(page))
> + if (folio->private)
> /*
> - * The page is dirty, which means it was budgeted twice:
> + * The folio is dirty, which means it was budgeted twice:
> * o first time the budget was allocated by the task which
> - * made the page dirty and set the PG_private flag;
> + * made the folio dirty and set the private field;
> * o and then we budgeted for it for the second time at the
> * very beginning of this function.
> *
> - * So what we have to do is to release the page budget we
> + * So what we have to do is to release the folio budget we
> * allocated.
> */
> release_new_page_budget(c);
> - else if (!PageChecked(page))
> + else if (!folio_test_checked(folio))
> /*
> - * We are changing a page which already exists on the media.
> - * This means that changing the page does not make the amount
> + * We are changing a folio which already exists on the media.
> + * This means that changing the folio does not make the amount
> * of indexing information larger, and this part of the budget
> * which we have already acquired may be released.
> */
> @@ -301,7 +302,7 @@ static int write_begin_slow(struct address_space *mapping,
> ubifs_release_dirty_inode_budget(c, ui);
> }
>
> - *pagep = page;
> + *pagep = &folio->page;
> return 0;
> }
>
>
More information about the linux-mtd
mailing list