block: propagate partition scanning errors to the BLKRRPART ioctl
BugLink: https://bugs.launchpad.net/bugs/2068087 [ Upstream commit 752863bddacab6b5c5164b1df8c8b2e3a175ee28 ] Commit4601b4b130("block: reopen the device in blkdev_reread_part") lost the propagation of I/O errors from the low-level read of the partition table to the user space caller of the BLKRRPART. Apparently some user space relies on, so restore the propagation. This isn't exactly pretty as other block device open calls explicitly do not are about these errors, so add a new BLK_OPEN_STRICT_SCAN to opt into the error propagation. Fixes:4601b4b130("block: reopen the device in blkdev_reread_part") Reported-by: Saranya Muruganandam <saranyamohan@google.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com> Reviewed-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Link: https://lore.kernel.org/r/20240417144743.2277601-1-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Portia Stephens <portia.stephens@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
This commit is contained in:
committed by
Stefan Bader
parent
c8f586954f
commit
dbc7f9e8d7
+19
-10
@@ -639,6 +639,14 @@ static void blkdev_flush_mapping(struct block_device *bdev)
|
||||
bdev_write_inode(bdev);
|
||||
}
|
||||
|
||||
static void blkdev_put_whole(struct block_device *bdev)
|
||||
{
|
||||
if (atomic_dec_and_test(&bdev->bd_openers))
|
||||
blkdev_flush_mapping(bdev);
|
||||
if (bdev->bd_disk->fops->release)
|
||||
bdev->bd_disk->fops->release(bdev->bd_disk);
|
||||
}
|
||||
|
||||
static int blkdev_get_whole(struct block_device *bdev, blk_mode_t mode)
|
||||
{
|
||||
struct gendisk *disk = bdev->bd_disk;
|
||||
@@ -657,20 +665,21 @@ static int blkdev_get_whole(struct block_device *bdev, blk_mode_t mode)
|
||||
|
||||
if (!atomic_read(&bdev->bd_openers))
|
||||
set_init_blocksize(bdev);
|
||||
if (test_bit(GD_NEED_PART_SCAN, &disk->state))
|
||||
bdev_disk_changed(disk, false);
|
||||
atomic_inc(&bdev->bd_openers);
|
||||
if (test_bit(GD_NEED_PART_SCAN, &disk->state)) {
|
||||
/*
|
||||
* Only return scanning errors if we are called from contexts
|
||||
* that explicitly want them, e.g. the BLKRRPART ioctl.
|
||||
*/
|
||||
ret = bdev_disk_changed(disk, false);
|
||||
if (ret && (mode & BLK_OPEN_STRICT_SCAN)) {
|
||||
blkdev_put_whole(bdev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void blkdev_put_whole(struct block_device *bdev)
|
||||
{
|
||||
if (atomic_dec_and_test(&bdev->bd_openers))
|
||||
blkdev_flush_mapping(bdev);
|
||||
if (bdev->bd_disk->fops->release)
|
||||
bdev->bd_disk->fops->release(bdev->bd_disk);
|
||||
}
|
||||
|
||||
static int blkdev_get_part(struct block_device *part, blk_mode_t mode)
|
||||
{
|
||||
struct gendisk *disk = part->bd_disk;
|
||||
|
||||
Reference in New Issue
Block a user