buffer: fix more functions for block size > PAGE_SIZE
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 9 Nov 2023 21:06:08 +0000 (21:06 +0000)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 29 Dec 2023 19:58:23 +0000 (11:58 -0800)
Both __block_write_full_folio() and block_read_full_folio() assumed that
block size <= PAGE_SIZE.  Replace the shift with a divide, which is
probably cheaper than first calculating the shift.  That lets us remove
block_size_bits() as these were the last callers.

Link: https://lkml.kernel.org/r/20231109210608.2252323-8-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: Pankaj Raghav <p.raghav@samsung.com>
Cc: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/buffer.c

index 9f47841501949a4a4a3ad83bc4c3e5621c01fdf3..3a8c8322ed2862fee818a0d84c63b77ac57a341e 100644 (file)
@@ -1742,19 +1742,6 @@ unlock_page:
 }
 EXPORT_SYMBOL(clean_bdev_aliases);
 
-/*
- * Size is a power-of-two in the range 512..PAGE_SIZE,
- * and the case we care about most is PAGE_SIZE.
- *
- * So this *could* possibly be written with those
- * constraints in mind (relevant mostly if some
- * architecture has a slow bit-scan instruction)
- */
-static inline int block_size_bits(unsigned int blocksize)
-{
-       return ilog2(blocksize);
-}
-
 static struct buffer_head *folio_create_buffers(struct folio *folio,
                                                struct inode *inode,
                                                unsigned int b_state)
@@ -1807,7 +1794,7 @@ int __block_write_full_folio(struct inode *inode, struct folio *folio,
        sector_t block;
        sector_t last_block;
        struct buffer_head *bh, *head;
-       unsigned int blocksize, bbits;
+       size_t blocksize;
        int nr_underway = 0;
        blk_opf_t write_flags = wbc_to_write_flags(wbc);
 
@@ -1826,10 +1813,9 @@ int __block_write_full_folio(struct inode *inode, struct folio *folio,
 
        bh = head;
        blocksize = bh->b_size;
-       bbits = block_size_bits(blocksize);
 
-       block = (sector_t)folio->index << (PAGE_SHIFT - bbits);
-       last_block = (i_size_read(inode) - 1) >> bbits;
+       block = div_u64(folio_pos(folio), blocksize);
+       last_block = div_u64(i_size_read(inode) - 1, blocksize);
 
        /*
         * Get all the dirty buffers mapped to disk addresses and
@@ -2355,7 +2341,7 @@ int block_read_full_folio(struct folio *folio, get_block_t *get_block)
        struct inode *inode = folio->mapping->host;
        sector_t iblock, lblock;
        struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
-       unsigned int blocksize, bbits;
+       size_t blocksize;
        int nr, i;
        int fully_mapped = 1;
        bool page_error = false;
@@ -2369,10 +2355,9 @@ int block_read_full_folio(struct folio *folio, get_block_t *get_block)
 
        head = folio_create_buffers(folio, inode, 0);
        blocksize = head->b_size;
-       bbits = block_size_bits(blocksize);
 
-       iblock = (sector_t)folio->index << (PAGE_SHIFT - bbits);
-       lblock = (limit+blocksize-1) >> bbits;
+       iblock = div_u64(folio_pos(folio), blocksize);
+       lblock = div_u64(limit + blocksize - 1, blocksize);
        bh = head;
        nr = 0;
        i = 0;