Support large folios in block_truncate_page() and avoid three hidden
calls to compound_head().

Signed-off-by: Matthew Wilcox (Oracle) <wi...@infradead.org>
---
 fs/buffer.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index c38fdcaa32ff..5a5b0c9d9769 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2598,17 +2598,16 @@ int block_truncate_page(struct address_space *mapping,
                        loff_t from, get_block_t *get_block)
 {
        pgoff_t index = from >> PAGE_SHIFT;
-       unsigned offset = from & (PAGE_SIZE-1);
        unsigned blocksize;
        sector_t iblock;
-       unsigned length, pos;
+       size_t offset, length, pos;
        struct inode *inode = mapping->host;
-       struct page *page;
+       struct folio *folio;
        struct buffer_head *bh;
        int err = 0;
 
        blocksize = i_blocksize(inode);
-       length = offset & (blocksize - 1);
+       length = from & (blocksize - 1);
 
        /* Block boundary? Nothing to do */
        if (!length)
@@ -2617,15 +2616,18 @@ int block_truncate_page(struct address_space *mapping,
        length = blocksize - length;
        iblock = (sector_t)index << (PAGE_SHIFT - inode->i_blkbits);
        
-       page = grab_cache_page(mapping, index);
-       if (!page)
+       folio = filemap_grab_folio(mapping, index);
+       if (!folio)
                return -ENOMEM;
 
-       if (!page_has_buffers(page))
-               create_empty_buffers(page, blocksize, 0);
+       bh = folio_buffers(folio);
+       if (!bh) {
+               folio_create_empty_buffers(folio, blocksize, 0);
+               bh = folio_buffers(folio);
+       }
 
        /* Find the buffer that contains "offset" */
-       bh = page_buffers(page);
+       offset = offset_in_folio(folio, from);
        pos = blocksize;
        while (offset >= pos) {
                bh = bh->b_this_page;
@@ -2644,7 +2646,7 @@ int block_truncate_page(struct address_space *mapping,
        }
 
        /* 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) && !buffer_delay(bh) && !buffer_unwritten(bh)) 
{
@@ -2654,12 +2656,12 @@ int block_truncate_page(struct address_space *mapping,
                        goto unlock;
        }
 
-       zero_user(page, offset, length);
+       folio_zero_range(folio, offset, length);
        mark_buffer_dirty(bh);
 
 unlock:
-       unlock_page(page);
-       put_page(page);
+       folio_unlock(folio);
+       folio_put(folio);
 
        return err;
 }
-- 
2.39.2

Reply via email to