summaryrefslogtreecommitdiffstats
path: root/block/bdev.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2023-06-08 13:02:29 +0200
committerJens Axboe <axboe@kernel.dk>2023-06-12 08:04:03 -0600
commit9d1c92872e7082f100f629a58b32fa0214aa1aec (patch)
tree5674b55326a5a01ae2e19ae3839b099968fc1a54 /block/bdev.c
parentfece685cc7bbb5e1af89f891223c31c3bcc969f7 (diff)
downloadlinux-stable-9d1c92872e7082f100f629a58b32fa0214aa1aec.tar.gz
linux-stable-9d1c92872e7082f100f629a58b32fa0214aa1aec.tar.bz2
linux-stable-9d1c92872e7082f100f629a58b32fa0214aa1aec.zip
block: also call ->open for incremental partition opens
For whole devices ->open is called for each open, but for partitions it is only called on the first open of a partition, e.g.: open("/dev/vdb", ...) open("/dev/vdb", ...) - 2 call to ->open open("/dev/vdb1", ...) open("/dev/vdb", ...) - 2 call to ->open open("/dev/vdb", ...) open("/dev/vdb", ...) - just open call to ->open This is problematic as various block drivers look at open flags and might not do all the required setup if the earlier open was with an odd flag like O_NDELAY or the magic 3 ioctl-only open mode. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Phillip Potter <phil@philpotter.co.uk> Reviewed-by: Hannes Reinecke <hare@suse.de> Acked-by: Christian Brauner <brauner@kernel.org> Link: https://lore.kernel.org/r/20230608110258.189493-2-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/bdev.c')
-rw-r--r--block/bdev.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/block/bdev.c b/block/bdev.c
index 5c46ff107706..981f61357951 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -683,9 +683,6 @@ static int blkdev_get_part(struct block_device *part, fmode_t mode)
struct gendisk *disk = part->bd_disk;
int ret;
- if (atomic_read(&part->bd_openers))
- goto done;
-
ret = blkdev_get_whole(bdev_whole(part), mode);
if (ret)
return ret;
@@ -694,9 +691,10 @@ static int blkdev_get_part(struct block_device *part, fmode_t mode)
if (!bdev_nr_sectors(part))
goto out_blkdev_put;
- disk->open_partitions++;
- set_init_blocksize(part);
-done:
+ if (!atomic_read(&part->bd_openers)) {
+ disk->open_partitions++;
+ set_init_blocksize(part);
+ }
atomic_inc(&part->bd_openers);
return 0;
@@ -709,10 +707,10 @@ static void blkdev_put_part(struct block_device *part, fmode_t mode)
{
struct block_device *whole = bdev_whole(part);
- if (!atomic_dec_and_test(&part->bd_openers))
- return;
- blkdev_flush_mapping(part);
- whole->bd_disk->open_partitions--;
+ if (atomic_dec_and_test(&part->bd_openers)) {
+ blkdev_flush_mapping(part);
+ whole->bd_disk->open_partitions--;
+ }
blkdev_put_whole(whole, mode);
}