diff options
author | Jan Kara <jack@suse.cz> | 2023-01-03 11:44:30 +0100 |
---|---|---|
committer | Andrew Morton <akpm@linux-foundation.org> | 2023-01-18 17:12:56 -0800 |
commit | 4b89a37d54a0b5ed6b2e5a9afc44a15a22e563f5 (patch) | |
tree | 8bdbc93c57930559198ec064b2900ce46eccb392 /fs/mpage.c | |
parent | 6c364edc194e104566f4de72f7a2af5b8fc17110 (diff) |
fs: don't allocate blocks beyond EOF from __mpage_writepage
When __mpage_writepage() is called for a page beyond EOF, it will go and
allocate all blocks underlying the page. This is not only unnecessary but
this way blocks can get leaked (e.g. if a page beyond EOF is marked dirty
but in the end write fails and i_size is not extended).
Link: https://lkml.kernel.org/r/20230103104430.27749-1-jack@suse.cz
Signed-off-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'fs/mpage.c')
-rw-r--r-- | fs/mpage.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/mpage.c b/fs/mpage.c index d36a95473f77..b8e7975159bc 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -524,6 +524,12 @@ static int __mpage_writepage(struct page *page, struct writeback_control *wbc, */ BUG_ON(!PageUptodate(page)); block_in_file = (sector_t)page->index << (PAGE_SHIFT - blkbits); + /* + * Whole page beyond EOF? Skip allocating blocks to avoid leaking + * space. + */ + if (block_in_file >= (i_size + (1 << blkbits) - 1) >> blkbits) + goto page_is_mapped; last_block = (i_size - 1) >> blkbits; map_bh.b_page = page; for (page_block = 0; page_block < blocks_per_page; ) { |