Commit 9d1c9287 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarPhillip Potter <phil@philpotter.co.uk>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Acked-by: default avatarChristian Brauner <brauner@kernel.org>
Link: https://lore.kernel.org/r/20230608110258.189493-2-hch@lst.de


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent fece685c
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -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;

	if (!atomic_read(&part->bd_openers)) {
		disk->open_partitions++;
		set_init_blocksize(part);
done:
	}
	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;
	if (atomic_dec_and_test(&part->bd_openers)) {
		blkdev_flush_mapping(part);
		whole->bd_disk->open_partitions--;
	}
	blkdev_put_whole(whole, mode);
}