diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-10-27 13:38:59 -1000 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-10-27 13:38:59 -1000 |
commit | 832328c9f8aa4b41423f29a53ba7080eb7214976 (patch) | |
tree | ccdd094d53ff1bbb103ad8b3a6eed62e9e7d85eb /drivers/scsi | |
parent | a78a67f3019c687d06dee8cebfb7b7cee7bf0216 (diff) | |
parent | 24eca2dce0f8d19db808c972b0281298d0bafe99 (diff) |
Merge tag 'ata-6.6-final' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata
Pull ATA fix from Damien Le Moal:
"A single patch to fix a regression introduced by the recent
suspend/resume fixes.
The regression is that ATA disks are not stopped on system shutdown,
which is not recommended and increases the disks SMART counters for
unclean power off events.
This patch fixes this by refining the recent rework of the scsi device
manage_xxx flags"
* tag 'ata-6.6-final' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata:
scsi: sd: Introduce manage_shutdown device flag
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/sd.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 83b6a3f3863b..6effa13039f3 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -209,7 +209,8 @@ manage_start_stop_show(struct device *dev, return sysfs_emit(buf, "%u\n", sdp->manage_system_start_stop && - sdp->manage_runtime_start_stop); + sdp->manage_runtime_start_stop && + sdp->manage_shutdown); } static DEVICE_ATTR_RO(manage_start_stop); @@ -275,6 +276,35 @@ manage_runtime_start_stop_store(struct device *dev, } static DEVICE_ATTR_RW(manage_runtime_start_stop); +static ssize_t manage_shutdown_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + struct scsi_device *sdp = sdkp->device; + + return sysfs_emit(buf, "%u\n", sdp->manage_shutdown); +} + +static ssize_t manage_shutdown_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + struct scsi_device *sdp = sdkp->device; + bool v; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (kstrtobool(buf, &v)) + return -EINVAL; + + sdp->manage_shutdown = v; + + return count; +} +static DEVICE_ATTR_RW(manage_shutdown); + static ssize_t allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -607,6 +637,7 @@ static struct attribute *sd_disk_attrs[] = { &dev_attr_manage_start_stop.attr, &dev_attr_manage_system_start_stop.attr, &dev_attr_manage_runtime_start_stop.attr, + &dev_attr_manage_shutdown.attr, &dev_attr_protection_type.attr, &dev_attr_protection_mode.attr, &dev_attr_app_tag_own.attr, @@ -3819,8 +3850,10 @@ static void sd_shutdown(struct device *dev) sd_sync_cache(sdkp, NULL); } - if (system_state != SYSTEM_RESTART && - sdkp->device->manage_system_start_stop) { + if ((system_state != SYSTEM_RESTART && + sdkp->device->manage_system_start_stop) || + (system_state == SYSTEM_POWER_OFF && + sdkp->device->manage_shutdown)) { sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); sd_start_stop_device(sdkp, 0); } |