Skip to content

Commit 01d0c69

Browse files
Christoph Hellwigaxboe
authored andcommitted
sr: implement ->free_disk to simplify refcounting
Simplify the refcounting and remove the need to clear disk->private_data by implementing the ->free_disk method. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Link: https://lore.kernel.org/r/20220308055200.735835-9-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 9c63f7f commit 01d0c69

File tree

2 files changed

+26
-102
lines changed

2 files changed

+26
-102
lines changed

drivers/scsi/sr.c

Lines changed: 26 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,6 @@ static DEFINE_SPINLOCK(sr_index_lock);
109109

110110
static struct lock_class_key sr_bio_compl_lkclass;
111111

112-
/* This semaphore is used to mediate the 0->1 reference get in the
113-
* face of object destruction (i.e. we can't allow a get on an
114-
* object after last put) */
115-
static DEFINE_MUTEX(sr_ref_mutex);
116-
117112
static int sr_open(struct cdrom_device_info *, int);
118113
static void sr_release(struct cdrom_device_info *);
119114

@@ -143,8 +138,6 @@ static const struct cdrom_device_ops sr_dops = {
143138
.capability = SR_CAPABILITIES,
144139
};
145140

146-
static void sr_kref_release(struct kref *kref);
147-
148141
static inline struct scsi_cd *scsi_cd(struct gendisk *disk)
149142
{
150143
return disk->private_data;
@@ -163,38 +156,6 @@ static int sr_runtime_suspend(struct device *dev)
163156
return 0;
164157
}
165158

166-
/*
167-
* The get and put routines for the struct scsi_cd. Note this entity
168-
* has a scsi_device pointer and owns a reference to this.
169-
*/
170-
static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
171-
{
172-
struct scsi_cd *cd = NULL;
173-
174-
mutex_lock(&sr_ref_mutex);
175-
if (disk->private_data == NULL)
176-
goto out;
177-
cd = scsi_cd(disk);
178-
kref_get(&cd->kref);
179-
if (scsi_device_get(cd->device)) {
180-
kref_put(&cd->kref, sr_kref_release);
181-
cd = NULL;
182-
}
183-
out:
184-
mutex_unlock(&sr_ref_mutex);
185-
return cd;
186-
}
187-
188-
static void scsi_cd_put(struct scsi_cd *cd)
189-
{
190-
struct scsi_device *sdev = cd->device;
191-
192-
mutex_lock(&sr_ref_mutex);
193-
kref_put(&cd->kref, sr_kref_release);
194-
scsi_device_put(sdev);
195-
mutex_unlock(&sr_ref_mutex);
196-
}
197-
198159
static unsigned int sr_get_events(struct scsi_device *sdev)
199160
{
200161
u8 buf[8];
@@ -522,15 +483,13 @@ static void sr_revalidate_disk(struct scsi_cd *cd)
522483

523484
static int sr_block_open(struct block_device *bdev, fmode_t mode)
524485
{
525-
struct scsi_cd *cd;
526-
struct scsi_device *sdev;
486+
struct scsi_cd *cd = cd = scsi_cd(bdev->bd_disk);
487+
struct scsi_device *sdev = cd->device;
527488
int ret = -ENXIO;
528489

529-
cd = scsi_cd_get(bdev->bd_disk);
530-
if (!cd)
531-
goto out;
490+
if (scsi_device_get(cd->device))
491+
return -ENXIO;
532492

533-
sdev = cd->device;
534493
scsi_autopm_get_device(sdev);
535494
if (bdev_check_media_change(bdev))
536495
sr_revalidate_disk(cd);
@@ -541,9 +500,7 @@ static int sr_block_open(struct block_device *bdev, fmode_t mode)
541500

542501
scsi_autopm_put_device(sdev);
543502
if (ret)
544-
scsi_cd_put(cd);
545-
546-
out:
503+
scsi_device_put(cd->device);
547504
return ret;
548505
}
549506

@@ -555,7 +512,7 @@ static void sr_block_release(struct gendisk *disk, fmode_t mode)
555512
cdrom_release(&cd->cdi, mode);
556513
mutex_unlock(&cd->lock);
557514

558-
scsi_cd_put(cd);
515+
scsi_device_put(cd->device);
559516
}
560517

561518
static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
@@ -595,18 +552,24 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
595552
static unsigned int sr_block_check_events(struct gendisk *disk,
596553
unsigned int clearing)
597554
{
598-
unsigned int ret = 0;
599-
struct scsi_cd *cd;
555+
struct scsi_cd *cd = disk->private_data;
600556

601-
cd = scsi_cd_get(disk);
602-
if (!cd)
557+
if (atomic_read(&cd->device->disk_events_disable_depth))
603558
return 0;
559+
return cdrom_check_events(&cd->cdi, clearing);
560+
}
604561

605-
if (!atomic_read(&cd->device->disk_events_disable_depth))
606-
ret = cdrom_check_events(&cd->cdi, clearing);
562+
static void sr_free_disk(struct gendisk *disk)
563+
{
564+
struct scsi_cd *cd = disk->private_data;
607565

608-
scsi_cd_put(cd);
609-
return ret;
566+
spin_lock(&sr_index_lock);
567+
clear_bit(MINOR(disk_devt(disk)), sr_index_bits);
568+
spin_unlock(&sr_index_lock);
569+
570+
unregister_cdrom(&cd->cdi);
571+
mutex_destroy(&cd->lock);
572+
kfree(cd);
610573
}
611574

612575
static const struct block_device_operations sr_bdops =
@@ -617,6 +580,7 @@ static const struct block_device_operations sr_bdops =
617580
.ioctl = sr_block_ioctl,
618581
.compat_ioctl = blkdev_compat_ptr_ioctl,
619582
.check_events = sr_block_check_events,
583+
.free_disk = sr_free_disk,
620584
};
621585

622586
static int sr_open(struct cdrom_device_info *cdi, int purpose)
@@ -660,8 +624,6 @@ static int sr_probe(struct device *dev)
660624
if (!cd)
661625
goto fail;
662626

663-
kref_init(&cd->kref);
664-
665627
disk = __alloc_disk_node(sdev->request_queue, NUMA_NO_NODE,
666628
&sr_bio_compl_lkclass);
667629
if (!disk)
@@ -727,17 +689,17 @@ static int sr_probe(struct device *dev)
727689
sr_revalidate_disk(cd);
728690

729691
error = device_add_disk(&sdev->sdev_gendev, disk, NULL);
730-
if (error) {
731-
kref_put(&cd->kref, sr_kref_release);
732-
goto fail;
733-
}
692+
if (error)
693+
goto unregister_cdrom;
734694

735695
sdev_printk(KERN_DEBUG, sdev,
736696
"Attached scsi CD-ROM %s\n", cd->cdi.name);
737697
scsi_autopm_put_device(cd->device);
738698

739699
return 0;
740700

701+
unregister_cdrom:
702+
unregister_cdrom(&cd->cdi);
741703
fail_minor:
742704
spin_lock(&sr_index_lock);
743705
clear_bit(minor, sr_index_bits);
@@ -1009,48 +971,14 @@ static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf,
1009971
return ret;
1010972
}
1011973

1012-
1013-
/**
1014-
* sr_kref_release - Called to free the scsi_cd structure
1015-
* @kref: pointer to embedded kref
1016-
*
1017-
* sr_ref_mutex must be held entering this routine. Because it is
1018-
* called on last put, you should always use the scsi_cd_get()
1019-
* scsi_cd_put() helpers which manipulate the semaphore directly
1020-
* and never do a direct kref_put().
1021-
**/
1022-
static void sr_kref_release(struct kref *kref)
1023-
{
1024-
struct scsi_cd *cd = container_of(kref, struct scsi_cd, kref);
1025-
struct gendisk *disk = cd->disk;
1026-
1027-
spin_lock(&sr_index_lock);
1028-
clear_bit(MINOR(disk_devt(disk)), sr_index_bits);
1029-
spin_unlock(&sr_index_lock);
1030-
1031-
unregister_cdrom(&cd->cdi);
1032-
1033-
disk->private_data = NULL;
1034-
1035-
put_disk(disk);
1036-
1037-
mutex_destroy(&cd->lock);
1038-
1039-
kfree(cd);
1040-
}
1041-
1042974
static int sr_remove(struct device *dev)
1043975
{
1044976
struct scsi_cd *cd = dev_get_drvdata(dev);
1045977

1046978
scsi_autopm_get_device(cd->device);
1047979

1048980
del_gendisk(cd->disk);
1049-
dev_set_drvdata(dev, NULL);
1050-
1051-
mutex_lock(&sr_ref_mutex);
1052-
kref_put(&cd->kref, sr_kref_release);
1053-
mutex_unlock(&sr_ref_mutex);
981+
put_disk(cd->disk);
1054982

1055983
return 0;
1056984
}

drivers/scsi/sr.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#ifndef _SR_H
1919
#define _SR_H
2020

21-
#include <linux/kref.h>
2221
#include <linux/mutex.h>
2322

2423
#define MAX_RETRIES 3
@@ -51,9 +50,6 @@ typedef struct scsi_cd {
5150

5251
struct cdrom_device_info cdi;
5352
struct mutex lock;
54-
/* We hold gendisk and scsi_device references on probe and use
55-
* the refs on this kref to decide when to release them */
56-
struct kref kref;
5753
struct gendisk *disk;
5854
} Scsi_CD;
5955

0 commit comments

Comments
 (0)