I need to use "reboot=p" on my desktop because one of the PCIe devices does not appear after a warm boot. This results in a very cold boot because the BIOS turns the PSU off and on. The scsi sd shutdown process does not send a stop command to disks before the reboot happens (stop commands are only sent for a shutdown). The result is that all of my SSDs experience a sudden power loss on every reboot, which is undesirable behaviour because it could cause data to be corrupted. These events are recorded in the SMART attributes. Add a "stop_before_reboot" module parameter that can be used to control the shutdown behaviour of disks before a reboot. The default will be the existing behaviour (disks are not stopped). sd_mod.stop_before_reboot=<integer> 0 = disabled (default) 1 = enabled The behaviour on shutdown is unchanged: all disks are unconditionally stopped. Signed-off-by: Simon Arlott <simon@xxxxxxxxxxx> --- Documentation/scsi/scsi-parameters.rst | 5 +++++ drivers/scsi/sd.c | 14 +++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Documentation/scsi/scsi-parameters.rst b/Documentation/scsi/scsi-parameters.rst index 9aba897c97ac..324610870de5 100644 --- a/Documentation/scsi/scsi-parameters.rst +++ b/Documentation/scsi/scsi-parameters.rst @@ -101,6 +101,11 @@ parameters may be changed at runtime by the command allowing boot to proceed. none ignores them, expecting user space to do the scan. + sd_mod.stop_before_reboot= + [SCSI] configure stop action for disks before a reboot + Format: <integer> + 0 = disabled (default), 1 = enabled + sim710= [SCSI,HW] See header of drivers/scsi/sim710.c. diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d90fefffe31b..506904bf15da 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -98,6 +98,12 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC); +static unsigned int stop_before_reboot = 0; + +module_param(stop_before_reboot, uint, 0644); +MODULE_PARM_DESC(stop_before_reboot, + "stop disks before reboot"); + #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) #define SD_MINORS 16 #else @@ -3576,9 +3582,11 @@ static void sd_shutdown(struct device *dev) sd_sync_cache(sdkp, NULL); } - if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); - sd_start_stop_device(sdkp, 0); + if (sdkp->device->manage_start_stop) { + if (system_state != SYSTEM_RESTART || stop_before_reboot) { + sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); + sd_start_stop_device(sdkp, 0); + } } } -- 2.17.1 -- Simon Arlott