FAILED: patch "[PATCH] scsi: sd: fix missing put_disk() when device_add(&disk_dev)" failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 1e111c4b3a726df1254670a5cc4868cedb946d37
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026050456-overview-shaking-6135@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 1e111c4b3a726df1254670a5cc4868cedb946d37 Mon Sep 17 00:00:00 2001
From: Yang Xiuwei <[email protected]>
Date: Mon, 30 Mar 2026 09:49:52 +0800
Subject: [PATCH] scsi: sd: fix missing put_disk() when device_add(&disk_dev)
fails
If device_add(&sdkp->disk_dev) fails, put_device() runs scsi_disk_release(), which frees the scsi_disk but leaves the gendisk referenced. The device_add_disk() error path in sd_probe() calls put_disk(gd); call put_disk(gd) here to mirror that cleanup.
drivers/scsi/sd.c +1 -0
@@ -4061,6 +4061,7 @@ static int sd_probe(struct scsi_device *sdp) error =device_add (&sdkp->disk_dev);if (error) {put_device (&sdkp->disk_dev); +put_disk (gd); goto out; }
Sasha Levin
maintainerPATCH 1/4 scsi: core: pm: Rely on the device driver core for async power management
From: Bart Van Assche <[email protected]>
[ Upstream commit a19a93e4c6a98c9c0f2f5a6db76846f10d7d1f85 ]
Instead of implementing asynchronous resume support in the SCSI core, rely on the device driver core for resuming SCSI devices asynchronously. Instead of only supporting asynchronous resumes, also support asynchronous suspends.
Stable-dep-of: 1e111c4b3a72 ("scsi: sd: fix missing put_disk() when device_add(&disk_dev) fails")
--- drivers/scsi/hosts.c | 1 + drivers/scsi/scsi.c | 8 ------- drivers/scsi/scsi_pm.c | 44 ++------------------------------------- drivers/scsi/scsi_priv.h | 4 +--- drivers/scsi/scsi_scan.c | 17 +++++++++++++++ drivers/scsi/scsi_sysfs.c | 1 + drivers/scsi/sd.c | 1 - 7 files changed, 22 insertions(+), 54 deletions(-)
drivers/scsi/hosts.c +1 -0
@@ -487,6 +487,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)dev_set_name (&shost->shost_gendev,"host%d" , shost->host_no); shost->shost_gendev.bus = &scsi_bus_type; shost->shost_gendev.type = &scsi_host_type; +scsi_enable_async_suspend (&shost->shost_gendev);device_initialize (&shost->shost_dev); shost->shost_dev.parent = &shost->shost_gendev;
drivers/scsi/scsi.c +0 -8
@@ -86,14 +86,6 @@ unsigned int scsi_logging_level;EXPORT_SYMBOL (scsi_logging_level);#endif -/* -* Domain for asynchronous system resume operations. It is marked 'exclusive' -* to avoid being included in the async_synchronize_full() that is invoked by -* dpm_resume(). -*/ -ASYNC_DOMAIN_EXCLUSIVE (scsi_sd_pm_domain); -EXPORT_SYMBOL (scsi_sd_pm_domain); -#ifdef CONFIG_SCSI_LOGGING void scsi_log_send (struct scsi_cmnd *cmd) {
drivers/scsi/scsi_pm.c +2 -42
59 lines not on this page · raw message
drivers/scsi/scsi_priv.h +1 -3
@@ -117,7 +117,7 @@ extern void scsi_exit_procfs(void);#endif /* CONFIG_PROC_FS */ /* scsi_scan.c */ -extern char scsi_scan_type[]; +void scsi_enable_async_suspend (struct device *dev);extern int scsi_complete_async_scans (void );extern int scsi_scan_host_selected (struct Scsi_Host *,unsigned int ,unsigned int ,u64 ,enum scsi_scan_mode );
@@ -171,8 +171,6 @@ static inline int scsi_autopm_get_host(struct Scsi_Host *h) { return 0; }static inline void scsi_autopm_put_host (struct Scsi_Host *h) {}#endif /* CONFIG_PM */ -extern struct async_domain scsi_sd_pm_domain; -/* scsi_dh.c */ #ifdef CONFIG_SCSI_DH void scsi_dh_add_device (struct scsi_device *sdev);
drivers/scsi/scsi_scan.c +17 -0
@@ -122,6 +122,22 @@ struct async_scan_data {struct completion prev_finished; }; +/** +* scsi_enable_async_suspend - Enable async suspend and resume +*/ +void scsi_enable_async_suspend (struct device *dev) +{ +/* +* If a user has disabled async probing a likely reason is due to a +* storage enclosure that does not inject staggered spin-ups. For +* safety, make resume synchronous as well in that case. +*/ +if (strncmp (scsi_scan_type,"async" ,5 ) !=0 ) +return ; +/* Enable asynchronous suspend and resume. */ +device_enable_async_suspend (dev); +} +/** * scsi_complete_async_scans - Wait for asynchronous scans to complete *
@@ -499,6 +515,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,dev_set_name (dev,"target%d:%d:%d" , shost->host_no, channel, id); dev->bus = &scsi_bus_type; dev->type = &scsi_target_type; +scsi_enable_async_suspend (dev); starget->id = id; starget->channel = channel; starget->can_queue =0 ;
drivers/scsi/scsi_sysfs.c +1 -0
@@ -1643,6 +1643,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)device_initialize (&sdev->sdev_gendev); sdev->sdev_gendev.bus = &scsi_bus_type; sdev->sdev_gendev.type = &scsi_dev_type; +scsi_enable_async_suspend (&sdev->sdev_gendev);dev_set_name (&sdev->sdev_gendev,"%d:%d:%d:%llu" , sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
drivers/scsi/sd.c +0 -1
@@ -3505,7 +3505,6 @@ static int sd_remove(struct device *dev) sdkp =dev_get_drvdata (dev);scsi_autopm_get_device (sdkp->device); -async_synchronize_full_domain (&scsi_sd_pm_domain);device_del (&sdkp->dev);del_gendisk (sdkp->disk);sd_shutdown (dev);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/4 scsi: sd: Add error handling support for add_disk()
From: Luis Chamberlain <[email protected]>
[ Upstream commit 2a7a891f4c406822801ecd676b076c64de072c9e ]
We never checked for errors on add_disk() as this function returned void. Now that this is fixed, use the shiny new error handling.
As with the error handling for device_add() we follow the same logic and just put the device so that cleanup is done via the scsi_disk_release().
Stable-dep-of: 1e111c4b3a72 ("scsi: sd: fix missing put_disk() when device_add(&disk_dev) fails")
--- drivers/scsi/sd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/scsi/sd.c +7 -1
@@ -3458,7 +3458,13 @@ static int sd_probe(struct device *dev)pm_runtime_set_autosuspend_delay (dev, sdp->host->hostt->rpm_autosuspend_delay); } -device_add_disk (dev, gd,NULL ); + + error =device_add_disk (dev, gd,NULL ); +if (error) { +put_device (&sdkp->dev); + goto out; + } +if (sdkp->capacity)sd_dif_config_host (sdkp);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/4 sd: rename the scsi_disk.dev field
In reply to Sasha LevinFrom: Christoph Hellwig <[email protected]>
[ Upstream commit fad45c3007a18064da759b4dba35eb722bc64e97 ]
dev is very hard to grep for. Give the field a more descriptive name and documents its purpose.
Stable-dep-of: 1e111c4b3a72 ("scsi: sd: fix missing put_disk() when device_add(&disk_dev) fails")
--- drivers/scsi/sd.c | 22 +++++++++++----------- drivers/scsi/sd.h | 9 +++++++-- 2 files changed, 18 insertions(+), 13 deletions(-)
drivers/scsi/sd.c +11 -11
@@ -674,7 +674,7 @@ static struct scsi_disk *scsi_disk_get(struct gendisk *disk)if (disk->private_data) { sdkp =scsi_disk (disk);if (scsi_device_get (sdkp->device) ==0 ) -get_device (&sdkp->dev); +get_device (&sdkp->disk_dev);else sdkp =NULL ; }
@@ -687,7 +687,7 @@ static void scsi_disk_put(struct scsi_disk *sdkp)struct scsi_device *sdev = sdkp->device;mutex_lock (&sd_ref_mutex); -put_device (&sdkp->dev); +put_device (&sdkp->disk_dev);scsi_device_put (sdev);mutex_unlock (&sd_ref_mutex); }
@@ -3412,14 +3412,14 @@ static int sd_probe(struct device *dev) SD_MOD_TIMEOUT); } -device_initialize (&sdkp->dev); - sdkp->dev.parent =get_device (dev); - sdkp->dev.class = &sd_disk_class; -dev_set_name (&sdkp->dev,"%s" ,dev_name (dev)); +device_initialize (&sdkp->disk_dev); + sdkp->disk_dev.parent =get_device (dev); + sdkp->disk_dev.class = &sd_disk_class; +dev_set_name (&sdkp->disk_dev,"%s" ,dev_name (dev)); - error =device_add (&sdkp->dev); + error =device_add (&sdkp->disk_dev);if (error) { -put_device (&sdkp->dev); +put_device (&sdkp->disk_dev); goto out; }
@@ -3461,7 +3461,7 @@ static int sd_probe(struct device *dev) error =device_add_disk (dev, gd,NULL );if (error) { -put_device (&sdkp->dev); +put_device (&sdkp->disk_dev); goto out; }
@@ -3511,7 +3511,7 @@ static int sd_remove(struct device *dev) sdkp =dev_get_drvdata (dev);scsi_autopm_get_device (sdkp->device); -device_del (&sdkp->dev); +device_del (&sdkp->disk_dev);del_gendisk (sdkp->disk);sd_shutdown (dev);
@@ -3519,7 +3519,7 @@ static int sd_remove(struct device *dev)mutex_lock (&sd_ref_mutex);dev_set_drvdata (dev,NULL ); -put_device (&sdkp->dev); +put_device (&sdkp->disk_dev);mutex_unlock (&sd_ref_mutex);return 0 ;
drivers/scsi/sd.h +7 -2
@@ -70,7 +70,12 @@ enum {struct scsi_disk {struct scsi_driver *driver;/* always &sd_template */ struct scsi_device *device; -struct device dev; + +/* +* disk_dev is used to show attributes in /sys/class/scsi_disk/, +* but otherwise not really needed. Do not use for refcounting. +*/ +struct device disk_dev;struct gendisk *disk;struct opal_dev *opal_dev;#ifdef CONFIG_BLK_DEV_ZONED
@@ -126,7 +131,7 @@ struct scsi_disk { unsigned security : 1; unsigned ignore_medium_access_errors : 1; }; -#define to_scsi_disk (obj) container_of(obj,struct scsi_disk,dev) +#define to_scsi_disk (obj) container_of(obj, struct scsi_disk, disk_dev)static inline struct scsi_disk *scsi_disk (struct gendisk *disk) {
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 4/4 scsi: sd: fix missing put_disk() when device_add(&disk_dev) fails
In reply to Sasha LevinFrom: Yang Xiuwei <[email protected]>
[ Upstream commit 1e111c4b3a726df1254670a5cc4868cedb946d37 ]
If device_add(&sdkp->disk_dev) fails, put_device() runs scsi_disk_release(), which frees the scsi_disk but leaves the gendisk referenced. The device_add_disk() error path in sd_probe() calls put_disk(gd); call put_disk(gd) here to mirror that cleanup.
--- drivers/scsi/sd.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/sd.c +1 -0
@@ -3420,6 +3420,7 @@ static int sd_probe(struct device *dev) error =device_add (&sdkp->disk_dev);if (error) {put_device (&sdkp->disk_dev); +put_disk (gd); goto out; }
Signature · 1 line
2.53.0