buffer: make folio_create_empty_buffers() return a buffer_head
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Mon, 16 Oct 2023 20:10:49 +0000 (21:10 +0100)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 25 Oct 2023 23:47:08 +0000 (16:47 -0700)
Patch series "Finish the create_empty_buffers() transition", v2.

Pankaj recently added folio_create_empty_buffers() as the folio equivalent
to create_empty_buffers().  This patch set finishes the conversion by
first converting all remaining filesystems to call
folio_create_empty_buffers(), then renaming it back to
create_empty_buffers().  I took the opportunity to make a few
simplifications like making folio_create_empty_buffers() return the head
buffer and extracting get_nth_bh() from nilfs2.

A few of the patches in this series aren't directly related to
create_empty_buffers(), but I saw them while I was working on this and
thought they'd be easy enough to add to this series.  Compile-tested only,
other than ext4.

This patch (of 26):

Almost all callers want to know the first BH that was allocated for this
folio.  We already have that handy, so return it.

Link: https://lkml.kernel.org/r/20231016201114.1928083-1-willy@infradead.org
Link: https://lkml.kernel.org/r/20231016201114.1928083-3-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
Cc: Andreas Gruenbacher <agruenba@redhat.com>
Cc: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/buffer.c
include/linux/buffer_head.h

index 86ddfa52c6995fa467141aad2883fc8f2e2a47cd..bfa7604d1891272c44488d8ab33b164ec36cda80 100644 (file)
@@ -1641,8 +1641,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;
@@ -1669,6 +1669,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);
 
@@ -1770,13 +1772,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;
 }
 
 /*
@@ -2676,10 +2680,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);
index 3dc4720e4773bdc898ee55621dfadc42716bae7e..1001244a8941bfafc5d7a718d562edfe854a733b 100644 (file)
@@ -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);