mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 04:33:26 +02:00
block: use the holder as indication for exclusive opens
The current interface for exclusive opens is rather confusing as it requires both the FMODE_EXCL flag and a holder. Remove the need to pass FMODE_EXCL and just key off the exclusive open off a non-NULL holder. For blkdev_put this requires adding the holder argument, which provides better debug checking that only the holder actually releases the hold, but at the same time allows removing the now superfluous mode argument. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Acked-by: Christian Brauner <brauner@kernel.org> Acked-by: David Sterba <dsterba@suse.com> [btrfs] Acked-by: Jack Wang <jinpu.wang@ionos.com> [rnbd] Link: https://lore.kernel.org/r/20230608110258.189493-16-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
committed by
Jens Axboe
parent
2ef789288a
commit
2736e8eeb0
37
block/bdev.c
37
block/bdev.c
@@ -604,7 +604,7 @@ void bd_abort_claiming(struct block_device *bdev, void *holder)
|
||||
}
|
||||
EXPORT_SYMBOL(bd_abort_claiming);
|
||||
|
||||
static void bd_end_claim(struct block_device *bdev)
|
||||
static void bd_end_claim(struct block_device *bdev, void *holder)
|
||||
{
|
||||
struct block_device *whole = bdev_whole(bdev);
|
||||
bool unblock = false;
|
||||
@@ -614,6 +614,7 @@ static void bd_end_claim(struct block_device *bdev)
|
||||
* bdev_lock. open_mutex is used to synchronize disk_holder unlinking.
|
||||
*/
|
||||
mutex_lock(&bdev_lock);
|
||||
WARN_ON_ONCE(bdev->bd_holder != holder);
|
||||
WARN_ON_ONCE(--bdev->bd_holders < 0);
|
||||
WARN_ON_ONCE(--whole->bd_holders < 0);
|
||||
if (!bdev->bd_holders) {
|
||||
@@ -750,10 +751,9 @@ void blkdev_put_no_open(struct block_device *bdev)
|
||||
* @holder: exclusive holder identifier
|
||||
* @hops: holder operations
|
||||
*
|
||||
* Open the block device described by device number @dev. If @mode includes
|
||||
* %FMODE_EXCL, the block device is opened with exclusive access. Specifying
|
||||
* %FMODE_EXCL with a %NULL @holder is invalid. Exclusive opens may nest for
|
||||
* the same @holder.
|
||||
* Open the block device described by device number @dev. If @holder is not
|
||||
* %NULL, the block device is opened with exclusive access. Exclusive opens may
|
||||
* nest for the same @holder.
|
||||
*
|
||||
* Use this interface ONLY if you really do not have anything better - i.e. when
|
||||
* you are behind a truly sucky interface and all you are given is a device
|
||||
@@ -785,10 +785,16 @@ struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder,
|
||||
return ERR_PTR(-ENXIO);
|
||||
disk = bdev->bd_disk;
|
||||
|
||||
if (mode & FMODE_EXCL) {
|
||||
if (holder) {
|
||||
mode |= FMODE_EXCL;
|
||||
ret = bd_prepare_to_claim(bdev, holder, hops);
|
||||
if (ret)
|
||||
goto put_blkdev;
|
||||
} else {
|
||||
if (WARN_ON_ONCE(mode & FMODE_EXCL)) {
|
||||
ret = -EIO;
|
||||
goto put_blkdev;
|
||||
}
|
||||
}
|
||||
|
||||
disk_block_events(disk);
|
||||
@@ -805,7 +811,7 @@ struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder,
|
||||
ret = blkdev_get_whole(bdev, mode);
|
||||
if (ret)
|
||||
goto put_module;
|
||||
if (mode & FMODE_EXCL) {
|
||||
if (holder) {
|
||||
bd_finish_claiming(bdev, holder, hops);
|
||||
|
||||
/*
|
||||
@@ -829,7 +835,7 @@ struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder,
|
||||
put_module:
|
||||
module_put(disk->fops->owner);
|
||||
abort_claiming:
|
||||
if (mode & FMODE_EXCL)
|
||||
if (holder)
|
||||
bd_abort_claiming(bdev, holder);
|
||||
mutex_unlock(&disk->open_mutex);
|
||||
disk_unblock_events(disk);
|
||||
@@ -845,10 +851,9 @@ EXPORT_SYMBOL(blkdev_get_by_dev);
|
||||
* @mode: FMODE_* mask
|
||||
* @holder: exclusive holder identifier
|
||||
*
|
||||
* Open the block device described by the device file at @path. If @mode
|
||||
* includes %FMODE_EXCL, the block device is opened with exclusive access.
|
||||
* Specifying %FMODE_EXCL with a %NULL @holder is invalid. Exclusive opens may
|
||||
* nest for the same @holder.
|
||||
* Open the block device described by the device file at @path. If @holder is
|
||||
* not %NULL, the block device is opened with exclusive access. Exclusive opens
|
||||
* may nest for the same @holder.
|
||||
*
|
||||
* CONTEXT:
|
||||
* Might sleep.
|
||||
@@ -869,7 +874,7 @@ struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,
|
||||
|
||||
bdev = blkdev_get_by_dev(dev, mode, holder, hops);
|
||||
if (!IS_ERR(bdev) && (mode & FMODE_WRITE) && bdev_read_only(bdev)) {
|
||||
blkdev_put(bdev, mode);
|
||||
blkdev_put(bdev, holder);
|
||||
return ERR_PTR(-EACCES);
|
||||
}
|
||||
|
||||
@@ -877,7 +882,7 @@ struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,
|
||||
}
|
||||
EXPORT_SYMBOL(blkdev_get_by_path);
|
||||
|
||||
void blkdev_put(struct block_device *bdev, fmode_t mode)
|
||||
void blkdev_put(struct block_device *bdev, void *holder)
|
||||
{
|
||||
struct gendisk *disk = bdev->bd_disk;
|
||||
|
||||
@@ -892,8 +897,8 @@ void blkdev_put(struct block_device *bdev, fmode_t mode)
|
||||
sync_blockdev(bdev);
|
||||
|
||||
mutex_lock(&disk->open_mutex);
|
||||
if (mode & FMODE_EXCL)
|
||||
bd_end_claim(bdev);
|
||||
if (holder)
|
||||
bd_end_claim(bdev, holder);
|
||||
|
||||
/*
|
||||
* Trigger event checking and tell drivers to flush MEDIA_CHANGE
|
||||
|
@@ -490,7 +490,9 @@ static int blkdev_open(struct inode *inode, struct file *filp)
|
||||
if ((filp->f_flags & O_ACCMODE) == 3)
|
||||
filp->f_mode |= FMODE_WRITE_IOCTL;
|
||||
|
||||
bdev = blkdev_get_by_dev(inode->i_rdev, filp->f_mode, filp, NULL);
|
||||
bdev = blkdev_get_by_dev(inode->i_rdev, filp->f_mode,
|
||||
(filp->f_mode & FMODE_EXCL) ? filp : NULL,
|
||||
NULL);
|
||||
if (IS_ERR(bdev))
|
||||
return PTR_ERR(bdev);
|
||||
|
||||
@@ -504,7 +506,7 @@ static int blkdev_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct block_device *bdev = filp->private_data;
|
||||
|
||||
blkdev_put(bdev, filp->f_mode);
|
||||
blkdev_put(bdev, (filp->f_mode & FMODE_EXCL) ? filp : NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -365,12 +365,11 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
|
||||
}
|
||||
|
||||
set_bit(GD_NEED_PART_SCAN, &disk->state);
|
||||
bdev = blkdev_get_by_dev(disk_devt(disk), mode & ~FMODE_EXCL, NULL,
|
||||
NULL);
|
||||
bdev = blkdev_get_by_dev(disk_devt(disk), mode, NULL, NULL);
|
||||
if (IS_ERR(bdev))
|
||||
ret = PTR_ERR(bdev);
|
||||
else
|
||||
blkdev_put(bdev, mode & ~FMODE_EXCL);
|
||||
blkdev_put(bdev, NULL);
|
||||
|
||||
/*
|
||||
* If blkdev_get_by_dev() failed early, GD_NEED_PART_SCAN is still set,
|
||||
|
@@ -454,11 +454,10 @@ static int blkdev_bszset(struct block_device *bdev, fmode_t mode,
|
||||
if (mode & FMODE_EXCL)
|
||||
return set_blocksize(bdev, n);
|
||||
|
||||
if (IS_ERR(blkdev_get_by_dev(bdev->bd_dev, mode | FMODE_EXCL, &bdev,
|
||||
NULL)))
|
||||
if (IS_ERR(blkdev_get_by_dev(bdev->bd_dev, mode, &bdev, NULL)))
|
||||
return -EBUSY;
|
||||
ret = set_blocksize(bdev, n);
|
||||
blkdev_put(bdev, mode | FMODE_EXCL);
|
||||
blkdev_put(bdev, &bdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user