Skip to content

Commit 86399ea

Browse files
kawasakiaxboe
authored andcommitted
block: Hold invalidate_lock in BLKRESETZONE ioctl
When BLKRESETZONE ioctl and data read race, the data read leaves stale page cache. The commit e511350 ("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: e511350 ("block: Discard page cache of zone reset target range") Signed-off-by: Shin'ichiro Kawasaki <[email protected]> Cc: [email protected] # v5.15 Reviewed-by: Jan Kara <[email protected]> Reviewed-by: Ming Lei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent b131f20 commit 86399ea

File tree

1 file changed

+5
-10
lines changed

1 file changed

+5
-10
lines changed

block/blk-zoned.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,10 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode,
429429
op = REQ_OP_ZONE_RESET;
430430

431431
/* Invalidate the page cache, including dirty pages. */
432+
filemap_invalidate_lock(bdev->bd_inode->i_mapping);
432433
ret = blkdev_truncate_zone_range(bdev, mode, &zrange);
433434
if (ret)
434-
return ret;
435+
goto fail;
435436
break;
436437
case BLKOPENZONE:
437438
op = REQ_OP_ZONE_OPEN;
@@ -449,15 +450,9 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode,
449450
ret = blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors,
450451
GFP_KERNEL);
451452

452-
/*
453-
* Invalidate the page cache again for zone reset: writes can only be
454-
* direct for zoned devices so concurrent writes would not add any page
455-
* to the page cache after/during reset. The page cache may be filled
456-
* again due to concurrent reads though and dropping the pages for
457-
* these is fine.
458-
*/
459-
if (!ret && cmd == BLKRESETZONE)
460-
ret = blkdev_truncate_zone_range(bdev, mode, &zrange);
453+
fail:
454+
if (cmd == BLKRESETZONE)
455+
filemap_invalidate_unlock(bdev->bd_inode->i_mapping);
461456

462457
return ret;
463458
}

0 commit comments

Comments
 (0)