mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-26 12:34:41 +08:00
block: Hold invalidate_lock in BLKRESETZONE ioctl
commit86399ea071
upstream. When BLKRESETZONE ioctl and data read race, the data read leaves stale page cache. The commite511350590
("block: Discard page cache of zone reset target range") added page cache truncation to avoid stale page cache after the ioctl. However, the stale page cache still can be read during the reset zone operation for the ioctl. To avoid the stale page cache completely, hold invalidate_lock of the block device file mapping. Fixes:e511350590
("block: Discard page cache of zone reset target range") Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Cc: stable@vger.kernel.org # v5.15 Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Ming Lei <ming.lei@redhat.com> Link: https://lore.kernel.org/r/20211111085238.942492-1-shinichiro.kawasaki@wdc.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
373c2bfecb
commit
5e84e9d61d
@ -429,9 +429,10 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
op = REQ_OP_ZONE_RESET;
|
||||
|
||||
/* Invalidate the page cache, including dirty pages. */
|
||||
filemap_invalidate_lock(bdev->bd_inode->i_mapping);
|
||||
ret = blkdev_truncate_zone_range(bdev, mode, &zrange);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto fail;
|
||||
break;
|
||||
case BLKOPENZONE:
|
||||
op = REQ_OP_ZONE_OPEN;
|
||||
@ -449,15 +450,9 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
ret = blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors,
|
||||
GFP_KERNEL);
|
||||
|
||||
/*
|
||||
* Invalidate the page cache again for zone reset: writes can only be
|
||||
* direct for zoned devices so concurrent writes would not add any page
|
||||
* to the page cache after/during reset. The page cache may be filled
|
||||
* again due to concurrent reads though and dropping the pages for
|
||||
* these is fine.
|
||||
*/
|
||||
if (!ret && cmd == BLKRESETZONE)
|
||||
ret = blkdev_truncate_zone_range(bdev, mode, &zrange);
|
||||
fail:
|
||||
if (cmd == BLKRESETZONE)
|
||||
filemap_invalidate_unlock(bdev->bd_inode->i_mapping);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user