Message ID | 20211109104723.835533-2-shinichiro.kawasaki@wdc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | block: Fix stale page cache of discard or zero out ioctl | expand |
On Tue 09-11-21 19:47:22, Shin'ichiro Kawasaki wrote: > When BLKDISCARD ioctl and data read race, the data read leaves stale > page cache. To avoid the stale page cache, hold invalidate_lock of the > block device file mapping. The stale page cache is observed when > blktests test case block/009 is repeated hundreds of times. > > This patch can be applied back to the stable kernel version v5.15.y > with slight patch edit. Rework is required for older stable kernels. > > Fixes: 351499a172c0 ("block: Invalidate cache on discard v2") > Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> > Cc: stable@vger.kernel.org # v5.15 Looks good to me. Feel free to add: Reviewed-by: Jan Kara <jack@suse.cz> Honza > --- > block/ioctl.c | 12 +++++++++--- > 1 file changed, 9 insertions(+), 3 deletions(-) > > diff --git a/block/ioctl.c b/block/ioctl.c > index d6af0ac97e57..9fa87f64f703 100644 > --- a/block/ioctl.c > +++ b/block/ioctl.c > @@ -113,6 +113,7 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode, > uint64_t range[2]; > uint64_t start, len; > struct request_queue *q = bdev_get_queue(bdev); > + struct inode *inode = bdev->bd_inode; > int err; > > if (!(mode & FMODE_WRITE)) > @@ -135,12 +136,17 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode, > if (start + len > bdev_nr_bytes(bdev)) > return -EINVAL; > > + filemap_invalidate_lock(inode->i_mapping); > err = truncate_bdev_range(bdev, mode, start, start + len - 1); > if (err) > - return err; > + goto fail; > + > + err = blkdev_issue_discard(bdev, start >> 9, len >> 9, > + GFP_KERNEL, flags); > > - return blkdev_issue_discard(bdev, start >> 9, len >> 9, > - GFP_KERNEL, flags); > +fail: > + filemap_invalidate_unlock(inode->i_mapping); > + return err; > } > > static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode, > -- > 2.33.1 >
diff --git a/block/ioctl.c b/block/ioctl.c index d6af0ac97e57..9fa87f64f703 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -113,6 +113,7 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode, uint64_t range[2]; uint64_t start, len; struct request_queue *q = bdev_get_queue(bdev); + struct inode *inode = bdev->bd_inode; int err; if (!(mode & FMODE_WRITE)) @@ -135,12 +136,17 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode, if (start + len > bdev_nr_bytes(bdev)) return -EINVAL; + filemap_invalidate_lock(inode->i_mapping); err = truncate_bdev_range(bdev, mode, start, start + len - 1); if (err) - return err; + goto fail; + + err = blkdev_issue_discard(bdev, start >> 9, len >> 9, + GFP_KERNEL, flags); - return blkdev_issue_discard(bdev, start >> 9, len >> 9, - GFP_KERNEL, flags); +fail: + filemap_invalidate_unlock(inode->i_mapping); + return err; } static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode,
When BLKDISCARD ioctl and data read race, the data read leaves stale page cache. To avoid the stale page cache, hold invalidate_lock of the block device file mapping. The stale page cache is observed when blktests test case block/009 is repeated hundreds of times. This patch can be applied back to the stable kernel version v5.15.y with slight patch edit. Rework is required for older stable kernels. Fixes: 351499a172c0 ("block: Invalidate cache on discard v2") Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Cc: stable@vger.kernel.org # v5.15 --- block/ioctl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)