Skip to content

Commit

Permalink
block: also call ->open for incremental partition opens
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Phillip Potter <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Acked-by: Christian Brauner <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
Christoph Hellwig authored and axboe committed Jun 12, 2023
1 parent fece685 commit 9d1c928
Showing 1 changed file with 8 additions and 10 deletions.
18 changes: 8 additions & 10 deletions block/bdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -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);
}

Expand Down

0 comments on commit 9d1c928

Please sign in to comment.