summaryrefslogtreecommitdiffstats
path: root/block/bdev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-04-20 11:28:02 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-04-20 11:28:02 -0700
commit977b1ef51866aa7170409af80740788d4f9c4841 (patch)
tree629c009c0ac92956b5c5a4b0b6848a95d3682135 /block/bdev.c
parent39316e5fa94157ac1eb481c762d1e688b2f08138 (diff)
parent01bc4fda9ea0a6b52f12326486f07a4910666cf6 (diff)
downloadlinux-stable-977b1ef51866aa7170409af80740788d4f9c4841.tar.gz
linux-stable-977b1ef51866aa7170409af80740788d4f9c4841.tar.bz2
linux-stable-977b1ef51866aa7170409af80740788d4f9c4841.zip
Merge tag 'block-6.9-20240420' of git://git.kernel.dk/linux
Pull block fixes from Jens Axboe: "Just two minor fixes that should go into the 6.9 kernel release, one fixing a regression with partition scanning errors, and one fixing a WARN_ON() that can get triggered if we race with a timer" * tag 'block-6.9-20240420' of git://git.kernel.dk/linux: blk-iocost: do not WARN if iocg was already offlined block: propagate partition scanning errors to the BLKRRPART ioctl
Diffstat (limited to 'block/bdev.c')
-rw-r--r--block/bdev.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/block/bdev.c b/block/bdev.c
index b8e32d933a63..4dc94145eb53 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -645,6 +645,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;
@@ -663,20 +671,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;