diff options
author | Christoph Hellwig <hch@lst.de> | 2023-06-08 13:02:29 +0200 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2023-06-12 16:04:03 +0200 |
commit | 9d1c92872e7082f100f629a58b32fa0214aa1aec (patch) | |
tree | 5674b55326a5a01ae2e19ae3839b099968fc1a54 /block/bdev.c | |
parent | block/rnbd-srv: make process_msg_sess_info returns void (diff) | |
download | linux-9d1c92872e7082f100f629a58b32fa0214aa1aec.tar.xz linux-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 '')
-rw-r--r-- | block/bdev.c | 18 |
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); } |