ATA fixes for 6.6-final

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.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQSRPv8tYSvhwAzJdzjdoc3SxdoYdgUCZTtnHAAKCRDdoc3SxdoY
 dqksAP95dLIScPn8PTW2oy2O+LHW1g67XVziTY5nce7byqNJwQEA/q8cRw2LYzB3
 ELPZElQzlAgD47JqC2YFIHbomnqEagU=
 =fC3T
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2023-10-27 13:38:59 -10:00
commit 832328c9f8
4 changed files with 58 additions and 7 deletions

View File

@ -1053,10 +1053,11 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev)
/*
* Ask the sd driver to issue START STOP UNIT on runtime suspend
* and resume only. For system level suspend/resume, devices
* power state is handled directly by libata EH.
* and resume and shutdown only. For system level suspend/resume,
* devices power state is handled directly by libata EH.
*/
sdev->manage_runtime_start_stop = true;
sdev->manage_shutdown = true;
}
/*

View File

@ -1521,6 +1521,7 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
if (sbp2_param_exclusive_login) {
sdev->manage_system_start_stop = true;
sdev->manage_runtime_start_stop = true;
sdev->manage_shutdown = true;
}
if (sdev->type == TYPE_ROM)

View File

@ -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);
}

View File

@ -162,8 +162,24 @@ struct scsi_device {
* core. */
unsigned int eh_timeout; /* Error handling timeout */
bool manage_system_start_stop; /* Let HLD (sd) manage system start/stop */
bool manage_runtime_start_stop; /* Let HLD (sd) manage runtime start/stop */
/*
* If true, let the high-level device driver (sd) manage the device
* power state for system suspend/resume (suspend to RAM and
* hibernation) operations.
*/
bool manage_system_start_stop;
/*
* If true, let the high-level device driver (sd) manage the device
* power state for runtime device suspand and resume operations.
*/
bool manage_runtime_start_stop;
/*
* If true, let the high-level device driver (sd) manage the device
* power state for system shutdown (power off) operations.
*/
bool manage_shutdown;
unsigned removable:1;
unsigned changed:1; /* Data invalid due to media change */