Commit 9acf381f authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

block: turn bdev->bd_openers into an atomic_t

All manipulation of bd_openers is under disk->open_mutex and will remain
so for the foreseeable future.  But at least one place reads it without
the lock (blkdev_get) and there are more to be added.  So make sure the
compiler does not do turn the increments and decrements into non-atomic
sequences by using an atomic_t.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20220330052917.2566582-6-hch@lst.deSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent dbdc1be3
...@@ -673,17 +673,17 @@ static int blkdev_get_whole(struct block_device *bdev, fmode_t mode) ...@@ -673,17 +673,17 @@ static int blkdev_get_whole(struct block_device *bdev, fmode_t mode)
} }
} }
if (!bdev->bd_openers) if (!atomic_read(&bdev->bd_openers))
set_init_blocksize(bdev); set_init_blocksize(bdev);
if (test_bit(GD_NEED_PART_SCAN, &disk->state)) if (test_bit(GD_NEED_PART_SCAN, &disk->state))
bdev_disk_changed(disk, false); bdev_disk_changed(disk, false);
bdev->bd_openers++; atomic_inc(&bdev->bd_openers);
return 0; return 0;
} }
static void blkdev_put_whole(struct block_device *bdev, fmode_t mode) static void blkdev_put_whole(struct block_device *bdev, fmode_t mode)
{ {
if (!--bdev->bd_openers) if (atomic_dec_and_test(&bdev->bd_openers))
blkdev_flush_mapping(bdev); blkdev_flush_mapping(bdev);
if (bdev->bd_disk->fops->release) if (bdev->bd_disk->fops->release)
bdev->bd_disk->fops->release(bdev->bd_disk, mode); bdev->bd_disk->fops->release(bdev->bd_disk, mode);
...@@ -694,7 +694,7 @@ static int blkdev_get_part(struct block_device *part, fmode_t mode) ...@@ -694,7 +694,7 @@ static int blkdev_get_part(struct block_device *part, fmode_t mode)
struct gendisk *disk = part->bd_disk; struct gendisk *disk = part->bd_disk;
int ret; int ret;
if (part->bd_openers) if (atomic_read(&part->bd_openers))
goto done; goto done;
ret = blkdev_get_whole(bdev_whole(part), mode); ret = blkdev_get_whole(bdev_whole(part), mode);
...@@ -708,7 +708,7 @@ static int blkdev_get_part(struct block_device *part, fmode_t mode) ...@@ -708,7 +708,7 @@ static int blkdev_get_part(struct block_device *part, fmode_t mode)
disk->open_partitions++; disk->open_partitions++;
set_init_blocksize(part); set_init_blocksize(part);
done: done:
part->bd_openers++; atomic_inc(&part->bd_openers);
return 0; return 0;
out_blkdev_put: out_blkdev_put:
...@@ -720,7 +720,7 @@ static void blkdev_put_part(struct block_device *part, fmode_t mode) ...@@ -720,7 +720,7 @@ static void blkdev_put_part(struct block_device *part, fmode_t mode)
{ {
struct block_device *whole = bdev_whole(part); struct block_device *whole = bdev_whole(part);
if (--part->bd_openers) if (!atomic_dec_and_test(&part->bd_openers))
return; return;
blkdev_flush_mapping(part); blkdev_flush_mapping(part);
whole->bd_disk->open_partitions--; whole->bd_disk->open_partitions--;
...@@ -899,7 +899,7 @@ void blkdev_put(struct block_device *bdev, fmode_t mode) ...@@ -899,7 +899,7 @@ void blkdev_put(struct block_device *bdev, fmode_t mode)
* of the world and we want to avoid long (could be several minute) * of the world and we want to avoid long (could be several minute)
* syncs while holding the mutex. * syncs while holding the mutex.
*/ */
if (bdev->bd_openers == 1) if (atomic_read(&bdev->bd_openers) == 1)
sync_blockdev(bdev); sync_blockdev(bdev);
mutex_lock(&disk->open_mutex); mutex_lock(&disk->open_mutex);
...@@ -1044,7 +1044,7 @@ void sync_bdevs(bool wait) ...@@ -1044,7 +1044,7 @@ void sync_bdevs(bool wait)
bdev = I_BDEV(inode); bdev = I_BDEV(inode);
mutex_lock(&bdev->bd_disk->open_mutex); mutex_lock(&bdev->bd_disk->open_mutex);
if (!bdev->bd_openers) { if (!atomic_read(&bdev->bd_openers)) {
; /* skip */ ; /* skip */
} else if (wait) { } else if (wait) {
/* /*
......
...@@ -478,7 +478,7 @@ int bdev_del_partition(struct gendisk *disk, int partno) ...@@ -478,7 +478,7 @@ int bdev_del_partition(struct gendisk *disk, int partno)
goto out_unlock; goto out_unlock;
ret = -EBUSY; ret = -EBUSY;
if (part->bd_openers) if (atomic_read(&part->bd_openers))
goto out_unlock; goto out_unlock;
delete_partition(part); delete_partition(part);
......
...@@ -44,7 +44,7 @@ struct block_device { ...@@ -44,7 +44,7 @@ struct block_device {
unsigned long bd_stamp; unsigned long bd_stamp;
bool bd_read_only; /* read-only policy */ bool bd_read_only; /* read-only policy */
dev_t bd_dev; dev_t bd_dev;
int bd_openers; atomic_t bd_openers;
struct inode * bd_inode; /* will die */ struct inode * bd_inode; /* will die */
struct super_block * bd_super; struct super_block * bd_super;
void * bd_claiming; void * bd_claiming;
......
...@@ -188,7 +188,7 @@ static inline bool disk_live(struct gendisk *disk) ...@@ -188,7 +188,7 @@ static inline bool disk_live(struct gendisk *disk)
*/ */
static inline unsigned int disk_openers(struct gendisk *disk) static inline unsigned int disk_openers(struct gendisk *disk)
{ {
return disk->part0->bd_openers; return atomic_read(&disk->part0->bd_openers);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment