diff mbox series

[v2,07/15] ubifs: Convert write_begin_slow() to use a folio

Message ID 20240124175302.1750912-8-willy@infradead.org
State Accepted
Headers show
Series ubifs folio conversion | expand

Commit Message

Matthew Wilcox Jan. 24, 2024, 5:52 p.m. UTC
Update to new APIs, removing several calls to compound_head() and
including support for large folios.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 fs/ubifs/file.c | 45 +++++++++++++++++++++++----------------------
 1 file changed, 23 insertions(+), 22 deletions(-)

Comments

Zhihao Cheng Jan. 25, 2024, 1:46 a.m. UTC | #1
在 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@infradead.org>
> ---
>   fs/ubifs/file.c | 45 +++++++++++++++++++++++----------------------
>   1 file changed, 23 insertions(+), 22 deletions(-)
> 

Reviewed-by: Zhihao Cheng <chengzhihao1@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;
>   }
>   
>
diff mbox series

Patch

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;
 }