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 <si...@octiron.net>
---
 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

Reply via email to