[PATCH 2/2] Fix standby timers

Phillip Susi psusi at ubuntu.com
Sat Jun 14 18:50:53 PDT 2014


If the drive was set to standby after >= 10 minutes of inactivity,
it would never standby because udisks would check every 10 minutes
to see if it was already in standby, and if not, update the SMART
stats, which would reset the standby timer.  This is especially
problematic since many drives enforce a 10 minute minimum standby
timer even if a lower value is specified.

This patch checks the kernel IO stats to see if any other IO has
been done on the drive since the last check, and if not, behaves
as if the drive is already sleeping.

Signed-off-by: Phillip Susi <psusi at ubuntu.com>
---
 src/udiskslinuxdriveata.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/udiskslinuxdriveata.c b/src/udiskslinuxdriveata.c
index 23d0216..84ed5c8 100644
--- a/src/udiskslinuxdriveata.c
+++ b/src/udiskslinuxdriveata.c
@@ -88,6 +88,7 @@ struct _UDisksLinuxDriveAta
   UDisksThreadedJob *selftest_job;
 
   gboolean     secure_erase_in_progress;
+  unsigned long driveread, drivewrite;
 };
 
 struct _UDisksLinuxDriveAtaClass
@@ -558,8 +559,29 @@ udisks_linux_drive_ata_refresh_smart_sync (UDisksLinuxDriveAta  *drive,
       if (!get_pm_state(device, error, &count))
         goto out;
       awake = count == 0xFF || count == 0x80;
+      const gchar *drivepath = g_udev_device_get_sysfs_path (device->udev_device);
+      gchar *statpath = alloca (1024);
+      unsigned long driveread, drivewrite;
+      gboolean noio = FALSE;
+      FILE *statf;
+      snprintf (statpath, 1024, "%s/stat", drivepath);
+      statf = fopen (statpath, "r");
+      if (statf == NULL)
+        {
+          udisks_warning ("Failed to open %s\n", statpath);
+        }
+      else
+        {
+          fscanf (statf, "%lud %*d %*d %*d %lud", &driveread, &drivewrite);
+          fclose (statf);
+          noio = driveread == drive->driveread && drivewrite == drive->drivewrite;
+          udisks_debug ("driveread=%lu, drivewrite=%lu, old_driveread=%lu, old_drivewrite=%lu\n",
+                        driveread, drivewrite, drive->driveread, drive->drivewrite);
+          drive->driveread = driveread;
+          drive->drivewrite = drivewrite;
+        }
       /* don't wake up disk unless specically asked to */
-      if (nowakeup && !awake)
+      if (nowakeup && (!awake || noio))
         {
           g_set_error (error,
                        UDISKS_ERROR,
-- 
1.9.1



More information about the devkit-devel mailing list