On Thu, Jun 08, 2023 at 01:02:29PM +0200, Christoph Hellwig wrote: > --- 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); > + } [with apologies for very late (and tangential) reply] That got me curious about the ->bd_openers - do we need it atomic? Most of the users (and all places that do modifications) are under ->open_mutex; the only exceptions are * early sync logics in blkdev_put(); it's explicitly racy - see the comment there. * callers of disk_openers() in loop and nbd (the ones in zram are under ->open_mutex). There's driver-private exclusion around those, but in any case - READ_ONCE() is no worse than atomic_read() in those cases. Is there something subtle I'm missing here?