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 <h...@lst.de>
Reviewed-by: Phillip Potter <p...@philpotter.co.uk>
Reviewed-by: Hannes Reinecke <h...@suse.de>
Acked-by: Christian Brauner <brau...@kernel.org>
---
 block/bdev.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/block/bdev.c b/block/bdev.c
index 5c46ff10770638..981f6135795138 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);
 }
 
-- 
2.39.2


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um

Reply via email to