Skip to content

Commit b061940

Browse files
Matthew Wilcox (Oracle)akpm00
authored andcommitted
buffer: handle large folios in __block_write_begin_int()
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>
1 parent 4b04646 commit b061940

File tree

1 file changed

+7
-10
lines changed

1 file changed

+7
-10
lines changed

fs/buffer.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,27 +2075,24 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh,
20752075
int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len,
20762076
get_block_t *get_block, const struct iomap *iomap)
20772077
{
2078-
unsigned from = pos & (PAGE_SIZE - 1);
2079-
unsigned to = from + len;
2078+
size_t from = offset_in_folio(folio, pos);
2079+
size_t to = from + len;
20802080
struct inode *inode = folio->mapping->host;
2081-
unsigned block_start, block_end;
2081+
size_t block_start, block_end;
20822082
sector_t block;
20832083
int err = 0;
2084-
unsigned blocksize, bbits;
2084+
size_t blocksize;
20852085
struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;
20862086

20872087
BUG_ON(!folio_test_locked(folio));
2088-
BUG_ON(from > PAGE_SIZE);
2089-
BUG_ON(to > PAGE_SIZE);
2088+
BUG_ON(to > folio_size(folio));
20902089
BUG_ON(from > to);
20912090

20922091
head = folio_create_buffers(folio, inode, 0);
20932092
blocksize = head->b_size;
2094-
bbits = block_size_bits(blocksize);
2095-
2096-
block = (sector_t)folio->index << (PAGE_SHIFT - bbits);
2093+
block = div_u64(folio_pos(folio), blocksize);
20972094

2098-
for(bh = head, block_start = 0; bh != head || !block_start;
2095+
for (bh = head, block_start = 0; bh != head || !block_start;
20992096
block++, block_start=block_end, bh = bh->b_this_page) {
21002097
block_end = block_start + blocksize;
21012098
if (block_end <= from || block_start >= to) {

0 commit comments

Comments
 (0)