mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-16 04:04:06 +00:00
iomap: add a workaround for racy i_size updates on block devices
A szybot reproducer that does write I/O while truncating the size of a block device can end up in clean_bdev_aliases, which tries to clean the bdev aliases that it uses. This is because iomap_to_bh automatically sets the BH_New flag when outside of i_size. For block devices updates to i_size are racy and we can hit this case in a tiny race window, leading to the eventual clean_bdev_aliases call. Fix this by erroring out of > i_size I/O on block devices. Reported-by: syzbot+1fa947e7f09e136925b8@syzkaller.appspotmail.com Signed-off-by: Christoph Hellwig <hch@lst.de> Tested-by: syzbot+1fa947e7f09e136925b8@syzkaller.appspotmail.com Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
a5f31a5028
commit
381c043233
1 changed files with 10 additions and 1 deletions
11
fs/buffer.c
11
fs/buffer.c
|
@ -2058,8 +2058,17 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh,
|
|||
fallthrough;
|
||||
case IOMAP_MAPPED:
|
||||
if ((iomap->flags & IOMAP_F_NEW) ||
|
||||
offset >= i_size_read(inode))
|
||||
offset >= i_size_read(inode)) {
|
||||
/*
|
||||
* This can happen if truncating the block device races
|
||||
* with the check in the caller as i_size updates on
|
||||
* block devices aren't synchronized by i_rwsem for
|
||||
* block devices.
|
||||
*/
|
||||
if (S_ISBLK(inode->i_mode))
|
||||
return -EIO;
|
||||
set_buffer_new(bh);
|
||||
}
|
||||
bh->b_blocknr = (iomap->addr + offset - iomap->offset) >>
|
||||
inode->i_blkbits;
|
||||
set_buffer_mapped(bh);
|
||||
|
|
Loading…
Add table
Reference in a new issue