]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
buffer: handle large folios in __block_write_begin_int()
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 9 Nov 2023 21:06:07 +0000 (21:06 +0000)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 20 Nov 2023 21:16:31 +0000 (13:16 -0800)
When __block_write_begin_int() was converted to support folios, we did not
expect large folios to be passed to it.  With the current work to support
large block size storage devices, this will no longer be true so change
the checks on 'from' and 'to' to be related to the size of the folio
instead of PAGE_SIZE.  Also remove an assumption that the block size is
smaller than PAGE_SIZE.

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

index faf1916200c2d35901b6ee6fe04625c5be34b9c5..ef444ab53a9b6fdc59dafb032e900d154794f90d 100644 (file)
@@ -2075,27 +2075,24 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh,
 int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len,
                get_block_t *get_block, const struct iomap *iomap)
 {
-       unsigned from = pos & (PAGE_SIZE - 1);
-       unsigned to = from + len;
+       size_t from = offset_in_folio(folio, pos);
+       size_t to = from + len;
        struct inode *inode = folio->mapping->host;
-       unsigned block_start, block_end;
+       size_t block_start, block_end;
        sector_t block;
        int err = 0;
-       unsigned blocksize, bbits;
+       size_t blocksize;
        struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;
 
        BUG_ON(!folio_test_locked(folio));
-       BUG_ON(from > PAGE_SIZE);
-       BUG_ON(to > PAGE_SIZE);
+       BUG_ON(to > folio_size(folio));
        BUG_ON(from > to);
 
        head = folio_create_buffers(folio, inode, 0);
        blocksize = head->b_size;
-       bbits = block_size_bits(blocksize);
-
-       block = (sector_t)folio->index << (PAGE_SHIFT - bbits);
+       block = div_u64(folio_pos(folio), blocksize);
 
-       for(bh = head, block_start = 0; bh != head || !block_start;
+       for (bh = head, block_start = 0; bh != head || !block_start;
            block++, block_start=block_end, bh = bh->b_this_page) {
                block_end = block_start + blocksize;
                if (block_end <= from || block_start >= to) {