* [PATCH 01/26] buffer: Make folio_create_empty_buffers() return a buffer_head
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
[not found] ` <CGME20230920093952eucas1p1f37c688dc553d6a85882cae29861a870@eucas1p1.samsung.com>
2023-09-19 4:51 ` [PATCH 02/26] mpage: Convert map_buffer_to_folio() to folio_create_empty_buffers() Matthew Wilcox (Oracle)
` (15 subsequent siblings)
16 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Almost all callers want to know the first BH that was allocated
for this folio. We already have that handy, so return it.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/buffer.c | 24 +++++++++++++-----------
include/linux/buffer_head.h | 4 ++--
2 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/fs/buffer.c b/fs/buffer.c
index ad2526dd7cb4..1b9e691714bd 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1646,8 +1646,8 @@ EXPORT_SYMBOL(block_invalidate_folio);
* block_dirty_folio() via private_lock. try_to_free_buffers
* is already excluded via the folio lock.
*/
-void folio_create_empty_buffers(struct folio *folio, unsigned long blocksize,
- unsigned long b_state)
+struct buffer_head *folio_create_empty_buffers(struct folio *folio,
+ unsigned long blocksize, unsigned long b_state)
{
struct buffer_head *bh, *head, *tail;
gfp_t gfp = GFP_NOFS | __GFP_ACCOUNT | __GFP_NOFAIL;
@@ -1674,6 +1674,8 @@ void folio_create_empty_buffers(struct folio *folio, unsigned long blocksize,
}
folio_attach_private(folio, head);
spin_unlock(&folio->mapping->private_lock);
+
+ return head;
}
EXPORT_SYMBOL(folio_create_empty_buffers);
@@ -1775,13 +1777,15 @@ static struct buffer_head *folio_create_buffers(struct folio *folio,
struct inode *inode,
unsigned int b_state)
{
+ struct buffer_head *bh;
+
BUG_ON(!folio_test_locked(folio));
- if (!folio_buffers(folio))
- folio_create_empty_buffers(folio,
- 1 << READ_ONCE(inode->i_blkbits),
- b_state);
- return folio_buffers(folio);
+ bh = folio_buffers(folio);
+ if (!bh)
+ bh = folio_create_empty_buffers(folio,
+ 1 << READ_ONCE(inode->i_blkbits), b_state);
+ return bh;
}
/*
@@ -2671,10 +2675,8 @@ int block_truncate_page(struct address_space *mapping,
return PTR_ERR(folio);
bh = folio_buffers(folio);
- if (!bh) {
- folio_create_empty_buffers(folio, blocksize, 0);
- bh = folio_buffers(folio);
- }
+ if (!bh)
+ bh = folio_create_empty_buffers(folio, blocksize, 0);
/* Find the buffer that contains "offset" */
offset = offset_in_folio(folio, from);
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 3dc4720e4773..1001244a8941 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -203,8 +203,8 @@ struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size,
bool retry);
void create_empty_buffers(struct page *, unsigned long,
unsigned long b_state);
-void folio_create_empty_buffers(struct folio *folio, unsigned long blocksize,
- unsigned long b_state);
+struct buffer_head *folio_create_empty_buffers(struct folio *folio,
+ unsigned long blocksize, unsigned long b_state);
void end_buffer_read_sync(struct buffer_head *bh, int uptodate);
void end_buffer_write_sync(struct buffer_head *bh, int uptodate);
void end_buffer_async_write(struct buffer_head *bh, int uptodate);
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 02/26] mpage: Convert map_buffer_to_folio() to folio_create_empty_buffers()
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 01/26] buffer: Make folio_create_empty_buffers() return a buffer_head Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
[not found] ` <CGME20230920095447eucas1p2fee0541ad835331ff6b4c5143122c341@eucas1p2.samsung.com>
2023-09-19 4:51 ` [PATCH 03/26] ext4: Convert to folio_create_empty_buffers Matthew Wilcox (Oracle)
` (14 subsequent siblings)
16 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Saves a folio->page->folio conversion.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/mpage.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/mpage.c b/fs/mpage.c
index 242e213ee064..964a6efe594d 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -119,8 +119,7 @@ static void map_buffer_to_folio(struct folio *folio, struct buffer_head *bh,
folio_mark_uptodate(folio);
return;
}
- create_empty_buffers(&folio->page, i_blocksize(inode), 0);
- head = folio_buffers(folio);
+ head = folio_create_empty_buffers(folio, i_blocksize(inode), 0);
}
page_bh = head;
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 03/26] ext4: Convert to folio_create_empty_buffers
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 01/26] buffer: Make folio_create_empty_buffers() return a buffer_head Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 02/26] mpage: Convert map_buffer_to_folio() to folio_create_empty_buffers() Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
[not found] ` <CGME20230920100012eucas1p1f44530cfdd1ff8ed668bfe0c088d31ce@eucas1p1.samsung.com>
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
` (13 subsequent siblings)
16 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Remove an unnecessary folio->page->folio conversion and take advantage
of the new return value from folio_create_empty_buffers().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ext4/inode.c | 14 +++++---------
fs/ext4/move_extent.c | 11 +++++------
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 4ce35f1c8b0a..8e431ff2fd95 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1020,10 +1020,8 @@ static int ext4_block_write_begin(struct folio *folio, loff_t pos, unsigned len,
BUG_ON(from > to);
head = folio_buffers(folio);
- if (!head) {
- create_empty_buffers(&folio->page, blocksize, 0);
- head = folio_buffers(folio);
- }
+ if (!head)
+ head = folio_create_empty_buffers(folio, blocksize, 0);
bbits = ilog2(blocksize);
block = (sector_t)folio->index << (PAGE_SHIFT - bbits);
@@ -1153,7 +1151,7 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
* starting the handle.
*/
if (!folio_buffers(folio))
- create_empty_buffers(&folio->page, inode->i_sb->s_blocksize, 0);
+ folio_create_empty_buffers(folio, inode->i_sb->s_blocksize, 0);
folio_unlock(folio);
@@ -3643,10 +3641,8 @@ static int __ext4_block_zero_page_range(handle_t *handle,
iblock = index << (PAGE_SHIFT - inode->i_sb->s_blocksize_bits);
bh = folio_buffers(folio);
- if (!bh) {
- create_empty_buffers(&folio->page, blocksize, 0);
- bh = folio_buffers(folio);
- }
+ if (!bh)
+ bh = folio_create_empty_buffers(folio, blocksize, 0);
/* Find the buffer that contains "offset" */
pos = blocksize;
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 18a9e7c47975..7fe448fb948b 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -183,10 +183,8 @@ mext_page_mkuptodate(struct folio *folio, unsigned from, unsigned to)
blocksize = i_blocksize(inode);
head = folio_buffers(folio);
- if (!head) {
- create_empty_buffers(&folio->page, blocksize, 0);
- head = folio_buffers(folio);
- }
+ if (!head)
+ head = folio_create_empty_buffers(folio, blocksize, 0);
block = (sector_t)folio->index << (PAGE_SHIFT - inode->i_blkbits);
for (bh = head, block_start = 0; bh != head || !block_start;
@@ -380,9 +378,10 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
}
/* Perform all necessary steps similar write_begin()/write_end()
* but keeping in mind that i_size will not change */
- if (!folio_buffers(folio[0]))
- create_empty_buffers(&folio[0]->page, 1 << orig_inode->i_blkbits, 0);
bh = folio_buffers(folio[0]);
+ if (!bh)
+ bh = folio_create_empty_buffers(folio[0],
+ 1 << orig_inode->i_blkbits, 0);
for (i = 0; i < data_offset_in_page; i++)
bh = bh->b_this_page;
for (i = 0; i < block_len_in_page; i++) {
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread[parent not found: <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>]
* [PATCH 04/26] buffer: Add get_nth_bh()
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
[not found] ` <20230919045135.3635437-5-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2023-09-19 4:51 ` [PATCH 05/26] gfs2: Convert inode unstuffing to use a folio Matthew Wilcox (Oracle)
` (8 subsequent siblings)
9 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
gfs2-cunTk1MwBs/YUNznpcFYbw, linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
Extract this useful helper from nilfs_page_get_nth_block()
Signed-off-by: Matthew Wilcox (Oracle) <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
---
fs/nilfs2/page.h | 7 +------
include/linux/buffer_head.h | 22 ++++++++++++++++++++++
2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
index 21ddcdd4d63e..344d71942d36 100644
--- a/fs/nilfs2/page.h
+++ b/fs/nilfs2/page.h
@@ -55,12 +55,7 @@ unsigned long nilfs_find_uncommitted_extent(struct inode *inode,
static inline struct buffer_head *
nilfs_page_get_nth_block(struct page *page, unsigned int count)
{
- struct buffer_head *bh = page_buffers(page);
-
- while (count-- > 0)
- bh = bh->b_this_page;
- get_bh(bh);
- return bh;
+ return get_nth_bh(page_buffers(page), count);
}
#endif /* _NILFS_PAGE_H */
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 1001244a8941..9fc615ee17fd 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -457,6 +457,28 @@ __bread(struct block_device *bdev, sector_t block, unsigned size)
return __bread_gfp(bdev, block, size, __GFP_MOVABLE);
}
+/**
+ * get_nth_bh - Get a reference on the n'th buffer after this one.
+ * @bh: The buffer to start counting from.
+ * @count: How many buffers to skip.
+ *
+ * This is primarily useful for finding the nth buffer in a folio; in
+ * that case you pass the head buffer and the byte offset in the folio
+ * divided by the block size. It can be used for other purposes, but
+ * it will wrap at the end of the folio rather than returning NULL or
+ * proceeding to the next folio for you.
+ *
+ * Return: The requested buffer with an elevated refcount.
+ */
+static inline struct buffer_head *get_nth_bh(struct buffer_head *bh,
+ unsigned int count)
+{
+ while (count--)
+ bh = bh->b_this_page;
+ get_bh(bh);
+ return bh;
+}
+
bool block_dirty_folio(struct address_space *mapping, struct folio *folio);
#ifdef CONFIG_BUFFER_HEAD
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 05/26] gfs2: Convert inode unstuffing to use a folio
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2023-09-19 4:51 ` [PATCH 04/26] buffer: Add get_nth_bh() Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 22:28 ` Andreas Gruenbacher
2023-09-19 4:51 ` [PATCH 06/26] gfs2: Convert gfs2_getbuf() to folios Matthew Wilcox (Oracle)
` (7 subsequent siblings)
9 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
gfs2-cunTk1MwBs/YUNznpcFYbw, linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
Use the folio APIs, removing numerous hidden calls to compound_head().
Also remove the stale comment about the page being looked up if it's NULL.
Signed-off-by: Matthew Wilcox (Oracle) <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
---
fs/gfs2/bmap.c | 48 +++++++++++++++++++++++-------------------------
1 file changed, 23 insertions(+), 25 deletions(-)
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index ef7017fb6951..247d2c16593c 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -43,53 +43,51 @@ struct metapath {
static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length);
/**
- * gfs2_unstuffer_page - unstuff a stuffed inode into a block cached by a page
+ * gfs2_unstuffer_folio - unstuff a stuffed inode into a block cached by a folio
* @ip: the inode
* @dibh: the dinode buffer
* @block: the block number that was allocated
- * @page: The (optional) page. This is looked up if @page is NULL
+ * @folio: The folio.
*
* Returns: errno
*/
-
-static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
- u64 block, struct page *page)
+static int gfs2_unstuffer_folio(struct gfs2_inode *ip, struct buffer_head *dibh,
+ u64 block, struct folio *folio)
{
struct inode *inode = &ip->i_inode;
- if (!PageUptodate(page)) {
- void *kaddr = kmap(page);
+ if (!folio_test_uptodate(folio)) {
+ void *kaddr = kmap_local_folio(folio, 0);
u64 dsize = i_size_read(inode);
memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
- memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
- kunmap(page);
+ memset(kaddr + dsize, 0, folio_size(folio) - dsize);
+ kunmap_local(kaddr);
- SetPageUptodate(page);
+ folio_mark_uptodate(folio);
}
if (gfs2_is_jdata(ip)) {
- struct buffer_head *bh;
+ struct buffer_head *bh = folio_buffers(folio);
- if (!page_has_buffers(page))
- create_empty_buffers(page, BIT(inode->i_blkbits),
- BIT(BH_Uptodate));
+ if (!bh)
+ bh = folio_create_empty_buffers(folio,
+ BIT(inode->i_blkbits), BIT(BH_Uptodate));
- bh = page_buffers(page);
if (!buffer_mapped(bh))
map_bh(bh, inode->i_sb, block);
set_buffer_uptodate(bh);
gfs2_trans_add_data(ip->i_gl, bh);
} else {
- set_page_dirty(page);
+ folio_mark_dirty(folio);
gfs2_ordered_add_inode(ip);
}
return 0;
}
-static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct page *page)
+static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct folio *folio)
{
struct buffer_head *bh, *dibh;
struct gfs2_dinode *di;
@@ -118,7 +116,7 @@ static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct page *page)
dibh, sizeof(struct gfs2_dinode));
brelse(bh);
} else {
- error = gfs2_unstuffer_page(ip, dibh, block, page);
+ error = gfs2_unstuffer_folio(ip, dibh, block, folio);
if (error)
goto out_brelse;
}
@@ -157,17 +155,17 @@ static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct page *page)
int gfs2_unstuff_dinode(struct gfs2_inode *ip)
{
struct inode *inode = &ip->i_inode;
- struct page *page;
+ struct folio *folio;
int error;
down_write(&ip->i_rw_mutex);
- page = grab_cache_page(inode->i_mapping, 0);
- error = -ENOMEM;
- if (!page)
+ folio = filemap_grab_folio(inode->i_mapping, 0);
+ error = PTR_ERR(folio);
+ if (IS_ERR(folio))
goto out;
- error = __gfs2_unstuff_inode(ip, page);
- unlock_page(page);
- put_page(page);
+ error = __gfs2_unstuff_inode(ip, folio);
+ folio_unlock(folio);
+ folio_put(folio);
out:
up_write(&ip->i_rw_mutex);
return error;
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* Re: [PATCH 05/26] gfs2: Convert inode unstuffing to use a folio
2023-09-19 4:51 ` [PATCH 05/26] gfs2: Convert inode unstuffing to use a folio Matthew Wilcox (Oracle)
@ 2023-09-19 22:28 ` Andreas Gruenbacher
0 siblings, 0 replies; 46+ messages in thread
From: Andreas Gruenbacher @ 2023-09-19 22:28 UTC (permalink / raw)
To: Matthew Wilcox (Oracle)
Cc: Andrew Morton, linux-fsdevel, gfs2, linux-nilfs, linux-ntfs-dev,
ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4, Pankaj Raghav
On Tue, Sep 19, 2023 at 7:00 AM Matthew Wilcox (Oracle)
<willy@infradead.org> wrote:
> Use the folio APIs, removing numerous hidden calls to compound_head().
> Also remove the stale comment about the page being looked up if it's NULL.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> fs/gfs2/bmap.c | 48 +++++++++++++++++++++++-------------------------
> 1 file changed, 23 insertions(+), 25 deletions(-)
>
> diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
> index ef7017fb6951..247d2c16593c 100644
> --- a/fs/gfs2/bmap.c
> +++ b/fs/gfs2/bmap.c
> @@ -43,53 +43,51 @@ struct metapath {
> static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length);
>
> /**
> - * gfs2_unstuffer_page - unstuff a stuffed inode into a block cached by a page
> + * gfs2_unstuffer_folio - unstuff a stuffed inode into a block cached by a folio
> * @ip: the inode
> * @dibh: the dinode buffer
> * @block: the block number that was allocated
> - * @page: The (optional) page. This is looked up if @page is NULL
> + * @folio: The folio.
> *
> * Returns: errno
> */
> -
> -static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
> - u64 block, struct page *page)
> +static int gfs2_unstuffer_folio(struct gfs2_inode *ip, struct buffer_head *dibh,
> + u64 block, struct folio *folio)
> {
> struct inode *inode = &ip->i_inode;
>
> - if (!PageUptodate(page)) {
> - void *kaddr = kmap(page);
> + if (!folio_test_uptodate(folio)) {
> + void *kaddr = kmap_local_folio(folio, 0);
> u64 dsize = i_size_read(inode);
>
> memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
> - memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
> - kunmap(page);
> + memset(kaddr + dsize, 0, folio_size(folio) - dsize);
> + kunmap_local(kaddr);
>
> - SetPageUptodate(page);
> + folio_mark_uptodate(folio);
> }
>
> if (gfs2_is_jdata(ip)) {
> - struct buffer_head *bh;
> + struct buffer_head *bh = folio_buffers(folio);
>
> - if (!page_has_buffers(page))
> - create_empty_buffers(page, BIT(inode->i_blkbits),
> - BIT(BH_Uptodate));
> + if (!bh)
> + bh = folio_create_empty_buffers(folio,
> + BIT(inode->i_blkbits), BIT(BH_Uptodate));
>
> - bh = page_buffers(page);
> if (!buffer_mapped(bh))
> map_bh(bh, inode->i_sb, block);
>
> set_buffer_uptodate(bh);
> gfs2_trans_add_data(ip->i_gl, bh);
> } else {
> - set_page_dirty(page);
> + folio_mark_dirty(folio);
> gfs2_ordered_add_inode(ip);
> }
>
> return 0;
> }
>
> -static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct page *page)
> +static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct folio *folio)
> {
> struct buffer_head *bh, *dibh;
> struct gfs2_dinode *di;
> @@ -118,7 +116,7 @@ static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct page *page)
> dibh, sizeof(struct gfs2_dinode));
> brelse(bh);
> } else {
> - error = gfs2_unstuffer_page(ip, dibh, block, page);
> + error = gfs2_unstuffer_folio(ip, dibh, block, folio);
> if (error)
> goto out_brelse;
> }
> @@ -157,17 +155,17 @@ static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct page *page)
> int gfs2_unstuff_dinode(struct gfs2_inode *ip)
> {
> struct inode *inode = &ip->i_inode;
> - struct page *page;
> + struct folio *folio;
> int error;
>
> down_write(&ip->i_rw_mutex);
> - page = grab_cache_page(inode->i_mapping, 0);
> - error = -ENOMEM;
> - if (!page)
> + folio = filemap_grab_folio(inode->i_mapping, 0);
> + error = PTR_ERR(folio);
> + if (IS_ERR(folio))
> goto out;
> - error = __gfs2_unstuff_inode(ip, page);
> - unlock_page(page);
> - put_page(page);
> + error = __gfs2_unstuff_inode(ip, folio);
> + folio_unlock(folio);
> + folio_put(folio);
> out:
> up_write(&ip->i_rw_mutex);
> return error;
> --
> 2.40.1
>
Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com>
Thanks,
Andreas
^ permalink raw reply [flat|nested] 46+ messages in thread
* [PATCH 06/26] gfs2: Convert gfs2_getbuf() to folios
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2023-09-19 4:51 ` [PATCH 04/26] buffer: Add get_nth_bh() Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 05/26] gfs2: Convert inode unstuffing to use a folio Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 22:34 ` Andreas Gruenbacher
2023-09-19 4:51 ` [PATCH 08/26] gfs2: Convert gfs2_write_buf_to_page() to use a folio Matthew Wilcox (Oracle)
` (6 subsequent siblings)
9 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
gfs2-cunTk1MwBs/YUNznpcFYbw, linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
Remove several folio->page->folio conversions. Also use __GFP_NOFAIL
instead of calling yield() and the new get_nth_bh().
Signed-off-by: Matthew Wilcox (Oracle) <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
---
fs/gfs2/meta_io.c | 39 +++++++++++++++++----------------------
1 file changed, 17 insertions(+), 22 deletions(-)
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 924361fa510b..f1fac1b45059 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -115,7 +115,7 @@ struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
{
struct address_space *mapping = gfs2_glock2aspace(gl);
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
- struct page *page;
+ struct folio *folio;
struct buffer_head *bh;
unsigned int shift;
unsigned long index;
@@ -129,36 +129,31 @@ struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
bufnum = blkno - (index << shift); /* block buf index within page */
if (create) {
- for (;;) {
- page = grab_cache_page(mapping, index);
- if (page)
- break;
- yield();
- }
- if (!page_has_buffers(page))
- create_empty_buffers(page, sdp->sd_sb.sb_bsize, 0);
+ folio = __filemap_get_folio(mapping, index,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
+ mapping_gfp_mask(mapping) | __GFP_NOFAIL);
+ bh = folio_buffers(folio);
+ if (!bh)
+ bh = folio_create_empty_buffers(folio,
+ sdp->sd_sb.sb_bsize, 0);
} else {
- page = find_get_page_flags(mapping, index,
- FGP_LOCK|FGP_ACCESSED);
- if (!page)
+ folio = __filemap_get_folio(mapping, index,
+ FGP_LOCK | FGP_ACCESSED, 0);
+ if (IS_ERR(folio))
return NULL;
- if (!page_has_buffers(page)) {
- bh = NULL;
- goto out_unlock;
- }
+ bh = folio_buffers(folio);
}
- /* Locate header for our buffer within our page */
- for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page)
- /* Do nothing */;
- get_bh(bh);
+ if (!bh)
+ goto out_unlock;
+ bh = get_nth_bh(bh, bufnum);
if (!buffer_mapped(bh))
map_bh(bh, sdp->sd_vfs, blkno);
out_unlock:
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
return bh;
}
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* Re: [PATCH 06/26] gfs2: Convert gfs2_getbuf() to folios
2023-09-19 4:51 ` [PATCH 06/26] gfs2: Convert gfs2_getbuf() to folios Matthew Wilcox (Oracle)
@ 2023-09-19 22:34 ` Andreas Gruenbacher
0 siblings, 0 replies; 46+ messages in thread
From: Andreas Gruenbacher @ 2023-09-19 22:34 UTC (permalink / raw)
To: Matthew Wilcox (Oracle)
Cc: Andrew Morton, linux-fsdevel, gfs2, linux-nilfs, linux-ntfs-dev,
ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4, Pankaj Raghav
On Tue, Sep 19, 2023 at 7:00 AM Matthew Wilcox (Oracle)
<willy@infradead.org> wrote:
> Remove several folio->page->folio conversions. Also use __GFP_NOFAIL
> instead of calling yield() and the new get_nth_bh().
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> fs/gfs2/meta_io.c | 39 +++++++++++++++++----------------------
> 1 file changed, 17 insertions(+), 22 deletions(-)
>
> diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
> index 924361fa510b..f1fac1b45059 100644
> --- a/fs/gfs2/meta_io.c
> +++ b/fs/gfs2/meta_io.c
> @@ -115,7 +115,7 @@ struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
> {
> struct address_space *mapping = gfs2_glock2aspace(gl);
> struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
> - struct page *page;
> + struct folio *folio;
> struct buffer_head *bh;
> unsigned int shift;
> unsigned long index;
> @@ -129,36 +129,31 @@ struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
> bufnum = blkno - (index << shift); /* block buf index within page */
>
> if (create) {
> - for (;;) {
> - page = grab_cache_page(mapping, index);
> - if (page)
> - break;
> - yield();
> - }
> - if (!page_has_buffers(page))
> - create_empty_buffers(page, sdp->sd_sb.sb_bsize, 0);
> + folio = __filemap_get_folio(mapping, index,
> + FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
> + mapping_gfp_mask(mapping) | __GFP_NOFAIL);
> + bh = folio_buffers(folio);
> + if (!bh)
> + bh = folio_create_empty_buffers(folio,
> + sdp->sd_sb.sb_bsize, 0);
> } else {
> - page = find_get_page_flags(mapping, index,
> - FGP_LOCK|FGP_ACCESSED);
> - if (!page)
> + folio = __filemap_get_folio(mapping, index,
> + FGP_LOCK | FGP_ACCESSED, 0);
> + if (IS_ERR(folio))
> return NULL;
> - if (!page_has_buffers(page)) {
> - bh = NULL;
> - goto out_unlock;
> - }
> + bh = folio_buffers(folio);
> }
>
> - /* Locate header for our buffer within our page */
> - for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page)
> - /* Do nothing */;
> - get_bh(bh);
> + if (!bh)
> + goto out_unlock;
>
> + bh = get_nth_bh(bh, bufnum);
> if (!buffer_mapped(bh))
> map_bh(bh, sdp->sd_vfs, blkno);
>
> out_unlock:
> - unlock_page(page);
> - put_page(page);
> + folio_unlock(folio);
> + folio_put(folio);
>
> return bh;
> }
> --
> 2.40.1
>
Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com>
Thanks,
Andreas
^ permalink raw reply [flat|nested] 46+ messages in thread
* [PATCH 08/26] gfs2: Convert gfs2_write_buf_to_page() to use a folio
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
` (2 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 06/26] gfs2: Convert gfs2_getbuf() to folios Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
[not found] ` <20230919045135.3635437-9-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2023-09-19 4:51 ` [PATCH 09/26] nilfs2: Convert nilfs_mdt_freeze_buffer " Matthew Wilcox (Oracle)
` (5 subsequent siblings)
9 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
gfs2-cunTk1MwBs/YUNznpcFYbw, linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
Remove several folio->page->folio conversions.
Signed-off-by: Matthew Wilcox (Oracle) <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
---
fs/gfs2/quota.c | 37 +++++++++++++++++++------------------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 171b2713d2e5..0ee4865ebdca 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -736,7 +736,7 @@ static int gfs2_write_buf_to_page(struct gfs2_sbd *sdp, unsigned long index,
struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
struct inode *inode = &ip->i_inode;
struct address_space *mapping = inode->i_mapping;
- struct page *page;
+ struct folio *folio;
struct buffer_head *bh;
u64 blk;
unsigned bsize = sdp->sd_sb.sb_bsize, bnum = 0, boff = 0;
@@ -745,15 +745,15 @@ static int gfs2_write_buf_to_page(struct gfs2_sbd *sdp, unsigned long index,
blk = index << (PAGE_SHIFT - sdp->sd_sb.sb_bsize_shift);
boff = off % bsize;
- page = grab_cache_page(mapping, index);
- if (!page)
- return -ENOMEM;
- if (!page_has_buffers(page))
- create_empty_buffers(page, bsize, 0);
+ folio = filemap_grab_folio(mapping, index);
+ if (IS_ERR(folio))
+ return PTR_ERR(folio);
+ bh = folio_buffers(folio);
+ if (!bh)
+ bh = folio_create_empty_buffers(folio, bsize, 0);
- bh = page_buffers(page);
- for(;;) {
- /* Find the beginning block within the page */
+ for (;;) {
+ /* Find the beginning block within the folio */
if (pg_off >= ((bnum * bsize) + bsize)) {
bh = bh->b_this_page;
bnum++;
@@ -766,9 +766,10 @@ static int gfs2_write_buf_to_page(struct gfs2_sbd *sdp, unsigned long index,
goto unlock_out;
/* If it's a newly allocated disk block, zero it */
if (buffer_new(bh))
- zero_user(page, bnum * bsize, bh->b_size);
+ folio_zero_range(folio, bnum * bsize,
+ bh->b_size);
}
- if (PageUptodate(page))
+ if (folio_test_uptodate(folio))
set_buffer_uptodate(bh);
if (bh_read(bh, REQ_META | REQ_PRIO) < 0)
goto unlock_out;
@@ -784,17 +785,17 @@ static int gfs2_write_buf_to_page(struct gfs2_sbd *sdp, unsigned long index,
break;
}
- /* Write to the page, now that we have setup the buffer(s) */
- memcpy_to_page(page, off, buf, bytes);
- flush_dcache_page(page);
- unlock_page(page);
- put_page(page);
+ /* Write to the folio, now that we have setup the buffer(s) */
+ memcpy_to_folio(folio, off, buf, bytes);
+ flush_dcache_folio(folio);
+ folio_unlock(folio);
+ folio_put(folio);
return 0;
unlock_out:
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
return -EIO;
}
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 09/26] nilfs2: Convert nilfs_mdt_freeze_buffer to use a folio
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
` (3 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 08/26] gfs2: Convert gfs2_write_buf_to_page() to use a folio Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
[not found] ` <20230919045135.3635437-10-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2023-09-19 4:51 ` [PATCH 13/26] nilfs2: Convert nilfs_mdt_get_frozen_buffer " Matthew Wilcox (Oracle)
` (4 subsequent siblings)
9 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
gfs2-cunTk1MwBs/YUNznpcFYbw, linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
Remove a number of folio->page->folio conversions.
Signed-off-by: Matthew Wilcox (Oracle) <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
---
fs/nilfs2/mdt.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 19c8158605ed..db2260d6e44d 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -560,17 +560,19 @@ int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh)
{
struct nilfs_shadow_map *shadow = NILFS_MDT(inode)->mi_shadow;
struct buffer_head *bh_frozen;
- struct page *page;
+ struct folio *folio;
int blkbits = inode->i_blkbits;
- page = grab_cache_page(shadow->inode->i_mapping, bh->b_folio->index);
- if (!page)
- return -ENOMEM;
+ folio = filemap_grab_folio(shadow->inode->i_mapping,
+ bh->b_folio->index);
+ if (IS_ERR(folio))
+ return PTR_ERR(folio);
- if (!page_has_buffers(page))
- create_empty_buffers(page, 1 << blkbits, 0);
+ bh_frozen = folio_buffers(folio);
+ if (!bh_frozen)
+ bh_frozen = folio_create_empty_buffers(folio, 1 << blkbits, 0);
- bh_frozen = nilfs_page_get_nth_block(page, bh_offset(bh) >> blkbits);
+ bh_frozen = get_nth_bh(bh_frozen, bh_offset(bh) >> blkbits);
if (!buffer_uptodate(bh_frozen))
nilfs_copy_buffer(bh_frozen, bh);
@@ -582,8 +584,8 @@ int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh)
brelse(bh_frozen); /* already frozen */
}
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
return 0;
}
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 13/26] nilfs2: Convert nilfs_mdt_get_frozen_buffer to use a folio
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
` (4 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 09/26] nilfs2: Convert nilfs_mdt_freeze_buffer " Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-20 8:07 ` Ryusuke Konishi
2023-09-19 4:51 ` [PATCH 17/26] ntfs: Convert ntfs_writepage " Matthew Wilcox (Oracle)
` (3 subsequent siblings)
9 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
gfs2-cunTk1MwBs/YUNznpcFYbw, linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
Remove a number of folio->page->folio conversions.
Signed-off-by: Matthew Wilcox (Oracle) <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
---
fs/nilfs2/mdt.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 11b7cf4acc92..7b754e6494d7 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -592,17 +592,19 @@ nilfs_mdt_get_frozen_buffer(struct inode *inode, struct buffer_head *bh)
{
struct nilfs_shadow_map *shadow = NILFS_MDT(inode)->mi_shadow;
struct buffer_head *bh_frozen = NULL;
- struct page *page;
+ struct folio *folio;
int n;
- page = find_lock_page(shadow->inode->i_mapping, bh->b_folio->index);
- if (page) {
- if (page_has_buffers(page)) {
+ folio = filemap_lock_folio(shadow->inode->i_mapping,
+ bh->b_folio->index);
+ if (!IS_ERR(folio)) {
+ bh_frozen = folio_buffers(folio);
+ if (bh_frozen) {
n = bh_offset(bh) >> inode->i_blkbits;
- bh_frozen = nilfs_page_get_nth_block(page, n);
+ bh_frozen = get_nth_bh(bh_frozen, n);
}
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
}
return bh_frozen;
}
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* Re: [PATCH 13/26] nilfs2: Convert nilfs_mdt_get_frozen_buffer to use a folio
2023-09-19 4:51 ` [PATCH 13/26] nilfs2: Convert nilfs_mdt_get_frozen_buffer " Matthew Wilcox (Oracle)
@ 2023-09-20 8:07 ` Ryusuke Konishi
0 siblings, 0 replies; 46+ messages in thread
From: Ryusuke Konishi @ 2023-09-20 8:07 UTC (permalink / raw)
To: Matthew Wilcox (Oracle)
Cc: Andrew Morton, linux-fsdevel, gfs2, linux-nilfs, linux-ntfs-dev,
ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4, Pankaj Raghav
On Tue, Sep 19, 2023 at 6:25 PM Matthew Wilcox (Oracle) wrote:
>
> Remove a number of folio->page->folio conversions.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> fs/nilfs2/mdt.c | 16 +++++++++-------
> 1 file changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
> index 11b7cf4acc92..7b754e6494d7 100644
> --- a/fs/nilfs2/mdt.c
> +++ b/fs/nilfs2/mdt.c
> @@ -592,17 +592,19 @@ nilfs_mdt_get_frozen_buffer(struct inode *inode, struct buffer_head *bh)
> {
> struct nilfs_shadow_map *shadow = NILFS_MDT(inode)->mi_shadow;
> struct buffer_head *bh_frozen = NULL;
> - struct page *page;
> + struct folio *folio;
> int n;
>
> - page = find_lock_page(shadow->inode->i_mapping, bh->b_folio->index);
> - if (page) {
> - if (page_has_buffers(page)) {
> + folio = filemap_lock_folio(shadow->inode->i_mapping,
> + bh->b_folio->index);
> + if (!IS_ERR(folio)) {
> + bh_frozen = folio_buffers(folio);
> + if (bh_frozen) {
> n = bh_offset(bh) >> inode->i_blkbits;
> - bh_frozen = nilfs_page_get_nth_block(page, n);
> + bh_frozen = get_nth_bh(bh_frozen, n);
> }
> - unlock_page(page);
> - put_page(page);
> + folio_unlock(folio);
> + folio_put(folio);
> }
> return bh_frozen;
> }
> --
> 2.40.1
>
Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Looks good to me.
Thanks,
Ryusuke Konishi
^ permalink raw reply [flat|nested] 46+ messages in thread
* [PATCH 17/26] ntfs: Convert ntfs_writepage to use a folio
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
` (5 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 13/26] nilfs2: Convert nilfs_mdt_get_frozen_buffer " Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 21/26] reiserfs: Convert writepage " Matthew Wilcox (Oracle)
` (2 subsequent siblings)
9 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
gfs2-cunTk1MwBs/YUNznpcFYbw, linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
use folio APIs throughout. Saves many hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
---
fs/ntfs/aops.c | 211 +++++++++++++++++++++++--------------------------
1 file changed, 100 insertions(+), 111 deletions(-)
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index d66a9f5ffde9..c4426992a2ee 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -501,28 +501,29 @@ static int ntfs_read_folio(struct file *file, struct folio *folio)
#ifdef NTFS_RW
/**
- * ntfs_write_block - write a @page to the backing store
- * @page: page cache page to write out
+ * ntfs_write_block - write a @folio to the backing store
+ * @folio: page cache folio to write out
* @wbc: writeback control structure
*
- * This function is for writing pages belonging to non-resident, non-mst
+ * This function is for writing folios belonging to non-resident, non-mst
* protected attributes to their backing store.
*
- * For a page with buffers, map and write the dirty buffers asynchronously
- * under page writeback. For a page without buffers, create buffers for the
- * page, then proceed as above.
+ * For a folio with buffers, map and write the dirty buffers asynchronously
+ * under folio writeback. For a folio without buffers, create buffers for the
+ * folio, then proceed as above.
*
- * If a page doesn't have buffers the page dirty state is definitive. If a page
- * does have buffers, the page dirty state is just a hint, and the buffer dirty
- * state is definitive. (A hint which has rules: dirty buffers against a clean
- * page is illegal. Other combinations are legal and need to be handled. In
- * particular a dirty page containing clean buffers for example.)
+ * If a folio doesn't have buffers the folio dirty state is definitive. If
+ * a folio does have buffers, the folio dirty state is just a hint,
+ * and the buffer dirty state is definitive. (A hint which has rules:
+ * dirty buffers against a clean folio is illegal. Other combinations are
+ * legal and need to be handled. In particular a dirty folio containing
+ * clean buffers for example.)
*
* Return 0 on success and -errno on error.
*
* Based on ntfs_read_block() and __block_write_full_folio().
*/
-static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
+static int ntfs_write_block(struct folio *folio, struct writeback_control *wbc)
{
VCN vcn;
LCN lcn;
@@ -540,41 +541,29 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
bool need_end_writeback;
unsigned char blocksize_bits;
- vi = page->mapping->host;
+ vi = folio->mapping->host;
ni = NTFS_I(vi);
vol = ni->vol;
ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
- "0x%lx.", ni->mft_no, ni->type, page->index);
+ "0x%lx.", ni->mft_no, ni->type, folio->index);
BUG_ON(!NInoNonResident(ni));
BUG_ON(NInoMstProtected(ni));
blocksize = vol->sb->s_blocksize;
blocksize_bits = vol->sb->s_blocksize_bits;
- if (!page_has_buffers(page)) {
- BUG_ON(!PageUptodate(page));
- create_empty_buffers(page, blocksize,
+ head = folio_buffers(folio);
+ if (!head) {
+ BUG_ON(!folio_test_uptodate(folio));
+ head = folio_create_empty_buffers(folio, blocksize,
(1 << BH_Uptodate) | (1 << BH_Dirty));
- if (unlikely(!page_has_buffers(page))) {
- ntfs_warning(vol->sb, "Error allocating page "
- "buffers. Redirtying page so we try "
- "again later.");
- /*
- * Put the page back on mapping->dirty_pages, but leave
- * its buffers' dirty state as-is.
- */
- redirty_page_for_writepage(wbc, page);
- unlock_page(page);
- return 0;
- }
}
- bh = head = page_buffers(page);
- BUG_ON(!bh);
+ bh = head;
/* NOTE: Different naming scheme to ntfs_read_block()! */
- /* The first block in the page. */
- block = (s64)page->index << (PAGE_SHIFT - blocksize_bits);
+ /* The first block in the folio. */
+ block = (s64)folio->index << (PAGE_SHIFT - blocksize_bits);
read_lock_irqsave(&ni->size_lock, flags);
i_size = i_size_read(vi);
@@ -591,14 +580,14 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
* Be very careful. We have no exclusion from block_dirty_folio
* here, and the (potentially unmapped) buffers may become dirty at
* any time. If a buffer becomes dirty here after we've inspected it
- * then we just miss that fact, and the page stays dirty.
+ * then we just miss that fact, and the folio stays dirty.
*
* Buffers outside i_size may be dirtied by block_dirty_folio;
* handle that here by just cleaning them.
*/
/*
- * Loop through all the buffers in the page, mapping all the dirty
+ * Loop through all the buffers in the folio, mapping all the dirty
* buffers to disk addresses and handling any aliases from the
* underlying block device's mapping.
*/
@@ -610,13 +599,13 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
if (unlikely(block >= dblock)) {
/*
* Mapped buffers outside i_size will occur, because
- * this page can be outside i_size when there is a
+ * this folio can be outside i_size when there is a
* truncate in progress. The contents of such buffers
* were zeroed by ntfs_writepage().
*
* FIXME: What about the small race window where
* ntfs_writepage() has not done any clearing because
- * the page was within i_size but before we get here,
+ * the folio was within i_size but before we get here,
* vmtruncate() modifies i_size?
*/
clear_buffer_dirty(bh);
@@ -632,38 +621,38 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
if (unlikely((block >= iblock) &&
(initialized_size < i_size))) {
/*
- * If this page is fully outside initialized
- * size, zero out all pages between the current
- * initialized size and the current page. Just
+ * If this folio is fully outside initialized
+ * size, zero out all folios between the current
+ * initialized size and the current folio. Just
* use ntfs_read_folio() to do the zeroing
* transparently.
*/
if (block > iblock) {
// TODO:
- // For each page do:
- // - read_cache_page()
- // Again for each page do:
- // - wait_on_page_locked()
- // - Check (PageUptodate(page) &&
- // !PageError(page))
+ // For each folio do:
+ // - read_cache_folio()
+ // Again for each folio do:
+ // - wait_on_folio_locked()
+ // - Check (folio_test_uptodate(folio) &&
+ // !folio_test_error(folio))
// Update initialized size in the attribute and
// in the inode.
- // Again, for each page do:
+ // Again, for each folio do:
// block_dirty_folio();
- // put_page()
+ // folio_put()
// We don't need to wait on the writes.
// Update iblock.
}
/*
- * The current page straddles initialized size. Zero
+ * The current folio straddles initialized size. Zero
* all non-uptodate buffers and set them uptodate (and
* dirty?). Note, there aren't any non-uptodate buffers
- * if the page is uptodate.
- * FIXME: For an uptodate page, the buffers may need to
+ * if the folio is uptodate.
+ * FIXME: For an uptodate folio, the buffers may need to
* be written out because they were not initialized on
* disk before.
*/
- if (!PageUptodate(page)) {
+ if (!folio_test_uptodate(folio)) {
// TODO:
// Zero any non-uptodate buffers up to i_size.
// Set them uptodate and dirty.
@@ -721,14 +710,14 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
unsigned long *bpos, *bend;
/* Check if the buffer is zero. */
- kaddr = kmap_atomic(page);
- bpos = (unsigned long *)(kaddr + bh_offset(bh));
- bend = (unsigned long *)((u8*)bpos + blocksize);
+ kaddr = kmap_local_folio(folio, bh_offset(bh));
+ bpos = (unsigned long *)kaddr;
+ bend = (unsigned long *)(kaddr + blocksize);
do {
if (unlikely(*bpos))
break;
} while (likely(++bpos < bend));
- kunmap_atomic(kaddr);
+ kunmap_local(kaddr);
if (bpos == bend) {
/*
* Buffer is zero and sparse, no need to write
@@ -768,7 +757,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
if (err == -ENOENT || lcn == LCN_ENOENT) {
bh->b_blocknr = -1;
clear_buffer_dirty(bh);
- zero_user(page, bh_offset(bh), blocksize);
+ folio_zero_range(folio, bh_offset(bh), blocksize);
set_buffer_uptodate(bh);
err = 0;
continue;
@@ -795,7 +784,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
bh = head;
/* Just an optimization, so ->read_folio() is not called later. */
- if (unlikely(!PageUptodate(page))) {
+ if (unlikely(!folio_test_uptodate(folio))) {
int uptodate = 1;
do {
if (!buffer_uptodate(bh)) {
@@ -805,7 +794,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
}
} while ((bh = bh->b_this_page) != head);
if (uptodate)
- SetPageUptodate(page);
+ folio_mark_uptodate(folio);
}
/* Setup all mapped, dirty buffers for async write i/o. */
@@ -820,7 +809,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
} else if (unlikely(err)) {
/*
* For the error case. The buffer may have been set
- * dirty during attachment to a dirty page.
+ * dirty during attachment to a dirty folio.
*/
if (err != -ENOMEM)
clear_buffer_dirty(bh);
@@ -833,20 +822,20 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
err = 0;
else if (err == -ENOMEM) {
ntfs_warning(vol->sb, "Error allocating memory. "
- "Redirtying page so we try again "
+ "Redirtying folio so we try again "
"later.");
/*
- * Put the page back on mapping->dirty_pages, but
+ * Put the folio back on mapping->dirty_pages, but
* leave its buffer's dirty state as-is.
*/
- redirty_page_for_writepage(wbc, page);
+ folio_redirty_for_writepage(wbc, folio);
err = 0;
} else
- SetPageError(page);
+ folio_set_error(folio);
}
- BUG_ON(PageWriteback(page));
- set_page_writeback(page); /* Keeps try_to_free_buffers() away. */
+ BUG_ON(folio_test_writeback(folio));
+ folio_start_writeback(folio); /* Keeps try_to_free_buffers() away. */
/* Submit the prepared buffers for i/o. */
need_end_writeback = true;
@@ -858,11 +847,11 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
}
bh = next;
} while (bh != head);
- unlock_page(page);
+ folio_unlock(folio);
- /* If no i/o was started, need to end_page_writeback(). */
+ /* If no i/o was started, need to end writeback here. */
if (unlikely(need_end_writeback))
- end_page_writeback(page);
+ folio_end_writeback(folio);
ntfs_debug("Done.");
return err;
@@ -1331,8 +1320,9 @@ static int ntfs_write_mst_block(struct page *page,
*/
static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
{
+ struct folio *folio = page_folio(page);
loff_t i_size;
- struct inode *vi = page->mapping->host;
+ struct inode *vi = folio->mapping->host;
ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);
char *addr;
ntfs_attr_search_ctx *ctx = NULL;
@@ -1341,14 +1331,13 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
int err;
retry_writepage:
- BUG_ON(!PageLocked(page));
+ BUG_ON(!folio_test_locked(folio));
i_size = i_size_read(vi);
- /* Is the page fully outside i_size? (truncate in progress) */
- if (unlikely(page->index >= (i_size + PAGE_SIZE - 1) >>
+ /* Is the folio fully outside i_size? (truncate in progress) */
+ if (unlikely(folio->index >= (i_size + PAGE_SIZE - 1) >>
PAGE_SHIFT)) {
- struct folio *folio = page_folio(page);
/*
- * The page may have dirty, unmapped buffers. Make them
+ * The folio may have dirty, unmapped buffers. Make them
* freeable here, so the page does not leak.
*/
block_invalidate_folio(folio, 0, folio_size(folio));
@@ -1367,7 +1356,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
if (ni->type != AT_INDEX_ALLOCATION) {
/* If file is encrypted, deny access, just like NT4. */
if (NInoEncrypted(ni)) {
- unlock_page(page);
+ folio_unlock(folio);
BUG_ON(ni->type != AT_DATA);
ntfs_debug("Denying write access to encrypted file.");
return -EACCES;
@@ -1378,14 +1367,14 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
BUG_ON(ni->name_len);
// TODO: Implement and replace this with
// return ntfs_write_compressed_block(page);
- unlock_page(page);
+ folio_unlock(folio);
ntfs_error(vi->i_sb, "Writing to compressed files is "
"not supported yet. Sorry.");
return -EOPNOTSUPP;
}
// TODO: Implement and remove this check.
if (NInoNonResident(ni) && NInoSparse(ni)) {
- unlock_page(page);
+ folio_unlock(folio);
ntfs_error(vi->i_sb, "Writing to sparse files is not "
"supported yet. Sorry.");
return -EOPNOTSUPP;
@@ -1394,34 +1383,34 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
/* NInoNonResident() == NInoIndexAllocPresent() */
if (NInoNonResident(ni)) {
/* We have to zero every time due to mmap-at-end-of-file. */
- if (page->index >= (i_size >> PAGE_SHIFT)) {
- /* The page straddles i_size. */
- unsigned int ofs = i_size & ~PAGE_MASK;
- zero_user_segment(page, ofs, PAGE_SIZE);
+ if (folio->index >= (i_size >> PAGE_SHIFT)) {
+ /* The folio straddles i_size. */
+ unsigned int ofs = i_size & (folio_size(folio) - 1);
+ folio_zero_segment(folio, ofs, folio_size(folio));
}
/* Handle mst protected attributes. */
if (NInoMstProtected(ni))
return ntfs_write_mst_block(page, wbc);
/* Normal, non-resident data stream. */
- return ntfs_write_block(page, wbc);
+ return ntfs_write_block(folio, wbc);
}
/*
* Attribute is resident, implying it is not compressed, encrypted, or
* mst protected. This also means the attribute is smaller than an mft
- * record and hence smaller than a page, so can simply return error on
- * any pages with index above 0. Note the attribute can actually be
+ * record and hence smaller than a folio, so can simply return error on
+ * any folios with index above 0. Note the attribute can actually be
* marked compressed but if it is resident the actual data is not
* compressed so we are ok to ignore the compressed flag here.
*/
- BUG_ON(page_has_buffers(page));
- BUG_ON(!PageUptodate(page));
- if (unlikely(page->index > 0)) {
- ntfs_error(vi->i_sb, "BUG()! page->index (0x%lx) > 0. "
- "Aborting write.", page->index);
- BUG_ON(PageWriteback(page));
- set_page_writeback(page);
- unlock_page(page);
- end_page_writeback(page);
+ BUG_ON(folio_buffers(folio));
+ BUG_ON(!folio_test_uptodate(folio));
+ if (unlikely(folio->index > 0)) {
+ ntfs_error(vi->i_sb, "BUG()! folio->index (0x%lx) > 0. "
+ "Aborting write.", folio->index);
+ BUG_ON(folio_test_writeback(folio));
+ folio_start_writeback(folio);
+ folio_unlock(folio);
+ folio_end_writeback(folio);
return -EIO;
}
if (!NInoAttr(ni))
@@ -1454,12 +1443,12 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
if (unlikely(err))
goto err_out;
/*
- * Keep the VM happy. This must be done otherwise the radix-tree tag
- * PAGECACHE_TAG_DIRTY remains set even though the page is clean.
+ * Keep the VM happy. This must be done otherwise
+ * PAGECACHE_TAG_DIRTY remains set even though the folio is clean.
*/
- BUG_ON(PageWriteback(page));
- set_page_writeback(page);
- unlock_page(page);
+ BUG_ON(folio_test_writeback(folio));
+ folio_start_writeback(folio);
+ folio_unlock(folio);
attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
i_size = i_size_read(vi);
if (unlikely(attr_len > i_size)) {
@@ -1474,18 +1463,18 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
/* Shrinking cannot fail. */
BUG_ON(err);
}
- addr = kmap_atomic(page);
- /* Copy the data from the page to the mft record. */
+ addr = kmap_local_folio(folio, 0);
+ /* Copy the data from the folio to the mft record. */
memcpy((u8*)ctx->attr +
le16_to_cpu(ctx->attr->data.resident.value_offset),
addr, attr_len);
- /* Zero out of bounds area in the page cache page. */
- memset(addr + attr_len, 0, PAGE_SIZE - attr_len);
- kunmap_atomic(addr);
- flush_dcache_page(page);
+ /* Zero out of bounds area in the page cache folio. */
+ memset(addr + attr_len, 0, folio_size(folio) - attr_len);
+ kunmap_local(addr);
+ flush_dcache_folio(folio);
flush_dcache_mft_record_page(ctx->ntfs_ino);
- /* We are done with the page. */
- end_page_writeback(page);
+ /* We are done with the folio. */
+ folio_end_writeback(folio);
/* Finally, mark the mft record dirty, so it gets written back. */
mark_mft_record_dirty(ctx->ntfs_ino);
ntfs_attr_put_search_ctx(ctx);
@@ -1496,18 +1485,18 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
ntfs_warning(vi->i_sb, "Error allocating memory. Redirtying "
"page so we try again later.");
/*
- * Put the page back on mapping->dirty_pages, but leave its
+ * Put the folio back on mapping->dirty_pages, but leave its
* buffers' dirty state as-is.
*/
- redirty_page_for_writepage(wbc, page);
+ folio_redirty_for_writepage(wbc, folio);
err = 0;
} else {
ntfs_error(vi->i_sb, "Resident attribute write failed with "
"error %i.", err);
- SetPageError(page);
+ folio_set_error(folio);
NVolSetErrors(ni->vol);
}
- unlock_page(page);
+ folio_unlock(folio);
if (ctx)
ntfs_attr_put_search_ctx(ctx);
if (m)
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 21/26] reiserfs: Convert writepage to use a folio
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
` (6 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 17/26] ntfs: Convert ntfs_writepage " Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 22/26] ufs: Add ufs_get_locked_folio and ufs_put_locked_folio Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 23/26] ufs: Use ufs_get_locked_folio() in ufs_alloc_lastblock() Matthew Wilcox (Oracle)
9 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
gfs2-cunTk1MwBs/YUNznpcFYbw, linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
Convert the incoming page to a folio and then use it throughout the
writeback path. This definitely isn't enough to support large folios, but
I don't expect reiserfs to gain support for those before it is removed.
Signed-off-by: Matthew Wilcox (Oracle) <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
---
fs/reiserfs/inode.c | 80 ++++++++++++++++++++++-----------------------
1 file changed, 40 insertions(+), 40 deletions(-)
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 86e55d4bb10d..d9737235b8e0 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2507,10 +2507,10 @@ static int map_block_for_writepage(struct inode *inode,
* start/recovery path as __block_write_full_folio, along with special
* code to handle reiserfs tails.
*/
-static int reiserfs_write_full_page(struct page *page,
+static int reiserfs_write_full_folio(struct folio *folio,
struct writeback_control *wbc)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = folio->mapping->host;
unsigned long end_index = inode->i_size >> PAGE_SHIFT;
int error = 0;
unsigned long block;
@@ -2518,7 +2518,7 @@ static int reiserfs_write_full_page(struct page *page,
struct buffer_head *head, *bh;
int partial = 0;
int nr = 0;
- int checked = PageChecked(page);
+ int checked = folio_test_checked(folio);
struct reiserfs_transaction_handle th;
struct super_block *s = inode->i_sb;
int bh_per_page = PAGE_SIZE / s->s_blocksize;
@@ -2526,47 +2526,46 @@ static int reiserfs_write_full_page(struct page *page,
/* no logging allowed when nonblocking or from PF_MEMALLOC */
if (checked && (current->flags & PF_MEMALLOC)) {
- redirty_page_for_writepage(wbc, page);
- unlock_page(page);
+ folio_redirty_for_writepage(wbc, folio);
+ folio_unlock(folio);
return 0;
}
/*
- * The page dirty bit is cleared before writepage is called, which
+ * The folio dirty bit is cleared before writepage is called, which
* means we have to tell create_empty_buffers to make dirty buffers
- * The page really should be up to date at this point, so tossing
+ * The folio really should be up to date at this point, so tossing
* in the BH_Uptodate is just a sanity check.
*/
- if (!page_has_buffers(page)) {
- create_empty_buffers(page, s->s_blocksize,
+ head = folio_buffers(folio);
+ if (!head)
+ head = folio_create_empty_buffers(folio, s->s_blocksize,
(1 << BH_Dirty) | (1 << BH_Uptodate));
- }
- head = page_buffers(page);
/*
- * last page in the file, zero out any contents past the
+ * last folio in the file, zero out any contents past the
* last byte in the file
*/
- if (page->index >= end_index) {
+ if (folio->index >= end_index) {
unsigned last_offset;
last_offset = inode->i_size & (PAGE_SIZE - 1);
- /* no file contents in this page */
- if (page->index >= end_index + 1 || !last_offset) {
- unlock_page(page);
+ /* no file contents in this folio */
+ if (folio->index >= end_index + 1 || !last_offset) {
+ folio_unlock(folio);
return 0;
}
- zero_user_segment(page, last_offset, PAGE_SIZE);
+ folio_zero_segment(folio, last_offset, folio_size(folio));
}
bh = head;
- block = page->index << (PAGE_SHIFT - s->s_blocksize_bits);
+ block = folio->index << (PAGE_SHIFT - s->s_blocksize_bits);
last_block = (i_size_read(inode) - 1) >> inode->i_blkbits;
/* first map all the buffers, logging any direct items we find */
do {
if (block > last_block) {
/*
* This can happen when the block size is less than
- * the page size. The corresponding bytes in the page
+ * the folio size. The corresponding bytes in the folio
* were zero filled above
*/
clear_buffer_dirty(bh);
@@ -2593,7 +2592,7 @@ static int reiserfs_write_full_page(struct page *page,
* blocks we're going to log
*/
if (checked) {
- ClearPageChecked(page);
+ folio_clear_checked(folio);
reiserfs_write_lock(s);
error = journal_begin(&th, s, bh_per_page + 1);
if (error) {
@@ -2602,7 +2601,7 @@ static int reiserfs_write_full_page(struct page *page,
}
reiserfs_update_inode_transaction(inode);
}
- /* now go through and lock any dirty buffers on the page */
+ /* now go through and lock any dirty buffers on the folio */
do {
get_bh(bh);
if (!buffer_mapped(bh))
@@ -2623,7 +2622,7 @@ static int reiserfs_write_full_page(struct page *page,
lock_buffer(bh);
} else {
if (!trylock_buffer(bh)) {
- redirty_page_for_writepage(wbc, page);
+ folio_redirty_for_writepage(wbc, folio);
continue;
}
}
@@ -2640,13 +2639,13 @@ static int reiserfs_write_full_page(struct page *page,
if (error)
goto fail;
}
- BUG_ON(PageWriteback(page));
- set_page_writeback(page);
- unlock_page(page);
+ BUG_ON(folio_test_writeback(folio));
+ folio_start_writeback(folio);
+ folio_unlock(folio);
/*
- * since any buffer might be the only dirty buffer on the page,
- * the first submit_bh can bring the page out of writeback.
+ * since any buffer might be the only dirty buffer on the folio,
+ * the first submit_bh can bring the folio out of writeback.
* be careful with the buffers.
*/
do {
@@ -2663,10 +2662,10 @@ static int reiserfs_write_full_page(struct page *page,
done:
if (nr == 0) {
/*
- * if this page only had a direct item, it is very possible for
+ * if this folio only had a direct item, it is very possible for
* no io to be required without there being an error. Or,
* someone else could have locked them and sent them down the
- * pipe without locking the page
+ * pipe without locking the folio
*/
bh = head;
do {
@@ -2677,18 +2676,18 @@ static int reiserfs_write_full_page(struct page *page,
bh = bh->b_this_page;
} while (bh != head);
if (!partial)
- SetPageUptodate(page);
- end_page_writeback(page);
+ folio_mark_uptodate(folio);
+ folio_end_writeback(folio);
}
return error;
fail:
/*
* catches various errors, we need to make sure any valid dirty blocks
- * get to the media. The page is currently locked and not marked for
+ * get to the media. The folio is currently locked and not marked for
* writeback
*/
- ClearPageUptodate(page);
+ folio_clear_uptodate(folio);
bh = head;
do {
get_bh(bh);
@@ -2698,16 +2697,16 @@ static int reiserfs_write_full_page(struct page *page,
} else {
/*
* clear any dirty bits that might have come from
- * getting attached to a dirty page
+ * getting attached to a dirty folio
*/
clear_buffer_dirty(bh);
}
bh = bh->b_this_page;
} while (bh != head);
- SetPageError(page);
- BUG_ON(PageWriteback(page));
- set_page_writeback(page);
- unlock_page(page);
+ folio_set_error(folio);
+ BUG_ON(folio_test_writeback(folio));
+ folio_start_writeback(folio);
+ folio_unlock(folio);
do {
struct buffer_head *next = bh->b_this_page;
if (buffer_async_write(bh)) {
@@ -2728,9 +2727,10 @@ static int reiserfs_read_folio(struct file *f, struct folio *folio)
static int reiserfs_writepage(struct page *page, struct writeback_control *wbc)
{
- struct inode *inode = page->mapping->host;
+ struct folio *folio = page_folio(page);
+ struct inode *inode = folio->mapping->host;
reiserfs_wait_on_write_block(inode->i_sb);
- return reiserfs_write_full_page(page, wbc);
+ return reiserfs_write_full_folio(folio, wbc);
}
static void reiserfs_truncate_failed_write(struct inode *inode)
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 22/26] ufs: Add ufs_get_locked_folio and ufs_put_locked_folio
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
` (7 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 21/26] reiserfs: Convert writepage " Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 23/26] ufs: Use ufs_get_locked_folio() in ufs_alloc_lastblock() Matthew Wilcox (Oracle)
9 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
gfs2-cunTk1MwBs/YUNznpcFYbw, linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
Convert the _page variants to call them. Saves a few hidden calls to
compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
---
fs/ufs/util.c | 43 +++++++++++++++++++++++++------------------
fs/ufs/util.h | 13 +++++++++----
2 files changed, 34 insertions(+), 22 deletions(-)
diff --git a/fs/ufs/util.c b/fs/ufs/util.c
index 08ddf41eaaad..151b400cb3b6 100644
--- a/fs/ufs/util.c
+++ b/fs/ufs/util.c
@@ -229,43 +229,50 @@ ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev
ufsi->i_u1.i_data[0] = cpu_to_fs32(sb, fs32);
}
+struct page *ufs_get_locked_page(struct address_space *mapping, pgoff_t index)
+{
+ struct folio *folio = ufs_get_locked_folio(mapping, index);
+
+ if (folio)
+ return folio_file_page(folio, index);
+ return NULL;
+}
+
/**
- * ufs_get_locked_page() - locate, pin and lock a pagecache page, if not exist
+ * ufs_get_locked_folio() - locate, pin and lock a pagecache folio, if not exist
* read it from disk.
* @mapping: the address_space to search
* @index: the page index
*
- * Locates the desired pagecache page, if not exist we'll read it,
+ * Locates the desired pagecache folio, if not exist we'll read it,
* locks it, increments its reference
* count and returns its address.
*
*/
-
-struct page *ufs_get_locked_page(struct address_space *mapping,
+struct folio *ufs_get_locked_folio(struct address_space *mapping,
pgoff_t index)
{
struct inode *inode = mapping->host;
- struct page *page = find_lock_page(mapping, index);
- if (!page) {
- page = read_mapping_page(mapping, index, NULL);
+ struct folio *folio = filemap_lock_folio(mapping, index);
+ if (!folio) {
+ folio = read_mapping_folio(mapping, index, NULL);
- if (IS_ERR(page)) {
- printk(KERN_ERR "ufs_change_blocknr: "
- "read_mapping_page error: ino %lu, index: %lu\n",
+ if (IS_ERR(folio)) {
+ printk(KERN_ERR "ufs_change_blocknr: read_mapping_folio error: ino %lu, index: %lu\n",
mapping->host->i_ino, index);
- return page;
+ return folio;
}
- lock_page(page);
+ folio_lock(folio);
- if (unlikely(page->mapping == NULL)) {
+ if (unlikely(folio->mapping == NULL)) {
/* Truncate got there first */
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
return NULL;
}
}
- if (!page_has_buffers(page))
- create_empty_buffers(page, 1 << inode->i_blkbits, 0);
- return page;
+ if (!folio_buffers(folio))
+ folio_create_empty_buffers(folio, 1 << inode->i_blkbits, 0);
+ return folio;
}
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 89247193d96d..62542561d150 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -273,12 +273,17 @@ extern void _ubh_ubhcpymem_(struct ufs_sb_private_info *, unsigned char *, struc
extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head *, unsigned char *, unsigned);
/* This functions works with cache pages*/
-extern struct page *ufs_get_locked_page(struct address_space *mapping,
- pgoff_t index);
+struct page *ufs_get_locked_page(struct address_space *mapping, pgoff_t index);
+struct folio *ufs_get_locked_folio(struct address_space *mapping, pgoff_t index);
+static inline void ufs_put_locked_folio(struct folio *folio)
+{
+ folio_unlock(folio);
+ folio_put(folio);
+}
+
static inline void ufs_put_locked_page(struct page *page)
{
- unlock_page(page);
- put_page(page);
+ ufs_put_locked_folio(page_folio(page));
}
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 23/26] ufs: Use ufs_get_locked_folio() in ufs_alloc_lastblock()
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
` (8 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 22/26] ufs: Add ufs_get_locked_folio and ufs_put_locked_folio Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
9 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
gfs2-cunTk1MwBs/YUNznpcFYbw, linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
Switch to the folio APIs, saving one folio->page->folio conversion.
Signed-off-by: Matthew Wilcox (Oracle) <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
---
fs/ufs/inode.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 21a4779a2de5..5b289374d4fd 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -1057,7 +1057,7 @@ static int ufs_alloc_lastblock(struct inode *inode, loff_t size)
struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
unsigned i, end;
sector_t lastfrag;
- struct page *lastpage;
+ struct folio *folio;
struct buffer_head *bh;
u64 phys64;
@@ -1068,18 +1068,17 @@ static int ufs_alloc_lastblock(struct inode *inode, loff_t size)
lastfrag--;
- lastpage = ufs_get_locked_page(mapping, lastfrag >>
+ folio = ufs_get_locked_folio(mapping, lastfrag >>
(PAGE_SHIFT - inode->i_blkbits));
- if (IS_ERR(lastpage)) {
- err = -EIO;
- goto out;
- }
-
- end = lastfrag & ((1 << (PAGE_SHIFT - inode->i_blkbits)) - 1);
- bh = page_buffers(lastpage);
- for (i = 0; i < end; ++i)
- bh = bh->b_this_page;
+ if (IS_ERR(folio)) {
+ err = -EIO;
+ goto out;
+ }
+ end = lastfrag & ((1 << (PAGE_SHIFT - inode->i_blkbits)) - 1);
+ bh = folio_buffers(folio);
+ for (i = 0; i < end; ++i)
+ bh = bh->b_this_page;
err = ufs_getfrag_block(inode, lastfrag, bh, 1);
@@ -1095,7 +1094,7 @@ static int ufs_alloc_lastblock(struct inode *inode, loff_t size)
*/
set_buffer_uptodate(bh);
mark_buffer_dirty(bh);
- set_page_dirty(lastpage);
+ folio_mark_dirty(folio);
}
if (lastfrag >= UFS_IND_FRAGMENT) {
@@ -1113,7 +1112,7 @@ static int ufs_alloc_lastblock(struct inode *inode, loff_t size)
}
}
out_unlock:
- ufs_put_locked_page(lastpage);
+ ufs_put_locked_folio(folio);
out:
return err;
}
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH 07/26] gfs2; Convert gfs2_getjdatabuf to use a folio
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (3 preceding siblings ...)
[not found] ` <20230919045135.3635437-1-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 22:27 ` Andreas Gruenbacher
2023-09-19 4:51 ` [PATCH 10/26] nilfs2: Convert nilfs_grab_buffer() " Matthew Wilcox (Oracle)
` (11 subsequent siblings)
16 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Use the folio APIs, saving four hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/gfs2/meta_io.c | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index f1fac1b45059..b28196015543 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -400,26 +400,20 @@ static struct buffer_head *gfs2_getjdatabuf(struct gfs2_inode *ip, u64 blkno)
{
struct address_space *mapping = ip->i_inode.i_mapping;
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
- struct page *page;
+ struct folio *folio;
struct buffer_head *bh;
unsigned int shift = PAGE_SHIFT - sdp->sd_sb.sb_bsize_shift;
unsigned long index = blkno >> shift; /* convert block to page */
unsigned int bufnum = blkno - (index << shift);
- page = find_get_page_flags(mapping, index, FGP_LOCK|FGP_ACCESSED);
- if (!page)
- return NULL;
- if (!page_has_buffers(page)) {
- unlock_page(page);
- put_page(page);
+ folio = __filemap_get_folio(mapping, index, FGP_LOCK | FGP_ACCESSED, 0);
+ if (IS_ERR(folio))
return NULL;
- }
- /* Locate header for our buffer within our page */
- for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page)
- /* Do nothing */;
- get_bh(bh);
- unlock_page(page);
- put_page(page);
+ bh = folio_buffers(folio);
+ if (bh)
+ get_nth_bh(bh, bufnum);
+ folio_unlock(folio);
+ folio_put(folio);
return bh;
}
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* Re: [PATCH 07/26] gfs2; Convert gfs2_getjdatabuf to use a folio
2023-09-19 4:51 ` [PATCH 07/26] gfs2; Convert gfs2_getjdatabuf to use a folio Matthew Wilcox (Oracle)
@ 2023-09-19 22:27 ` Andreas Gruenbacher
[not found] ` <CAHc6FU4-RSAsc-LWw2OuLDecofapd30OZhxyjVKLXzJNwh-ZoA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 46+ messages in thread
From: Andreas Gruenbacher @ 2023-09-19 22:27 UTC (permalink / raw)
To: Matthew Wilcox (Oracle)
Cc: Andrew Morton, linux-fsdevel, gfs2, linux-nilfs, linux-ntfs-dev,
ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4, Pankaj Raghav
Thanks,
but this patch has an unwanted semicolon in the subject.
On Tue, Sep 19, 2023 at 7:00 AM Matthew Wilcox (Oracle)
<willy@infradead.org> wrote:
>
> Use the folio APIs, saving four hidden calls to compound_head().
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> fs/gfs2/meta_io.c | 22 ++++++++--------------
> 1 file changed, 8 insertions(+), 14 deletions(-)
>
> diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
> index f1fac1b45059..b28196015543 100644
> --- a/fs/gfs2/meta_io.c
> +++ b/fs/gfs2/meta_io.c
> @@ -400,26 +400,20 @@ static struct buffer_head *gfs2_getjdatabuf(struct gfs2_inode *ip, u64 blkno)
> {
> struct address_space *mapping = ip->i_inode.i_mapping;
> struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
> - struct page *page;
> + struct folio *folio;
> struct buffer_head *bh;
> unsigned int shift = PAGE_SHIFT - sdp->sd_sb.sb_bsize_shift;
> unsigned long index = blkno >> shift; /* convert block to page */
> unsigned int bufnum = blkno - (index << shift);
>
> - page = find_get_page_flags(mapping, index, FGP_LOCK|FGP_ACCESSED);
> - if (!page)
> - return NULL;
> - if (!page_has_buffers(page)) {
> - unlock_page(page);
> - put_page(page);
> + folio = __filemap_get_folio(mapping, index, FGP_LOCK | FGP_ACCESSED, 0);
> + if (IS_ERR(folio))
> return NULL;
> - }
> - /* Locate header for our buffer within our page */
> - for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page)
> - /* Do nothing */;
> - get_bh(bh);
> - unlock_page(page);
> - put_page(page);
> + bh = folio_buffers(folio);
> + if (bh)
> + get_nth_bh(bh, bufnum);
And we need this here:
bh = get_nth_bh(bh, bufnum);
> + folio_unlock(folio);
> + folio_put(folio);
> return bh;
> }
>
> --
> 2.40.1
>
>
Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com>
^ permalink raw reply [flat|nested] 46+ messages in thread
* [PATCH 10/26] nilfs2: Convert nilfs_grab_buffer() to use a folio
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (4 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 07/26] gfs2; Convert gfs2_getjdatabuf to use a folio Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
[not found] ` <20230919045135.3635437-11-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2023-09-19 4:51 ` [PATCH 11/26] nilfs2: Convert nilfs_copy_page() to nilfs_copy_folio() Matthew Wilcox (Oracle)
` (10 subsequent siblings)
16 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Remove a number of folio->page->folio conversions.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/page.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index b4e54d079b7d..1c075bd906c9 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -25,19 +25,19 @@
(BIT(BH_Uptodate) | BIT(BH_Mapped) | BIT(BH_NILFS_Node) | \
BIT(BH_NILFS_Volatile) | BIT(BH_NILFS_Checked))
-static struct buffer_head *
-__nilfs_get_page_block(struct page *page, unsigned long block, pgoff_t index,
- int blkbits, unsigned long b_state)
+static struct buffer_head *__nilfs_get_folio_block(struct folio *folio,
+ unsigned long block, pgoff_t index, int blkbits,
+ unsigned long b_state)
{
unsigned long first_block;
- struct buffer_head *bh;
+ struct buffer_head *bh = folio_buffers(folio);
- if (!page_has_buffers(page))
- create_empty_buffers(page, 1 << blkbits, b_state);
+ if (!bh)
+ bh = folio_create_empty_buffers(folio, 1 << blkbits, b_state);
first_block = (unsigned long)index << (PAGE_SHIFT - blkbits);
- bh = nilfs_page_get_nth_block(page, block - first_block);
+ bh = get_nth_bh(bh, block - first_block);
touch_buffer(bh);
wait_on_buffer(bh);
@@ -51,17 +51,17 @@ struct buffer_head *nilfs_grab_buffer(struct inode *inode,
{
int blkbits = inode->i_blkbits;
pgoff_t index = blkoff >> (PAGE_SHIFT - blkbits);
- struct page *page;
+ struct folio *folio;
struct buffer_head *bh;
- page = grab_cache_page(mapping, index);
- if (unlikely(!page))
+ folio = filemap_grab_folio(mapping, index);
+ if (IS_ERR(folio))
return NULL;
- bh = __nilfs_get_page_block(page, blkoff, index, blkbits, b_state);
+ bh = __nilfs_get_folio_block(folio, blkoff, index, blkbits, b_state);
if (unlikely(!bh)) {
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
return NULL;
}
return bh;
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 11/26] nilfs2: Convert nilfs_copy_page() to nilfs_copy_folio()
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (5 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 10/26] nilfs2: Convert nilfs_grab_buffer() " Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 13:01 ` Ryusuke Konishi
` (2 more replies)
2023-09-19 4:51 ` [PATCH 12/26] nilfs2: Convert nilfs_mdt_forget_block() to use a folio Matthew Wilcox (Oracle)
` (9 subsequent siblings)
16 siblings, 3 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Both callers already have a folio, so pass it in and use it directly.
Removes a lot of hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/page.c | 50 +++++++++++++++++++++++++-----------------------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 1c075bd906c9..696215d899bf 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -184,30 +184,32 @@ void nilfs_page_bug(struct page *page)
}
/**
- * nilfs_copy_page -- copy the page with buffers
- * @dst: destination page
- * @src: source page
- * @copy_dirty: flag whether to copy dirty states on the page's buffer heads.
+ * nilfs_copy_folio -- copy the folio with buffers
+ * @dst: destination folio
+ * @src: source folio
+ * @copy_dirty: flag whether to copy dirty states on the folio's buffer heads.
*
- * This function is for both data pages and btnode pages. The dirty flag
- * should be treated by caller. The page must not be under i/o.
- * Both src and dst page must be locked
+ * This function is for both data folios and btnode folios. The dirty flag
+ * should be treated by caller. The folio must not be under i/o.
+ * Both src and dst folio must be locked
*/
-static void nilfs_copy_page(struct page *dst, struct page *src, int copy_dirty)
+static void nilfs_copy_folio(struct folio *dst, struct folio *src,
+ bool copy_dirty)
{
struct buffer_head *dbh, *dbufs, *sbh;
unsigned long mask = NILFS_BUFFER_INHERENT_BITS;
- BUG_ON(PageWriteback(dst));
+ BUG_ON(folio_test_writeback(dst));
- sbh = page_buffers(src);
- if (!page_has_buffers(dst))
- create_empty_buffers(dst, sbh->b_size, 0);
+ sbh = folio_buffers(src);
+ dbh = folio_buffers(dst);
+ if (!dbh)
+ dbh = folio_create_empty_buffers(dst, sbh->b_size, 0);
if (copy_dirty)
mask |= BIT(BH_Dirty);
- dbh = dbufs = page_buffers(dst);
+ dbufs = dbh;
do {
lock_buffer(sbh);
lock_buffer(dbh);
@@ -218,16 +220,16 @@ static void nilfs_copy_page(struct page *dst, struct page *src, int copy_dirty)
dbh = dbh->b_this_page;
} while (dbh != dbufs);
- copy_highpage(dst, src);
+ folio_copy(dst, src);
- if (PageUptodate(src) && !PageUptodate(dst))
- SetPageUptodate(dst);
- else if (!PageUptodate(src) && PageUptodate(dst))
- ClearPageUptodate(dst);
- if (PageMappedToDisk(src) && !PageMappedToDisk(dst))
- SetPageMappedToDisk(dst);
- else if (!PageMappedToDisk(src) && PageMappedToDisk(dst))
- ClearPageMappedToDisk(dst);
+ if (folio_test_uptodate(src) && !folio_test_uptodate(dst))
+ folio_mark_uptodate(dst);
+ else if (!folio_test_uptodate(src) && folio_test_uptodate(dst))
+ folio_clear_uptodate(dst);
+ if (folio_test_mappedtodisk(src) && !folio_test_mappedtodisk(dst))
+ folio_set_mappedtodisk(dst);
+ else if (!folio_test_mappedtodisk(src) && folio_test_mappedtodisk(dst))
+ folio_clear_mappedtodisk(dst);
do {
unlock_buffer(sbh);
@@ -269,7 +271,7 @@ int nilfs_copy_dirty_pages(struct address_space *dmap,
NILFS_PAGE_BUG(&folio->page,
"found empty page in dat page cache");
- nilfs_copy_page(&dfolio->page, &folio->page, 1);
+ nilfs_copy_folio(dfolio, folio, true);
filemap_dirty_folio(folio_mapping(dfolio), dfolio);
folio_unlock(dfolio);
@@ -314,7 +316,7 @@ void nilfs_copy_back_pages(struct address_space *dmap,
if (!IS_ERR(dfolio)) {
/* overwrite existing folio in the destination cache */
WARN_ON(folio_test_dirty(dfolio));
- nilfs_copy_page(&dfolio->page, &folio->page, 0);
+ nilfs_copy_folio(dfolio, folio, false);
folio_unlock(dfolio);
folio_put(dfolio);
/* Do we not need to remove folio from smap here? */
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* Re: [PATCH 11/26] nilfs2: Convert nilfs_copy_page() to nilfs_copy_folio()
2023-09-19 4:51 ` [PATCH 11/26] nilfs2: Convert nilfs_copy_page() to nilfs_copy_folio() Matthew Wilcox (Oracle)
@ 2023-09-19 13:01 ` Ryusuke Konishi
[not found] ` <CAKFNMonjfsWBageg6vfWok9vvNEzjhXiqCCb+=cDFuwnTER95A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
[not found] ` <20230919045135.3635437-12-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2023-09-20 5:47 ` Ryusuke Konishi
2 siblings, 1 reply; 46+ messages in thread
From: Ryusuke Konishi @ 2023-09-19 13:01 UTC (permalink / raw)
To: Matthew Wilcox (Oracle)
Cc: Andrew Morton, linux-fsdevel, gfs2, linux-nilfs, linux-ntfs-dev,
ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4, Pankaj Raghav
Hi,
On Tue, Sep 19, 2023 at 1:56 PM Matthew Wilcox (Oracle) wrote:
>
> Both callers already have a folio, so pass it in and use it directly.
> Removes a lot of hidden calls to compound_head().
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> fs/nilfs2/page.c | 50 +++++++++++++++++++++++++-----------------------
> 1 file changed, 26 insertions(+), 24 deletions(-)
>
> diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
> index 1c075bd906c9..696215d899bf 100644
> --- a/fs/nilfs2/page.c
> +++ b/fs/nilfs2/page.c
> @@ -184,30 +184,32 @@ void nilfs_page_bug(struct page *page)
> }
>
> /**
> - * nilfs_copy_page -- copy the page with buffers
> - * @dst: destination page
> - * @src: source page
> - * @copy_dirty: flag whether to copy dirty states on the page's buffer heads.
> + * nilfs_copy_folio -- copy the folio with buffers
> + * @dst: destination folio
> + * @src: source folio
> + * @copy_dirty: flag whether to copy dirty states on the folio's buffer heads.
> *
> - * This function is for both data pages and btnode pages. The dirty flag
> - * should be treated by caller. The page must not be under i/o.
> - * Both src and dst page must be locked
> + * This function is for both data folios and btnode folios. The dirty flag
> + * should be treated by caller. The folio must not be under i/o.
> + * Both src and dst folio must be locked
> */
> -static void nilfs_copy_page(struct page *dst, struct page *src, int copy_dirty)
> +static void nilfs_copy_folio(struct folio *dst, struct folio *src,
> + bool copy_dirty)
> {
> struct buffer_head *dbh, *dbufs, *sbh;
> unsigned long mask = NILFS_BUFFER_INHERENT_BITS;
>
> - BUG_ON(PageWriteback(dst));
> + BUG_ON(folio_test_writeback(dst));
>
> - sbh = page_buffers(src);
> - if (!page_has_buffers(dst))
> - create_empty_buffers(dst, sbh->b_size, 0);
> + sbh = folio_buffers(src);
> + dbh = folio_buffers(dst);
> + if (!dbh)
> + dbh = folio_create_empty_buffers(dst, sbh->b_size, 0);
>
> if (copy_dirty)
> mask |= BIT(BH_Dirty);
>
> - dbh = dbufs = page_buffers(dst);
> + dbufs = dbh;
> do {
> lock_buffer(sbh);
> lock_buffer(dbh);
> @@ -218,16 +220,16 @@ static void nilfs_copy_page(struct page *dst, struct page *src, int copy_dirty)
> dbh = dbh->b_this_page;
> } while (dbh != dbufs);
>
> - copy_highpage(dst, src);
> + folio_copy(dst, src);
>
> - if (PageUptodate(src) && !PageUptodate(dst))
> - SetPageUptodate(dst);
> - else if (!PageUptodate(src) && PageUptodate(dst))
> - ClearPageUptodate(dst);
> - if (PageMappedToDisk(src) && !PageMappedToDisk(dst))
> - SetPageMappedToDisk(dst);
> - else if (!PageMappedToDisk(src) && PageMappedToDisk(dst))
> - ClearPageMappedToDisk(dst);
> + if (folio_test_uptodate(src) && !folio_test_uptodate(dst))
> + folio_mark_uptodate(dst);
> + else if (!folio_test_uptodate(src) && folio_test_uptodate(dst))
> + folio_clear_uptodate(dst);
> + if (folio_test_mappedtodisk(src) && !folio_test_mappedtodisk(dst))
> + folio_set_mappedtodisk(dst);
> + else if (!folio_test_mappedtodisk(src) && folio_test_mappedtodisk(dst))
> + folio_clear_mappedtodisk(dst);
>
> do {
> unlock_buffer(sbh);
> @@ -269,7 +271,7 @@ int nilfs_copy_dirty_pages(struct address_space *dmap,
> NILFS_PAGE_BUG(&folio->page,
> "found empty page in dat page cache");
>
> - nilfs_copy_page(&dfolio->page, &folio->page, 1);
> + nilfs_copy_folio(dfolio, folio, true);
> filemap_dirty_folio(folio_mapping(dfolio), dfolio);
>
> folio_unlock(dfolio);
> @@ -314,7 +316,7 @@ void nilfs_copy_back_pages(struct address_space *dmap,
> if (!IS_ERR(dfolio)) {
> /* overwrite existing folio in the destination cache */
> WARN_ON(folio_test_dirty(dfolio));
> - nilfs_copy_page(&dfolio->page, &folio->page, 0);
> + nilfs_copy_folio(dfolio, folio, false);
> folio_unlock(dfolio);
> folio_put(dfolio);
> /* Do we not need to remove folio from smap here? */
> --
> 2.40.1
When I tried to test the patchset against 6.6-rc2, I encountered the
following error during the build:
ERROR: modpost: "folio_copy" [fs/nilfs2/nilfs2.ko] undefined!
It looks like "folio_copy" is not exported to modules.
I'll correct this manually for now and proceed with the review and
testing, but could you please fix this build issue in some way ?
Thanks,
Ryusuke Konishi
^ permalink raw reply [flat|nested] 46+ messages in thread[parent not found: <20230919045135.3635437-12-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>]
* Re: [PATCH 11/26] nilfs2: Convert nilfs_copy_page() to nilfs_copy_folio()
[not found] ` <20230919045135.3635437-12-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
@ 2023-09-19 18:59 ` kernel test robot
0 siblings, 0 replies; 46+ messages in thread
From: kernel test robot @ 2023-09-19 18:59 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), Andrew Morton
Cc: oe-kbuild-all-cunTk1MwBs/YUNznpcFYbw,
Linux Memory Management List, Matthew Wilcox (Oracle),
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, gfs2-cunTk1MwBs/YUNznpcFYbw,
linux-nilfs-u79uwXL29TY76Z2rM5mHXA,
linux-ntfs-dev-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
ntfs3-cunTk1MwBs/YUNznpcFYbw, ocfs2-devel-cunTk1MwBs/YUNznpcFYbw,
reiserfs-devel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, Pankaj Raghav
Hi Matthew,
kernel test robot noticed the following build errors:
[auto build test ERROR on next-20230918]
[also build test ERROR on v6.6-rc2]
[cannot apply to konis-nilfs2/upstream gfs2/for-next tytso-ext4/dev linus/master v6.6-rc2 v6.6-rc1 v6.5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/buffer-Make-folio_create_empty_buffers-return-a-buffer_head/20230919-125330
base: next-20230918
patch link: https://lore.kernel.org/r/20230919045135.3635437-12-willy%40infradead.org
patch subject: [PATCH 11/26] nilfs2: Convert nilfs_copy_page() to nilfs_copy_folio()
config: s390-defconfig (https://download.01.org/0day-ci/archive/20230920/202309200252.NpD8SUsn-lkp-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org/config)
compiler: s390-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230920/202309200252.NpD8SUsn-lkp-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309200252.NpD8SUsn-lkp-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org/
All errors (new ones prefixed by >>, old ones prefixed by <<):
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/net/amt.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/net/macvtap.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/net/tap.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/net/ppp/ppp_generic.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/net/ppp/ppp_async.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/net/ppp/bsd_comp.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/net/ppp/ppp_deflate.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/net/ppp/ppp_synctty.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/net/slip/slhc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/cdrom/cdrom.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/s390/cio/vfio_ccw.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/s390/block/dcssblk.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/s390/net/lcs.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/802/garp.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/act_gate.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_htb.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_hfsc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_red.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_gred.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_ingress.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_sfq.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_tbf.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_teql.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_prio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_multiq.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_netem.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_drr.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_plug.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_ets.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_mqprio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_mqprio_lib.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_choke.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/sch_qfq.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/cls_u32.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/cls_route.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/cls_fw.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sched/cls_basic.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netlink/netlink_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/nfnetlink_osf.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/nf_conntrack.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/nf_conntrack_netlink.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/nf_conntrack_broadcast.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/nf_nat.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/nf_tables.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/nft_fib.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/nft_chain_nat.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_rr.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_wrr.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_lc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_wlc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_lblc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_lblcr.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_dh.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_sh.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_sed.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_nq.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_twos.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_ftp.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/netfilter/ipvs/ip_vs_pe_sip.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/netfilter/nf_defrag_ipv4.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/netfilter/nf_reject_ipv4.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/netfilter/iptable_nat.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/netfilter/iptable_raw.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/ip_tunnel.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/ipip.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/ip_gre.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/udp_tunnel.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/ip_vti.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/ah4.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/esp4.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/xfrm4_tunnel.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/tunnel4.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/inet_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/tcp_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv4/udp_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/xfrm/xfrm_algo.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/xfrm/xfrm_user.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/unix/unix_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/netfilter/ip6table_raw.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/netfilter/ip6table_nat.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/netfilter/nf_defrag_ipv6.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/netfilter/nf_reject_ipv6.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/ah6.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/esp6.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/xfrm6_tunnel.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/tunnel6.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/mip6.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/sit.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/ipv6/ip6_udp_tunnel.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/packet/af_packet_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/8021q/8021q.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/mptcp/mptcp_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/key/af_key.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sunrpc/sunrpc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sunrpc/auth_gss/auth_rpcgss.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sunrpc/auth_gss/rpcsec_gss_krb5.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/sctp/sctp_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/smc/smc_diag.o
WARNING: modpost: missing MODULE_DESCRIPTION() in net/vmw_vsock/vsock_diag.o
>> ERROR: modpost: "folio_copy" [fs/nilfs2/nilfs2.ko] undefined!
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH 11/26] nilfs2: Convert nilfs_copy_page() to nilfs_copy_folio()
2023-09-19 4:51 ` [PATCH 11/26] nilfs2: Convert nilfs_copy_page() to nilfs_copy_folio() Matthew Wilcox (Oracle)
2023-09-19 13:01 ` Ryusuke Konishi
[not found] ` <20230919045135.3635437-12-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
@ 2023-09-20 5:47 ` Ryusuke Konishi
2 siblings, 0 replies; 46+ messages in thread
From: Ryusuke Konishi @ 2023-09-20 5:47 UTC (permalink / raw)
To: Matthew Wilcox (Oracle)
Cc: Andrew Morton, linux-fsdevel, gfs2, linux-nilfs, linux-ntfs-dev,
ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4, Pankaj Raghav
On Tue, Sep 19, 2023 at 1:56 PM Matthew Wilcox (Oracle) wrote:
>
> Both callers already have a folio, so pass it in and use it directly.
> Removes a lot of hidden calls to compound_head().
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> fs/nilfs2/page.c | 50 +++++++++++++++++++++++++-----------------------
> 1 file changed, 26 insertions(+), 24 deletions(-)
>
> diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
> index 1c075bd906c9..696215d899bf 100644
> --- a/fs/nilfs2/page.c
> +++ b/fs/nilfs2/page.c
> @@ -184,30 +184,32 @@ void nilfs_page_bug(struct page *page)
> }
>
> /**
> - * nilfs_copy_page -- copy the page with buffers
> - * @dst: destination page
> - * @src: source page
> - * @copy_dirty: flag whether to copy dirty states on the page's buffer heads.
> + * nilfs_copy_folio -- copy the folio with buffers
> + * @dst: destination folio
> + * @src: source folio
> + * @copy_dirty: flag whether to copy dirty states on the folio's buffer heads.
> *
> - * This function is for both data pages and btnode pages. The dirty flag
> - * should be treated by caller. The page must not be under i/o.
> - * Both src and dst page must be locked
> + * This function is for both data folios and btnode folios. The dirty flag
> + * should be treated by caller. The folio must not be under i/o.
> + * Both src and dst folio must be locked
> */
> -static void nilfs_copy_page(struct page *dst, struct page *src, int copy_dirty)
> +static void nilfs_copy_folio(struct folio *dst, struct folio *src,
> + bool copy_dirty)
> {
> struct buffer_head *dbh, *dbufs, *sbh;
> unsigned long mask = NILFS_BUFFER_INHERENT_BITS;
>
> - BUG_ON(PageWriteback(dst));
> + BUG_ON(folio_test_writeback(dst));
>
> - sbh = page_buffers(src);
> - if (!page_has_buffers(dst))
> - create_empty_buffers(dst, sbh->b_size, 0);
> + sbh = folio_buffers(src);
> + dbh = folio_buffers(dst);
> + if (!dbh)
> + dbh = folio_create_empty_buffers(dst, sbh->b_size, 0);
>
> if (copy_dirty)
> mask |= BIT(BH_Dirty);
>
> - dbh = dbufs = page_buffers(dst);
> + dbufs = dbh;
> do {
> lock_buffer(sbh);
> lock_buffer(dbh);
> @@ -218,16 +220,16 @@ static void nilfs_copy_page(struct page *dst, struct page *src, int copy_dirty)
> dbh = dbh->b_this_page;
> } while (dbh != dbufs);
>
> - copy_highpage(dst, src);
> + folio_copy(dst, src);
>
> - if (PageUptodate(src) && !PageUptodate(dst))
> - SetPageUptodate(dst);
> - else if (!PageUptodate(src) && PageUptodate(dst))
> - ClearPageUptodate(dst);
> - if (PageMappedToDisk(src) && !PageMappedToDisk(dst))
> - SetPageMappedToDisk(dst);
> - else if (!PageMappedToDisk(src) && PageMappedToDisk(dst))
> - ClearPageMappedToDisk(dst);
> + if (folio_test_uptodate(src) && !folio_test_uptodate(dst))
> + folio_mark_uptodate(dst);
> + else if (!folio_test_uptodate(src) && folio_test_uptodate(dst))
> + folio_clear_uptodate(dst);
> + if (folio_test_mappedtodisk(src) && !folio_test_mappedtodisk(dst))
> + folio_set_mappedtodisk(dst);
> + else if (!folio_test_mappedtodisk(src) && folio_test_mappedtodisk(dst))
> + folio_clear_mappedtodisk(dst);
>
> do {
> unlock_buffer(sbh);
> @@ -269,7 +271,7 @@ int nilfs_copy_dirty_pages(struct address_space *dmap,
> NILFS_PAGE_BUG(&folio->page,
> "found empty page in dat page cache");
>
> - nilfs_copy_page(&dfolio->page, &folio->page, 1);
> + nilfs_copy_folio(dfolio, folio, true);
> filemap_dirty_folio(folio_mapping(dfolio), dfolio);
>
> folio_unlock(dfolio);
> @@ -314,7 +316,7 @@ void nilfs_copy_back_pages(struct address_space *dmap,
> if (!IS_ERR(dfolio)) {
> /* overwrite existing folio in the destination cache */
> WARN_ON(folio_test_dirty(dfolio));
> - nilfs_copy_page(&dfolio->page, &folio->page, 0);
> + nilfs_copy_folio(dfolio, folio, false);
> folio_unlock(dfolio);
> folio_put(dfolio);
> /* Do we not need to remove folio from smap here? */
> --
> 2.40.1
>
Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Everything else looks fine if the folio_copy symbol is exported.
Thanks,
Ryusuke Konishi
^ permalink raw reply [flat|nested] 46+ messages in thread
* [PATCH 12/26] nilfs2: Convert nilfs_mdt_forget_block() to use a folio
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (6 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 11/26] nilfs2: Convert nilfs_copy_page() to nilfs_copy_folio() Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-20 7:25 ` Ryusuke Konishi
2023-09-19 4:51 ` [PATCH 14/26] nilfs2: Remove nilfs_page_get_nth_block Matthew Wilcox (Oracle)
` (8 subsequent siblings)
16 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Remove a number of folio->page->folio conversions.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/mdt.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index db2260d6e44d..11b7cf4acc92 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -356,30 +356,28 @@ int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)
*/
int nilfs_mdt_forget_block(struct inode *inode, unsigned long block)
{
- pgoff_t index = (pgoff_t)block >>
- (PAGE_SHIFT - inode->i_blkbits);
- struct page *page;
- unsigned long first_block;
+ pgoff_t index = block >> (PAGE_SHIFT - inode->i_blkbits);
+ struct folio *folio;
+ struct buffer_head *bh;
int ret = 0;
int still_dirty;
- page = find_lock_page(inode->i_mapping, index);
- if (!page)
+ folio = filemap_lock_folio(inode->i_mapping, index);
+ if (IS_ERR(folio))
return -ENOENT;
- wait_on_page_writeback(page);
+ folio_wait_writeback(folio);
- first_block = (unsigned long)index <<
- (PAGE_SHIFT - inode->i_blkbits);
- if (page_has_buffers(page)) {
- struct buffer_head *bh;
-
- bh = nilfs_page_get_nth_block(page, block - first_block);
+ bh = folio_buffers(folio);
+ if (bh) {
+ unsigned long first_block = index <<
+ (PAGE_SHIFT - inode->i_blkbits);
+ bh = get_nth_bh(bh, block - first_block);
nilfs_forget_buffer(bh);
}
- still_dirty = PageDirty(page);
- unlock_page(page);
- put_page(page);
+ still_dirty = folio_test_dirty(folio);
+ folio_unlock(folio);
+ folio_put(folio);
if (still_dirty ||
invalidate_inode_pages2_range(inode->i_mapping, index, index) != 0)
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* Re: [PATCH 12/26] nilfs2: Convert nilfs_mdt_forget_block() to use a folio
2023-09-19 4:51 ` [PATCH 12/26] nilfs2: Convert nilfs_mdt_forget_block() to use a folio Matthew Wilcox (Oracle)
@ 2023-09-20 7:25 ` Ryusuke Konishi
0 siblings, 0 replies; 46+ messages in thread
From: Ryusuke Konishi @ 2023-09-20 7:25 UTC (permalink / raw)
To: Matthew Wilcox (Oracle)
Cc: Andrew Morton, linux-fsdevel, gfs2, linux-nilfs, linux-ntfs-dev,
ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4, Pankaj Raghav
On Tue, Sep 19, 2023 at 3:04 PM Matthew Wilcox (Oracle) wrote:
>
> Remove a number of folio->page->folio conversions.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> fs/nilfs2/mdt.c | 30 ++++++++++++++----------------
> 1 file changed, 14 insertions(+), 16 deletions(-)
>
> diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
> index db2260d6e44d..11b7cf4acc92 100644
> --- a/fs/nilfs2/mdt.c
> +++ b/fs/nilfs2/mdt.c
> @@ -356,30 +356,28 @@ int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)
> */
> int nilfs_mdt_forget_block(struct inode *inode, unsigned long block)
> {
> - pgoff_t index = (pgoff_t)block >>
> - (PAGE_SHIFT - inode->i_blkbits);
> - struct page *page;
> - unsigned long first_block;
> + pgoff_t index = block >> (PAGE_SHIFT - inode->i_blkbits);
> + struct folio *folio;
> + struct buffer_head *bh;
> int ret = 0;
> int still_dirty;
>
> - page = find_lock_page(inode->i_mapping, index);
> - if (!page)
> + folio = filemap_lock_folio(inode->i_mapping, index);
> + if (IS_ERR(folio))
> return -ENOENT;
>
> - wait_on_page_writeback(page);
> + folio_wait_writeback(folio);
>
> - first_block = (unsigned long)index <<
> - (PAGE_SHIFT - inode->i_blkbits);
> - if (page_has_buffers(page)) {
> - struct buffer_head *bh;
> -
> - bh = nilfs_page_get_nth_block(page, block - first_block);
> + bh = folio_buffers(folio);
> + if (bh) {
> + unsigned long first_block = index <<
> + (PAGE_SHIFT - inode->i_blkbits);
> + bh = get_nth_bh(bh, block - first_block);
> nilfs_forget_buffer(bh);
> }
> - still_dirty = PageDirty(page);
> - unlock_page(page);
> - put_page(page);
> + still_dirty = folio_test_dirty(folio);
> + folio_unlock(folio);
> + folio_put(folio);
>
> if (still_dirty ||
> invalidate_inode_pages2_range(inode->i_mapping, index, index) != 0)
> --
> 2.40.1
>
Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Looks good to me.
Thanks,
Ryusuke Konishi
^ permalink raw reply [flat|nested] 46+ messages in thread
* [PATCH 14/26] nilfs2: Remove nilfs_page_get_nth_block
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (7 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 12/26] nilfs2: Convert nilfs_mdt_forget_block() to use a folio Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
[not found] ` <20230919045135.3635437-15-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2023-09-19 4:51 ` [PATCH 15/26] nilfs2: Convert nilfs_lookup_dirty_data_buffers to use folio_create_empty_buffers Matthew Wilcox (Oracle)
` (7 subsequent siblings)
16 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
All users have now been converted to get_nth_block().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/page.h | 6 ------
1 file changed, 6 deletions(-)
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
index 344d71942d36..d249ea1cefff 100644
--- a/fs/nilfs2/page.h
+++ b/fs/nilfs2/page.h
@@ -52,10 +52,4 @@ unsigned long nilfs_find_uncommitted_extent(struct inode *inode,
#define NILFS_PAGE_BUG(page, m, a...) \
do { nilfs_page_bug(page); BUG(); } while (0)
-static inline struct buffer_head *
-nilfs_page_get_nth_block(struct page *page, unsigned int count)
-{
- return get_nth_bh(page_buffers(page), count);
-}
-
#endif /* _NILFS_PAGE_H */
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 15/26] nilfs2: Convert nilfs_lookup_dirty_data_buffers to use folio_create_empty_buffers
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (8 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 14/26] nilfs2: Remove nilfs_page_get_nth_block Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
[not found] ` <20230919045135.3635437-16-willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2023-09-19 4:51 ` [PATCH 16/26] ntfs: Convert ntfs_read_block() to use a folio Matthew Wilcox (Oracle)
` (6 subsequent siblings)
16 siblings, 1 reply; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
This function was already using a folio, so this update to the new API
removes a single folio->page->folio conversion.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/segment.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 7ec16879756e..94388fe83cf8 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -731,10 +731,9 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
continue;
}
head = folio_buffers(folio);
- if (!head) {
- create_empty_buffers(&folio->page, i_blocksize(inode), 0);
- head = folio_buffers(folio);
- }
+ if (!head)
+ head = folio_create_empty_buffers(folio,
+ i_blocksize(inode), 0);
folio_unlock(folio);
bh = head;
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 16/26] ntfs: Convert ntfs_read_block() to use a folio
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (9 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 15/26] nilfs2: Convert nilfs_lookup_dirty_data_buffers to use folio_create_empty_buffers Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 18/26] ntfs: Convert ntfs_prepare_pages_for_non_resident_write() to folios Matthew Wilcox (Oracle)
` (5 subsequent siblings)
16 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
The caller already has the folio, so pass it in and use the folio API
throughout saving five hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ntfs/aops.c | 44 +++++++++++++++++++-------------------------
1 file changed, 19 insertions(+), 25 deletions(-)
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 4e158bce4192..d66a9f5ffde9 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -145,13 +145,12 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
}
/**
- * ntfs_read_block - fill a @page of an address space with data
- * @page: page cache page to fill with data
+ * ntfs_read_block - fill a @folio of an address space with data
+ * @folio: page cache folio to fill with data
*
- * Fill the page @page of the address space belonging to the @page->host inode.
* We read each buffer asynchronously and when all buffers are read in, our io
* completion handler ntfs_end_buffer_read_async(), if required, automatically
- * applies the mst fixups to the page before finally marking it uptodate and
+ * applies the mst fixups to the folio before finally marking it uptodate and
* unlocking it.
*
* We only enforce allocated_size limit because i_size is checked for in
@@ -161,7 +160,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
*
* Contains an adapted version of fs/buffer.c::block_read_full_folio().
*/
-static int ntfs_read_block(struct page *page)
+static int ntfs_read_block(struct folio *folio)
{
loff_t i_size;
VCN vcn;
@@ -178,7 +177,7 @@ static int ntfs_read_block(struct page *page)
int i, nr;
unsigned char blocksize_bits;
- vi = page->mapping->host;
+ vi = folio->mapping->host;
ni = NTFS_I(vi);
vol = ni->vol;
@@ -188,15 +187,10 @@ static int ntfs_read_block(struct page *page)
blocksize = vol->sb->s_blocksize;
blocksize_bits = vol->sb->s_blocksize_bits;
- if (!page_has_buffers(page)) {
- create_empty_buffers(page, blocksize, 0);
- if (unlikely(!page_has_buffers(page))) {
- unlock_page(page);
- return -ENOMEM;
- }
- }
- bh = head = page_buffers(page);
- BUG_ON(!bh);
+ head = folio_buffers(folio);
+ if (!head)
+ head = folio_create_empty_buffers(folio, blocksize, 0);
+ bh = head;
/*
* We may be racing with truncate. To avoid some of the problems we
@@ -205,11 +199,11 @@ static int ntfs_read_block(struct page *page)
* may leave some buffers unmapped which are now allocated. This is
* not a problem since these buffers will just get mapped when a write
* occurs. In case of a shrinking truncate, we will detect this later
- * on due to the runlist being incomplete and if the page is being
+ * on due to the runlist being incomplete and if the folio is being
* fully truncated, truncate will throw it away as soon as we unlock
* it so no need to worry what we do with it.
*/
- iblock = (s64)page->index << (PAGE_SHIFT - blocksize_bits);
+ iblock = (s64)folio->index << (PAGE_SHIFT - blocksize_bits);
read_lock_irqsave(&ni->size_lock, flags);
lblock = (ni->allocated_size + blocksize - 1) >> blocksize_bits;
init_size = ni->initialized_size;
@@ -221,7 +215,7 @@ static int ntfs_read_block(struct page *page)
}
zblock = (init_size + blocksize - 1) >> blocksize_bits;
- /* Loop through all the buffers in the page. */
+ /* Loop through all the buffers in the folio. */
rl = NULL;
nr = i = 0;
do {
@@ -299,7 +293,7 @@ static int ntfs_read_block(struct page *page)
if (!err)
err = -EIO;
bh->b_blocknr = -1;
- SetPageError(page);
+ folio_set_error(folio);
ntfs_error(vol->sb, "Failed to read from inode 0x%lx, "
"attribute type 0x%x, vcn 0x%llx, "
"offset 0x%x because its location on "
@@ -312,13 +306,13 @@ static int ntfs_read_block(struct page *page)
/*
* Either iblock was outside lblock limits or
* ntfs_rl_vcn_to_lcn() returned error. Just zero that portion
- * of the page and set the buffer uptodate.
+ * of the folio and set the buffer uptodate.
*/
handle_hole:
bh->b_blocknr = -1UL;
clear_buffer_mapped(bh);
handle_zblock:
- zero_user(page, i * blocksize, blocksize);
+ folio_zero_range(folio, i * blocksize, blocksize);
if (likely(!err))
set_buffer_uptodate(bh);
} while (i++, iblock++, (bh = bh->b_this_page) != head);
@@ -349,11 +343,11 @@ static int ntfs_read_block(struct page *page)
return 0;
}
/* No i/o was scheduled on any of the buffers. */
- if (likely(!PageError(page)))
- SetPageUptodate(page);
+ if (likely(!folio_test_error(folio)))
+ folio_mark_uptodate(folio);
else /* Signal synchronous i/o error. */
nr = -EIO;
- unlock_page(page);
+ folio_unlock(folio);
return nr;
}
@@ -433,7 +427,7 @@ static int ntfs_read_folio(struct file *file, struct folio *folio)
/* NInoNonResident() == NInoIndexAllocPresent() */
if (NInoNonResident(ni)) {
/* Normal, non-resident data stream. */
- return ntfs_read_block(page);
+ return ntfs_read_block(folio);
}
/*
* Attribute is resident, implying it is not compressed or encrypted.
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 18/26] ntfs: Convert ntfs_prepare_pages_for_non_resident_write() to folios
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (10 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 16/26] ntfs: Convert ntfs_read_block() to use a folio Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 19/26] ntfs3: Convert ntfs_zero_range() to use a folio Matthew Wilcox (Oracle)
` (4 subsequent siblings)
16 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Convert each element of the pages array to a folio before using it.
This in no way renders the function large-folio safe, but it does remove
a lot of hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ntfs/file.c | 89 +++++++++++++++++++++++---------------------------
1 file changed, 41 insertions(+), 48 deletions(-)
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index cbc545999cfe..099141d20db6 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -567,7 +567,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
LCN lcn;
s64 bh_pos, vcn_len, end, initialized_size;
sector_t lcn_block;
- struct page *page;
+ struct folio *folio;
struct inode *vi;
ntfs_inode *ni, *base_ni = NULL;
ntfs_volume *vol;
@@ -601,20 +601,6 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
(long long)pos, bytes);
blocksize = vol->sb->s_blocksize;
blocksize_bits = vol->sb->s_blocksize_bits;
- u = 0;
- do {
- page = pages[u];
- BUG_ON(!page);
- /*
- * create_empty_buffers() will create uptodate/dirty buffers if
- * the page is uptodate/dirty.
- */
- if (!page_has_buffers(page)) {
- create_empty_buffers(page, blocksize, 0);
- if (unlikely(!page_has_buffers(page)))
- return -ENOMEM;
- }
- } while (++u < nr_pages);
rl_write_locked = false;
rl = NULL;
err = 0;
@@ -626,14 +612,21 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
end = pos + bytes;
cend = (end + vol->cluster_size - 1) >> vol->cluster_size_bits;
/*
- * Loop over each page and for each page over each buffer. Use goto to
+ * Loop over each buffer in each folio. Use goto to
* reduce indentation.
*/
u = 0;
-do_next_page:
- page = pages[u];
- bh_pos = (s64)page->index << PAGE_SHIFT;
- bh = head = page_buffers(page);
+do_next_folio:
+ folio = page_folio(pages[u]);
+ bh_pos = folio_pos(folio);
+ head = folio_buffers(folio);
+ if (!head)
+ /*
+ * create_empty_buffers() will create uptodate/dirty
+ * buffers if the folio is uptodate/dirty.
+ */
+ head = folio_create_empty_buffers(folio, blocksize, 0);
+ bh = head;
do {
VCN cdelta;
s64 bh_end;
@@ -653,15 +646,15 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
if (buffer_uptodate(bh))
continue;
/*
- * The buffer is not uptodate. If the page is uptodate
+ * The buffer is not uptodate. If the folio is uptodate
* set the buffer uptodate and otherwise ignore it.
*/
- if (PageUptodate(page)) {
+ if (folio_test_uptodate(folio)) {
set_buffer_uptodate(bh);
continue;
}
/*
- * Neither the page nor the buffer are uptodate. If
+ * Neither the folio nor the buffer are uptodate. If
* the buffer is only partially being written to, we
* need to read it in before the write, i.e. now.
*/
@@ -679,7 +672,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
ntfs_submit_bh_for_read(bh);
*wait_bh++ = bh;
} else {
- zero_user(page, bh_offset(bh),
+ folio_zero_range(folio, bh_offset(bh),
blocksize);
set_buffer_uptodate(bh);
}
@@ -706,7 +699,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
(bh_cofs >> blocksize_bits);
set_buffer_mapped(bh);
/*
- * If the page is uptodate so is the buffer. If the
+ * If the folio is uptodate so is the buffer. If the
* buffer is fully outside the write, we ignore it if
* it was already allocated and we mark it dirty so it
* gets written out if we allocated it. On the other
@@ -714,7 +707,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
* marking it dirty we set buffer_new so we can do
* error recovery.
*/
- if (PageUptodate(page)) {
+ if (folio_test_uptodate(folio)) {
if (!buffer_uptodate(bh))
set_buffer_uptodate(bh);
if (unlikely(was_hole)) {
@@ -754,7 +747,8 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
ntfs_submit_bh_for_read(bh);
*wait_bh++ = bh;
} else {
- zero_user(page, bh_offset(bh),
+ folio_zero_range(folio,
+ bh_offset(bh),
blocksize);
set_buffer_uptodate(bh);
}
@@ -773,7 +767,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
*/
if (bh_end <= pos || bh_pos >= end) {
if (!buffer_uptodate(bh)) {
- zero_user(page, bh_offset(bh),
+ folio_zero_range(folio, bh_offset(bh),
blocksize);
set_buffer_uptodate(bh);
}
@@ -786,7 +780,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
u8 *kaddr;
unsigned pofs;
- kaddr = kmap_atomic(page);
+ kaddr = kmap_local_folio(folio, 0);
if (bh_pos < pos) {
pofs = bh_pos & ~PAGE_MASK;
memset(kaddr + pofs, 0, pos - bh_pos);
@@ -795,8 +789,8 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
pofs = end & ~PAGE_MASK;
memset(kaddr + pofs, 0, bh_end - end);
}
- kunmap_atomic(kaddr);
- flush_dcache_page(page);
+ kunmap_local(kaddr);
+ flush_dcache_folio(folio);
}
continue;
}
@@ -809,11 +803,12 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
initialized_size = ni->allocated_size;
read_unlock_irqrestore(&ni->size_lock, flags);
if (bh_pos > initialized_size) {
- if (PageUptodate(page)) {
+ if (folio_test_uptodate(folio)) {
if (!buffer_uptodate(bh))
set_buffer_uptodate(bh);
} else if (!buffer_uptodate(bh)) {
- zero_user(page, bh_offset(bh), blocksize);
+ folio_zero_range(folio, bh_offset(bh),
+ blocksize);
set_buffer_uptodate(bh);
}
continue;
@@ -927,17 +922,17 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
bh->b_blocknr = -1;
/*
* If the buffer is uptodate we skip it. If it
- * is not but the page is uptodate, we can set
- * the buffer uptodate. If the page is not
+ * is not but the folio is uptodate, we can set
+ * the buffer uptodate. If the folio is not
* uptodate, we can clear the buffer and set it
* uptodate. Whether this is worthwhile is
* debatable and this could be removed.
*/
- if (PageUptodate(page)) {
+ if (folio_test_uptodate(folio)) {
if (!buffer_uptodate(bh))
set_buffer_uptodate(bh);
} else if (!buffer_uptodate(bh)) {
- zero_user(page, bh_offset(bh),
+ folio_zero_range(folio, bh_offset(bh),
blocksize);
set_buffer_uptodate(bh);
}
@@ -1167,7 +1162,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
} while (bh_pos += blocksize, (bh = bh->b_this_page) != head);
/* If there are no errors, do the next page. */
if (likely(!err && ++u < nr_pages))
- goto do_next_page;
+ goto do_next_folio;
/* If there are no errors, release the runlist lock if we took it. */
if (likely(!err)) {
if (unlikely(rl_write_locked)) {
@@ -1185,9 +1180,8 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
bh = *--wait_bh;
wait_on_buffer(bh);
if (likely(buffer_uptodate(bh))) {
- page = bh->b_page;
- bh_pos = ((s64)page->index << PAGE_SHIFT) +
- bh_offset(bh);
+ folio = bh->b_folio;
+ bh_pos = folio_pos(folio) + bh_offset(bh);
/*
* If the buffer overflows the initialized size, need
* to zero the overflowing region.
@@ -1197,7 +1191,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
if (likely(bh_pos < initialized_size))
ofs = initialized_size - bh_pos;
- zero_user_segment(page, bh_offset(bh) + ofs,
+ folio_zero_segment(folio, bh_offset(bh) + ofs,
blocksize);
}
} else /* if (unlikely(!buffer_uptodate(bh))) */
@@ -1324,21 +1318,20 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
u = 0;
end = bh_cpos << vol->cluster_size_bits;
do {
- page = pages[u];
- bh = head = page_buffers(page);
+ folio = page_folio(pages[u]);
+ bh = head = folio_buffers(folio);
do {
if (u == nr_pages &&
- ((s64)page->index << PAGE_SHIFT) +
- bh_offset(bh) >= end)
+ folio_pos(folio) + bh_offset(bh) >= end)
break;
if (!buffer_new(bh))
continue;
clear_buffer_new(bh);
if (!buffer_uptodate(bh)) {
- if (PageUptodate(page))
+ if (folio_test_uptodate(folio))
set_buffer_uptodate(bh);
else {
- zero_user(page, bh_offset(bh),
+ folio_zero_range(folio, bh_offset(bh),
blocksize);
set_buffer_uptodate(bh);
}
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 19/26] ntfs3: Convert ntfs_zero_range() to use a folio
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (11 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 18/26] ntfs: Convert ntfs_prepare_pages_for_non_resident_write() to folios Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 20/26] ocfs2: Convert ocfs2_map_page_blocks " Matthew Wilcox (Oracle)
` (3 subsequent siblings)
16 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Use the folio API throughout, saving six hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ntfs3/file.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index 962f12ce6c0a..a003a69091a2 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -187,7 +187,7 @@ static int ntfs_zero_range(struct inode *inode, u64 vbo, u64 vbo_to)
struct buffer_head *head, *bh;
u32 bh_next, bh_off, to;
sector_t iblock;
- struct page *page;
+ struct folio *folio;
for (; idx < idx_end; idx += 1, from = 0) {
page_off = (loff_t)idx << PAGE_SHIFT;
@@ -195,16 +195,17 @@ static int ntfs_zero_range(struct inode *inode, u64 vbo, u64 vbo_to)
PAGE_SIZE;
iblock = page_off >> inode->i_blkbits;
- page = find_or_create_page(mapping, idx,
- mapping_gfp_constraint(mapping,
- ~__GFP_FS));
- if (!page)
- return -ENOMEM;
+ folio = __filemap_get_folio(mapping, idx,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
+ mapping_gfp_constraint(mapping, ~__GFP_FS));
+ if (IS_ERR(folio))
+ return PTR_ERR(folio);
- if (!page_has_buffers(page))
- create_empty_buffers(page, blocksize, 0);
+ head = folio_buffers(folio);
+ if (!head)
+ head = folio_create_empty_buffers(folio, blocksize, 0);
- bh = head = page_buffers(page);
+ bh = head;
bh_off = 0;
do {
bh_next = bh_off + blocksize;
@@ -220,14 +221,14 @@ static int ntfs_zero_range(struct inode *inode, u64 vbo, u64 vbo_to)
}
/* Ok, it's mapped. Make sure it's up-to-date. */
- if (PageUptodate(page))
+ if (folio_test_uptodate(folio))
set_buffer_uptodate(bh);
if (!buffer_uptodate(bh)) {
err = bh_read(bh, 0);
if (err < 0) {
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
goto out;
}
}
@@ -237,10 +238,10 @@ static int ntfs_zero_range(struct inode *inode, u64 vbo, u64 vbo_to)
} while (bh_off = bh_next, iblock += 1,
head != (bh = bh->b_this_page));
- zero_user_segment(page, from, to);
+ folio_zero_segment(folio, from, to);
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
cond_resched();
}
out:
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 20/26] ocfs2: Convert ocfs2_map_page_blocks to use a folio
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (12 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 19/26] ntfs3: Convert ntfs_zero_range() to use a folio Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 24/26] ufs; Convert ufs_change_blocknr() to use folios Matthew Wilcox (Oracle)
` (2 subsequent siblings)
16 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Convert the page argument to a folio and then use the folio APIs
throughout. Replaces three hidden calls to compound_head() with one
explicit one.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 0fdba30740ab..95d1e70b4401 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -568,10 +568,10 @@ static void ocfs2_clear_page_regions(struct page *page,
* read-in the blocks at the tail of our file. Avoid reading them by
* testing i_size against each block offset.
*/
-static int ocfs2_should_read_blk(struct inode *inode, struct page *page,
+static int ocfs2_should_read_blk(struct inode *inode, struct folio *folio,
unsigned int block_start)
{
- u64 offset = page_offset(page) + block_start;
+ u64 offset = folio_pos(folio) + block_start;
if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
return 1;
@@ -593,15 +593,16 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
struct inode *inode, unsigned int from,
unsigned int to, int new)
{
+ struct folio *folio = page_folio(page);
int ret = 0;
struct buffer_head *head, *bh, *wait[2], **wait_bh = wait;
unsigned int block_end, block_start;
unsigned int bsize = i_blocksize(inode);
- if (!page_has_buffers(page))
- create_empty_buffers(page, bsize, 0);
+ head = folio_buffers(folio);
+ if (!head)
+ head = folio_create_empty_buffers(folio, bsize, 0);
- head = page_buffers(page);
for (bh = head, block_start = 0; bh != head || !block_start;
bh = bh->b_this_page, block_start += bsize) {
block_end = block_start + bsize;
@@ -613,7 +614,7 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
* they may belong to unallocated clusters.
*/
if (block_start >= to || block_end <= from) {
- if (PageUptodate(page))
+ if (folio_test_uptodate(folio))
set_buffer_uptodate(bh);
continue;
}
@@ -630,11 +631,11 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
clean_bdev_bh_alias(bh);
}
- if (PageUptodate(page)) {
+ if (folio_test_uptodate(folio)) {
set_buffer_uptodate(bh);
} else if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
!buffer_new(bh) &&
- ocfs2_should_read_blk(inode, page, block_start) &&
+ ocfs2_should_read_blk(inode, folio, block_start) &&
(block_start < from || block_end > to)) {
bh_read_nowait(bh, 0);
*wait_bh++=bh;
@@ -668,7 +669,7 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
if (block_start >= to)
break;
- zero_user(page, block_start, bh->b_size);
+ folio_zero_range(folio, block_start, bh->b_size);
set_buffer_uptodate(bh);
mark_buffer_dirty(bh);
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 24/26] ufs; Convert ufs_change_blocknr() to use folios
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (13 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 20/26] ocfs2: Convert ocfs2_map_page_blocks " Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 25/26] ufs: Remove ufs_get_locked_page() Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 26/26] buffer: Remove folio_create_empty_buffers() Matthew Wilcox (Oracle)
16 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Convert the locked_page argument to a folio, then use folios throughout.
Saves three hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/balloc.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 2436e3f82147..53c11be2b2c1 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -240,6 +240,7 @@ static void ufs_change_blocknr(struct inode *inode, sector_t beg,
unsigned int count, sector_t oldb,
sector_t newb, struct page *locked_page)
{
+ struct folio *folio, *locked_folio = page_folio(locked_page);
const unsigned blks_per_page =
1 << (PAGE_SHIFT - inode->i_blkbits);
const unsigned mask = blks_per_page - 1;
@@ -247,42 +248,39 @@ static void ufs_change_blocknr(struct inode *inode, sector_t beg,
pgoff_t index, cur_index, last_index;
unsigned pos, j, lblock;
sector_t end, i;
- struct page *page;
struct buffer_head *head, *bh;
UFSD("ENTER, ino %lu, count %u, oldb %llu, newb %llu\n",
inode->i_ino, count,
(unsigned long long)oldb, (unsigned long long)newb);
- BUG_ON(!locked_page);
- BUG_ON(!PageLocked(locked_page));
+ BUG_ON(!folio_test_locked(locked_folio));
- cur_index = locked_page->index;
+ cur_index = locked_folio->index;
end = count + beg;
last_index = end >> (PAGE_SHIFT - inode->i_blkbits);
for (i = beg; i < end; i = (i | mask) + 1) {
index = i >> (PAGE_SHIFT - inode->i_blkbits);
if (likely(cur_index != index)) {
- page = ufs_get_locked_page(mapping, index);
- if (!page)/* it was truncated */
+ folio = ufs_get_locked_folio(mapping, index);
+ if (!folio) /* it was truncated */
continue;
- if (IS_ERR(page)) {/* or EIO */
+ if (IS_ERR(folio)) {/* or EIO */
ufs_error(inode->i_sb, __func__,
"read of page %llu failed\n",
(unsigned long long)index);
continue;
}
} else
- page = locked_page;
+ folio = locked_folio;
- head = page_buffers(page);
+ head = folio_buffers(folio);
bh = head;
pos = i & mask;
for (j = 0; j < pos; ++j)
bh = bh->b_this_page;
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 25/26] ufs: Remove ufs_get_locked_page()
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (14 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 24/26] ufs; Convert ufs_change_blocknr() to use folios Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
2023-09-19 4:51 ` [PATCH 26/26] buffer: Remove folio_create_empty_buffers() Matthew Wilcox (Oracle)
16 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
Both callers are now converted to ufs_get_locked_folio().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/util.c | 9 ---------
fs/ufs/util.h | 7 -------
2 files changed, 16 deletions(-)
diff --git a/fs/ufs/util.c b/fs/ufs/util.c
index 151b400cb3b6..d32de30009a0 100644
--- a/fs/ufs/util.c
+++ b/fs/ufs/util.c
@@ -229,15 +229,6 @@ ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev
ufsi->i_u1.i_data[0] = cpu_to_fs32(sb, fs32);
}
-struct page *ufs_get_locked_page(struct address_space *mapping, pgoff_t index)
-{
- struct folio *folio = ufs_get_locked_folio(mapping, index);
-
- if (folio)
- return folio_file_page(folio, index);
- return NULL;
-}
-
/**
* ufs_get_locked_folio() - locate, pin and lock a pagecache folio, if not exist
* read it from disk.
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 62542561d150..0ecd2ed792f5 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -273,7 +273,6 @@ extern void _ubh_ubhcpymem_(struct ufs_sb_private_info *, unsigned char *, struc
extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head *, unsigned char *, unsigned);
/* This functions works with cache pages*/
-struct page *ufs_get_locked_page(struct address_space *mapping, pgoff_t index);
struct folio *ufs_get_locked_folio(struct address_space *mapping, pgoff_t index);
static inline void ufs_put_locked_folio(struct folio *folio)
{
@@ -281,12 +280,6 @@ static inline void ufs_put_locked_folio(struct folio *folio)
folio_put(folio);
}
-static inline void ufs_put_locked_page(struct page *page)
-{
- ufs_put_locked_folio(page_folio(page));
-}
-
-
/*
* macros and inline function to get important structures from ufs_sb_private_info
*/
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread* [PATCH 26/26] buffer: Remove folio_create_empty_buffers()
2023-09-19 4:51 [PATCH 00/26] Finish the create_empty_buffers() transition Matthew Wilcox (Oracle)
` (15 preceding siblings ...)
2023-09-19 4:51 ` [PATCH 25/26] ufs: Remove ufs_get_locked_page() Matthew Wilcox (Oracle)
@ 2023-09-19 4:51 ` Matthew Wilcox (Oracle)
16 siblings, 0 replies; 46+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-09-19 4:51 UTC (permalink / raw)
To: Andrew Morton
Cc: Matthew Wilcox (Oracle), linux-fsdevel, gfs2, linux-nilfs,
linux-ntfs-dev, ntfs3, ocfs2-devel, reiserfs-devel, linux-ext4,
Pankaj Raghav
With all users converted, remove the old create_empty_buffers() and
rename folio_create_empty_buffers() to create_empty_buffers().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/buffer.c | 13 +++----------
fs/ext4/inode.c | 6 +++---
fs/ext4/move_extent.c | 4 ++--
fs/gfs2/aops.c | 2 +-
fs/gfs2/bmap.c | 2 +-
fs/gfs2/meta_io.c | 2 +-
fs/gfs2/quota.c | 2 +-
fs/mpage.c | 2 +-
fs/nilfs2/mdt.c | 2 +-
fs/nilfs2/page.c | 4 ++--
fs/nilfs2/segment.c | 2 +-
fs/ntfs/aops.c | 4 ++--
fs/ntfs/file.c | 2 +-
fs/ntfs3/file.c | 2 +-
fs/ocfs2/aops.c | 2 +-
fs/reiserfs/inode.c | 2 +-
fs/ufs/util.c | 2 +-
include/linux/buffer_head.h | 4 +---
18 files changed, 25 insertions(+), 34 deletions(-)
diff --git a/fs/buffer.c b/fs/buffer.c
index 1b9e691714bd..d483903fa9ff 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1646,7 +1646,7 @@ EXPORT_SYMBOL(block_invalidate_folio);
* block_dirty_folio() via private_lock. try_to_free_buffers
* is already excluded via the folio lock.
*/
-struct buffer_head *folio_create_empty_buffers(struct folio *folio,
+struct buffer_head *create_empty_buffers(struct folio *folio,
unsigned long blocksize, unsigned long b_state)
{
struct buffer_head *bh, *head, *tail;
@@ -1677,13 +1677,6 @@ struct buffer_head *folio_create_empty_buffers(struct folio *folio,
return head;
}
-EXPORT_SYMBOL(folio_create_empty_buffers);
-
-void create_empty_buffers(struct page *page,
- unsigned long blocksize, unsigned long b_state)
-{
- folio_create_empty_buffers(page_folio(page), blocksize, b_state);
-}
EXPORT_SYMBOL(create_empty_buffers);
/**
@@ -1783,7 +1776,7 @@ static struct buffer_head *folio_create_buffers(struct folio *folio,
bh = folio_buffers(folio);
if (!bh)
- bh = folio_create_empty_buffers(folio,
+ bh = create_empty_buffers(folio,
1 << READ_ONCE(inode->i_blkbits), b_state);
return bh;
}
@@ -2676,7 +2669,7 @@ int block_truncate_page(struct address_space *mapping,
bh = folio_buffers(folio);
if (!bh)
- bh = folio_create_empty_buffers(folio, blocksize, 0);
+ bh = create_empty_buffers(folio, blocksize, 0);
/* Find the buffer that contains "offset" */
offset = offset_in_folio(folio, from);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 8e431ff2fd95..347fc8986e93 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1021,7 +1021,7 @@ static int ext4_block_write_begin(struct folio *folio, loff_t pos, unsigned len,
head = folio_buffers(folio);
if (!head)
- head = folio_create_empty_buffers(folio, blocksize, 0);
+ head = create_empty_buffers(folio, blocksize, 0);
bbits = ilog2(blocksize);
block = (sector_t)folio->index << (PAGE_SHIFT - bbits);
@@ -1151,7 +1151,7 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
* starting the handle.
*/
if (!folio_buffers(folio))
- folio_create_empty_buffers(folio, inode->i_sb->s_blocksize, 0);
+ create_empty_buffers(folio, inode->i_sb->s_blocksize, 0);
folio_unlock(folio);
@@ -3642,7 +3642,7 @@ static int __ext4_block_zero_page_range(handle_t *handle,
bh = folio_buffers(folio);
if (!bh)
- bh = folio_create_empty_buffers(folio, blocksize, 0);
+ bh = create_empty_buffers(folio, blocksize, 0);
/* Find the buffer that contains "offset" */
pos = blocksize;
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 7fe448fb948b..3aa57376d9c2 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -184,7 +184,7 @@ mext_page_mkuptodate(struct folio *folio, unsigned from, unsigned to)
blocksize = i_blocksize(inode);
head = folio_buffers(folio);
if (!head)
- head = folio_create_empty_buffers(folio, blocksize, 0);
+ head = create_empty_buffers(folio, blocksize, 0);
block = (sector_t)folio->index << (PAGE_SHIFT - inode->i_blkbits);
for (bh = head, block_start = 0; bh != head || !block_start;
@@ -380,7 +380,7 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
* but keeping in mind that i_size will not change */
bh = folio_buffers(folio[0]);
if (!bh)
- bh = folio_create_empty_buffers(folio[0],
+ bh = create_empty_buffers(folio[0],
1 << orig_inode->i_blkbits, 0);
for (i = 0; i < data_offset_in_page; i++)
bh = bh->b_this_page;
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index c26d48355cc2..6b060fc9e260 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -130,7 +130,7 @@ static int __gfs2_jdata_write_folio(struct folio *folio,
if (folio_test_checked(folio)) {
folio_clear_checked(folio);
if (!folio_buffers(folio)) {
- folio_create_empty_buffers(folio,
+ create_empty_buffers(folio,
inode->i_sb->s_blocksize,
BIT(BH_Dirty)|BIT(BH_Uptodate));
}
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 247d2c16593c..f1eee3f4704b 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -71,7 +71,7 @@ static int gfs2_unstuffer_folio(struct gfs2_inode *ip, struct buffer_head *dibh,
struct buffer_head *bh = folio_buffers(folio);
if (!bh)
- bh = folio_create_empty_buffers(folio,
+ bh = create_empty_buffers(folio,
BIT(inode->i_blkbits), BIT(BH_Uptodate));
if (!buffer_mapped(bh))
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index b28196015543..681cbf2b4405 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -134,7 +134,7 @@ struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
mapping_gfp_mask(mapping) | __GFP_NOFAIL);
bh = folio_buffers(folio);
if (!bh)
- bh = folio_create_empty_buffers(folio,
+ bh = create_empty_buffers(folio,
sdp->sd_sb.sb_bsize, 0);
} else {
folio = __filemap_get_folio(mapping, index,
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 0ee4865ebdca..bf093f195abb 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -750,7 +750,7 @@ static int gfs2_write_buf_to_page(struct gfs2_sbd *sdp, unsigned long index,
return PTR_ERR(folio);
bh = folio_buffers(folio);
if (!bh)
- bh = folio_create_empty_buffers(folio, bsize, 0);
+ bh = create_empty_buffers(folio, bsize, 0);
for (;;) {
/* Find the beginning block within the folio */
diff --git a/fs/mpage.c b/fs/mpage.c
index 964a6efe594d..ffb064ed9d04 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -119,7 +119,7 @@ static void map_buffer_to_folio(struct folio *folio, struct buffer_head *bh,
folio_mark_uptodate(folio);
return;
}
- head = folio_create_empty_buffers(folio, i_blocksize(inode), 0);
+ head = create_empty_buffers(folio, i_blocksize(inode), 0);
}
page_bh = head;
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 7b754e6494d7..c97c77a39668 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -568,7 +568,7 @@ int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh)
bh_frozen = folio_buffers(folio);
if (!bh_frozen)
- bh_frozen = folio_create_empty_buffers(folio, 1 << blkbits, 0);
+ bh_frozen = create_empty_buffers(folio, 1 << blkbits, 0);
bh_frozen = get_nth_bh(bh_frozen, bh_offset(bh) >> blkbits);
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 696215d899bf..06b04758f289 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -34,7 +34,7 @@ static struct buffer_head *__nilfs_get_folio_block(struct folio *folio,
struct buffer_head *bh = folio_buffers(folio);
if (!bh)
- bh = folio_create_empty_buffers(folio, 1 << blkbits, b_state);
+ bh = create_empty_buffers(folio, 1 << blkbits, b_state);
first_block = (unsigned long)index << (PAGE_SHIFT - blkbits);
bh = get_nth_bh(bh, block - first_block);
@@ -204,7 +204,7 @@ static void nilfs_copy_folio(struct folio *dst, struct folio *src,
sbh = folio_buffers(src);
dbh = folio_buffers(dst);
if (!dbh)
- dbh = folio_create_empty_buffers(dst, sbh->b_size, 0);
+ dbh = create_empty_buffers(dst, sbh->b_size, 0);
if (copy_dirty)
mask |= BIT(BH_Dirty);
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 94388fe83cf8..55e31cc903d1 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -732,7 +732,7 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
}
head = folio_buffers(folio);
if (!head)
- head = folio_create_empty_buffers(folio,
+ head = create_empty_buffers(folio,
i_blocksize(inode), 0);
folio_unlock(folio);
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index c4426992a2ee..71e31e789b29 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -189,7 +189,7 @@ static int ntfs_read_block(struct folio *folio)
head = folio_buffers(folio);
if (!head)
- head = folio_create_empty_buffers(folio, blocksize, 0);
+ head = create_empty_buffers(folio, blocksize, 0);
bh = head;
/*
@@ -555,7 +555,7 @@ static int ntfs_write_block(struct folio *folio, struct writeback_control *wbc)
head = folio_buffers(folio);
if (!head) {
BUG_ON(!folio_test_uptodate(folio));
- head = folio_create_empty_buffers(folio, blocksize,
+ head = create_empty_buffers(folio, blocksize,
(1 << BH_Uptodate) | (1 << BH_Dirty));
}
bh = head;
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 099141d20db6..297c0b9db621 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -625,7 +625,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
* create_empty_buffers() will create uptodate/dirty
* buffers if the folio is uptodate/dirty.
*/
- head = folio_create_empty_buffers(folio, blocksize, 0);
+ head = create_empty_buffers(folio, blocksize, 0);
bh = head;
do {
VCN cdelta;
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index a003a69091a2..66fd4ac28395 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -203,7 +203,7 @@ static int ntfs_zero_range(struct inode *inode, u64 vbo, u64 vbo_to)
head = folio_buffers(folio);
if (!head)
- head = folio_create_empty_buffers(folio, blocksize, 0);
+ head = create_empty_buffers(folio, blocksize, 0);
bh = head;
bh_off = 0;
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 95d1e70b4401..a6405dd5df09 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -601,7 +601,7 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
head = folio_buffers(folio);
if (!head)
- head = folio_create_empty_buffers(folio, bsize, 0);
+ head = create_empty_buffers(folio, bsize, 0);
for (bh = head, block_start = 0; bh != head || !block_start;
bh = bh->b_this_page, block_start += bsize) {
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index d9737235b8e0..a9075c4843ed 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2539,7 +2539,7 @@ static int reiserfs_write_full_folio(struct folio *folio,
*/
head = folio_buffers(folio);
if (!head)
- head = folio_create_empty_buffers(folio, s->s_blocksize,
+ head = create_empty_buffers(folio, s->s_blocksize,
(1 << BH_Dirty) | (1 << BH_Uptodate));
/*
diff --git a/fs/ufs/util.c b/fs/ufs/util.c
index d32de30009a0..13ba34e6d64f 100644
--- a/fs/ufs/util.c
+++ b/fs/ufs/util.c
@@ -264,6 +264,6 @@ struct folio *ufs_get_locked_folio(struct address_space *mapping,
}
}
if (!folio_buffers(folio))
- folio_create_empty_buffers(folio, 1 << inode->i_blkbits, 0);
+ create_empty_buffers(folio, 1 << inode->i_blkbits, 0);
return folio;
}
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 9fc615ee17fd..37a69e8828c0 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -201,9 +201,7 @@ struct buffer_head *folio_alloc_buffers(struct folio *folio, unsigned long size,
gfp_t gfp);
struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size,
bool retry);
-void create_empty_buffers(struct page *, unsigned long,
- unsigned long b_state);
-struct buffer_head *folio_create_empty_buffers(struct folio *folio,
+struct buffer_head *create_empty_buffers(struct folio *folio,
unsigned long blocksize, unsigned long b_state);
void end_buffer_read_sync(struct buffer_head *bh, int uptodate);
void end_buffer_write_sync(struct buffer_head *bh, int uptodate);
--
2.40.1
^ permalink raw reply related [flat|nested] 46+ messages in thread