Hello community,

here is the log from the commit of package hdparm for openSUSE:Factory checked 
in at 2012-10-03 07:45:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hdparm (Old)
 and      /work/SRC/openSUSE:Factory/.hdparm.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "hdparm", Maintainer is "vdziewie...@suse.com"

Changes:
--------
--- /work/SRC/openSUSE:Factory/hdparm/hdparm.changes    2012-03-07 
13:42:36.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.hdparm.new/hdparm.changes       2012-10-03 
07:45:29.000000000 +0200
@@ -1,0 +2,18 @@
+Mon Oct  1 10:53:29 UTC 2012 - pu...@suse.com
+
+- update to hdparm-9.42
+  - fix ordering of -S -y flags
+  - spelling, typo, and formatting fixes for manpage and others
+  - set block-count to 1 for Security commands sent via SAT (sgio)
+  - use FIGETBSZ to determine filesystem block size for fibmap -- needed for 
FAT
+  - fix master password revcode handling
+  - try and fix reg_flags (again!) for old IDE taskfile ioctls
+  - fixed '&&' bug in dco_identify code
+  - force sector dumps (read-sector, identify, ..) to use le16 output format
+  - proper SCT identify info courtesy of Leonid Evdokimov <l...@darkk.net.ru>
+  - updated raid1ext4trim.sh-1.5 script
+  - avoid HDIO_GETGEO_BIG when possible (doesn't exist in
+    linux-2.6.xx and beyond)
+  - pad secure erase timeouts by 30minutes rather than 5minutes.
+
+-------------------------------------------------------------------

Old:
----
  hdparm-9.39.tar.gz

New:
----
  hdparm-9.42.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ hdparm.spec ++++++
--- /var/tmp/diff_new_pack.NKje3M/_old  2012-10-03 07:45:30.000000000 +0200
+++ /var/tmp/diff_new_pack.NKje3M/_new  2012-10-03 07:45:30.000000000 +0200
@@ -19,7 +19,7 @@
 Name:           hdparm
 PreReq:         %insserv_prereq %fillup_prereq coreutils
 Provides:       base:/sbin/hdparm
-Version:        9.39
+Version:        9.42
 Release:        0
 Summary:        A Program to get and set hard disk parameters
 License:        SUSE-Permissive

++++++ hdparm-9.39.tar.gz -> hdparm-9.42.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/Changelog new/hdparm-9.42/Changelog
--- old/hdparm-9.39/Changelog   2012-02-06 14:45:27.000000000 +0100
+++ new/hdparm-9.42/Changelog   2012-09-28 20:10:36.000000000 +0200
@@ -1,3 +1,18 @@
+hdparm-9.42
+       - fix ordering of -S -y flags
+       - spelling, typo, and formatting fixes for manpage and others
+       - set block-count to 1 for Security commands sent via SAT (sgio)
+       - use FIGETBSZ to determine filesystem block size for fibmap -- needed 
for FAT
+       - fix master password revcode handling
+       - try and fix reg_flags (again!) for old IDE taskfile ioctls
+       - fixed '&&' bug in dco_identify code
+       - force sector dumps (read-sector, identify, ..) to use le16 output 
format
+hdparm-9.41
+       - proper SCT identify info courtesy of Leonid Evdokimov 
<l...@darkk.net.ru>
+       - updated raid1ext4trim.sh-1.5 script
+hdparm-9.40
+       - avoid HDIO_GETGEO_BIG when possible (doesn't exist in linux-2.6.xx 
and beyond)
+       - pad secure erase timeouts by 30minutes rather than 5minutes.
 hdparm-9.39
        - added -R flag to control Read-Write-Verify feature, courtesy of 
Gordan Bobic
        - nuked leftover sgio.c.orig file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/TODO new/hdparm-9.42/TODO
--- old/hdparm-9.39/TODO        2010-03-09 15:20:02.000000000 +0100
+++ new/hdparm-9.42/TODO        2012-09-28 18:51:04.000000000 +0200
@@ -1,8 +1,6 @@
 Mark's TO-DO list for hdparm:
 ============================
 
-- Make parameter parsing/etc.. LBA48 safe everywhere (instead of merely u32).
-
 - Add "wipe-drive" functionality via SCT WRITE_SAME (or manual).
 
 - Add "surface-scan" functionality via SG READ_VERIFY.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/fibmap.c new/hdparm-9.42/fibmap.c
--- old/hdparm-9.39/fibmap.c    2010-11-24 22:20:17.000000000 +0100
+++ new/hdparm-9.42/fibmap.c    2012-09-28 19:40:23.000000000 +0200
@@ -222,7 +222,7 @@
        int fd, err;
        struct stat st;
        __u64 start_lba = 0;
-       unsigned int sectors_per_block;
+       unsigned int sectors_per_block, blksize;
 
        if ((fd = open(file_name, O_RDONLY)) == -1) {
                err = errno;
@@ -253,11 +253,15 @@
                close(fd);
                return EIO;
        }
-
-       sectors_per_block = st.st_blksize / sector_bytes;
-       printf("\n%s:\n filesystem blocksize %lu, begins at LBA %llu;"
+       if((err=ioctl(fd,FIGETBSZ,&blksize))){
+               fprintf(stderr, "Unable to determine block size, aborting.\n");
+               close(fd);
+               return err;
+       };
+       sectors_per_block = blksize / sector_bytes;
+       printf("\n%s:\n filesystem blocksize %u, begins at LBA %llu;"
               " assuming %u byte sectors.\n",
-              file_name, (unsigned long)st.st_blksize, start_lba, 
sector_bytes);
+              file_name, blksize, start_lba, sector_bytes);
        printf("%12s %10s %10s %10s\n", "byte_offset", "begin_LBA", "end_LBA", 
"sectors");
 
        if (st.st_size == 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/geom.c new/hdparm-9.42/geom.c
--- old/hdparm-9.39/geom.c      2010-11-24 22:54:48.000000000 +0100
+++ new/hdparm-9.42/geom.c      2012-05-04 15:20:57.000000000 +0200
@@ -144,7 +144,7 @@
 {
        static struct local_hd_geometry      g;
        static struct local_hd_big_geometry bg;
-       int err = 0;
+       int err = 0, try_getgeo_big_first = 1;
 
        if (nsectors) {
                err = get_sector_count(fd, nsectors);
@@ -163,14 +163,17 @@
                {
                        *start_lba = result;
                         start_lba = NULL;
+                       try_getgeo_big_first = 0;       /* if kernel has sysfs, 
it probably lacks GETGEO_BIG */
                } else if (fd_is_raid(fd)) {
-                       *start_lba = START_LBA_UNKNOWN;  /* RAID: no such thing 
as a "start_lba" */
+                       *start_lba = START_LBA_UNKNOWN; /* RAID: no such thing 
as a "start_lba" */
                         start_lba = NULL;
+                       try_getgeo_big_first = 0;       /* no point even trying 
it on RAID */
                }
        }
 
        if (cyls || heads || sects || start_lba) {
-               if (!ioctl(fd, HDIO_GETGEO_BIG, &bg)) {
+               /* Skip HDIO_GETGEO_BIG (doesn't exist) on kernels with sysfs 
(>= 2.6.xx) */
+               if (try_getgeo_big_first && !ioctl(fd, HDIO_GETGEO_BIG, &bg)) {
                        if (cyls)       *cyls  = bg.cylinders;
                        if (heads)      *heads = bg.heads;
                        if (sects)      *sects = bg.sectors;
@@ -180,6 +183,11 @@
                        if (heads)      *heads = g.heads;
                        if (sects)      *sects = g.sectors;
                        if (start_lba)  *start_lba = g.start;
+               } else if (!try_getgeo_big_first && !ioctl(fd, HDIO_GETGEO_BIG, 
&bg)) {
+                       if (cyls)       *cyls  = bg.cylinders;
+                       if (heads)      *heads = bg.heads;
+                       if (sects)      *sects = bg.sectors;
+                       if (start_lba)  *start_lba = bg.start;
                } else {
                        err = errno;
                        perror(" HDIO_GETGEO failed");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/hdparm.8 new/hdparm-9.42/hdparm.8
--- old/hdparm-9.39/hdparm.8    2012-02-03 04:24:42.000000000 +0100
+++ new/hdparm-9.42/hdparm.8    2012-09-28 20:12:12.000000000 +0200
@@ -1,4 +1,4 @@
-.TH HDPARM 8 "January 2012" "Version 9.39"
+.TH HDPARM 8 "September 2012" "Version 9.42"
 
 .SH NAME
 hdparm \- get/set SATA/IDE device parameters
@@ -346,9 +346,9 @@
 option should therefore only be set after one has achieved confidence in
 correct system operation with a chosen set of configuration settings.
 In practice, all that is typically necessary to test a configuration
-(prior to using -k) is to verify that the drive can be read/written,
+(prior to using \-k) is to verify that the drive can be read/written,
 and that no error logs (kernel messages) are generated in the process
-(look in /var/adm/messages on most systems).
+(look in /var/log/messages on most systems).
 .TP
 .I -K
 Set the drive\'s "keep_features_over_reset" flag.  Setting this enables
@@ -579,7 +579,7 @@
 share a power supply.  Primarily for use in large RAID setups.
 This feature is usually disabled and the drive is powered-up in the
 .B active
-mode (see -C above).
+mode (see \-C above).
 Note that a drive may also allow enabling this feature by a jumper.
 Some SATA drives support the control of this feature by pin 11 of
 the SATA power connector. In these cases, this command may be
@@ -674,7 +674,7 @@
 provides a safe fix for the problem for use with earlier kernels.
 .TP
 .I -v 
-Display some basic settings, similar to -acdgkmur for IDE.
+Display some basic settings, similar to \-acdgkmur for IDE.
 This is also the default behaviour when no options are specified.
 .TP
 .I --verbose 
@@ -767,19 +767,19 @@
 .B USE AT YOUR OWN RISK.
 .TP
 .I --security-help             
-Display terse usage info for all of the --security-* options.
+Display terse usage info for all of the \--security-* options.
 .TP
 .I --security-freeze             
 Freeze the drive\'s security settings.
 The drive does not accept any security commands until next power-on reset.
-Use this function in combination with --security-unlock to protect drive
+Use this function in combination with \--security-unlock to protect drive
 from any attempt to set a new password. Can be used standalone, too.
 No other options are permitted on the command line with this one.
 .TP
 .I --security-unlock PWD 
 Unlock the drive, using password PWD.
 Password is given as an ASCII string and is padded with NULs to reach 32 bytes.
-The applicable drive password is selected with the --user-master switch
+The applicable drive password is selected with the \--user-master switch
 (default is "user" password).
 No other options are permitted on the command line with this one.
 .TP
@@ -790,15 +790,15 @@
 Use the special password
 .B NULL
 to set an empty password.
-The applicable drive password is selected with the --user-master switch
+The applicable drive password is selected with the \--user-master switch
 (default is "user" password)
-and the applicable security mode with the --security-mode switch.
+and the applicable security mode with the \--security-mode switch.
 No other options are permitted on the command line with this one.
 .TP
 .I --security-disable PWD 
 Disable drive locking, using password PWD.
 Password is given as an ASCII string and is padded with NULs to reach 32 bytes.
-The applicable drive password is selected with the --user-master switch
+The applicable drive password is selected with the \--user-master switch
 (default is "user" password).
 No other options are permitted on the command line with this one.
 .TP
@@ -809,7 +809,7 @@
 Use the special password
 .B NULL
 to represent an empty password.
-The applicable drive password is selected with the --user-master switch
+The applicable drive password is selected with the \--user-master switch
 (default is "user" password).
 No other options are permitted on the command line with this one.
 .TP
@@ -817,15 +817,15 @@
 Enhanced erase (locked) drive, using password PWD
 .B (DANGEROUS).
 Password is given as an ASCII string and is padded with NULs to reach 32 bytes.
-The applicable drive password is selected with the --user-master switch
+The applicable drive password is selected with the \--user-master switch
 (default is "user" password).
 No other options are permitted on the command line with this one.
 .TP
 .I --user-master USER
 Specifies which password (user/master) to select.
 .B Defaults to "user" password.
-Only useful in combination with --security-unlock, --security-set-pass,
---security-disable, --security-erase or --security-erase-enhanced.
+Only useful in combination with \--security-unlock, \--security-set-pass,
+\--security-disable, \--security-erase or \--security-erase-enhanced.
         u       user password
         m       master password
 
@@ -833,7 +833,7 @@
 .I --security-mode MODE 
 Specifies which security mode (high/maximum) to set.
 .B Defaults to high.
-Only useful in combination with --security-set-pass.
+Only useful in combination with \--security-set-pass.
         h       high security
         m       maximum security
 
@@ -850,7 +850,7 @@
 a few drive/controller combinations are not 100% compatible.  Filesystem
 corruption may result.  Backup everything before experimenting!
 .PP
-Some options (e.g. -r for SCSI) may not work with old kernels as 
+Some options (e.g. \-r for SCSI) may not work with old kernels as 
 necessary ioctl()\'s were not supported.
 .PP
 Although this utility is intended primarily for use with SATA/IDE hard disk
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/hdparm.c new/hdparm-9.42/hdparm.c
--- old/hdparm-9.39/hdparm.c    2012-02-03 04:24:33.000000000 +0100
+++ new/hdparm-9.42/hdparm.c    2012-09-28 20:12:01.000000000 +0200
@@ -1,5 +1,7 @@
-/* hdparm.c - Command line interface to get/set hard disk parameters */
-/*          - by Mark Lord (C) 1994-2012 -- freely distributable */
+/*
+ * hdparm.c - Command line interface to get/set hard disk parameters.
+ *          - by Mark Lord (C) 1994-2012 -- freely distributable.
+ */
 #define _LARGEFILE64_SOURCE /*for lseek64*/
 #define _BSD_SOURCE    /* for strtoll() */
 #include <unistd.h>
@@ -23,6 +25,7 @@
 #include <linux/types.h>
 #include <linux/fs.h>
 #include <linux/major.h>
+#include <endian.h>
 #include <asm/byteorder.h>
 
 #include "hdparm.h"
@@ -35,7 +38,7 @@
 
 extern const char *minor_str[];
 
-#define VERSION "v9.39"
+#define VERSION "v9.42"
 
 #ifndef O_DIRECT
 #define O_DIRECT       040000  /* direct disk access, not easily obtained from 
headers */
@@ -719,7 +722,7 @@
                                if (timeout < estimate)
                                        timeout = estimate;
                        } else {
-                               timeout = (timeout * 2) + 5;  /* Add on a 5min 
margin */
+                               timeout = (timeout * 2) + 30;  /* Add on a 
30min margin */
                        }
                }
        }
@@ -749,6 +752,8 @@
        r->dphase       = TASKFILE_DPHASE_PIO_OUT;
        r->obytes       = 512;
        r->lob.command  = security_command;
+       r->oflags.lob.nsect = 1;
+       r->lob.nsect        = 1;
        data            = (__u8*)r->data;
        data[0]         = security_master & 0x01;
        memcpy(data+2, security_password, 32);
@@ -777,7 +782,7 @@
                                if (!id)
                                        exit(EIO);
                                revcode = id[92];
-                               if (revcode == 0xffff)
+                               if (revcode == 0xfffe)
                                        revcode = 0;
                                revcode += 1;
                                data[34] = revcode;
@@ -922,8 +927,18 @@
        unsigned int i;
 
        for (i = 0; i < (count*256/8); ++i) {
-               printf("%04x %04x %04x %04x %04x %04x %04x %04x\n", w[0], w[1], 
w[2], w[3], w[4], w[5], w[6], w[7]);
+#if 0
+               printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
+                       w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7]);
                w += 8;
+#else
+               int word;
+               for (word = 0; word < 8; ++word) {
+                       printf("%04x", le16toh(w[0]));
+                       ++w;
+                       putchar(word == 7 ? '\n' : ' ');
+               }
+#endif
        }
 }
 
@@ -1517,7 +1532,7 @@
        " --security-erase    PASSWD  Erase a (locked) drive.\n"
        " --security-erase-enhanced PASSWD   Enhanced-erase a (locked) drive.\n"
        "\n"
-       " The above four commands may optionally be preceeded by these 
options:\n"
+       " The above four commands may optionally be preceded by these 
options:\n"
        " --security-mode  LEVEL      Use LEVEL to select security level:\n"
        "                                  h   high security (default).\n"
        "                                  m   maximum security.\n"
@@ -1841,6 +1856,17 @@
                if (!wcache)
                        err = flush_wcache(fd);
        }
+       if (set_standby) {
+               __u8 args[4] = {ATA_OP_SETIDLE,standby,0,0};
+               if (get_standby) {
+                       printf(" setting standby to %u", standby);
+                       interpret_standby();
+               }
+               if (do_drive_cmd(fd, args, 0)) {
+                       err = errno;
+                       perror(" HDIO_DRIVE_CMD(setidle) failed");
+               }
+       }
        if (set_standbynow) {
                __u8 args1[4] = {ATA_OP_STANDBYNOW1,0,0,0};
                __u8 args2[4] = {ATA_OP_STANDBYNOW2,0,0,0};
@@ -1917,17 +1943,6 @@
                        perror(" HDIO_DRIVE_CMD(seagatepwrsave) failed");
                }
        }
-       if (set_standby) {
-               __u8 args[4] = {ATA_OP_SETIDLE,standby,0,0};
-               if (get_standby) {
-                       printf(" setting standby to %u", standby);
-                       interpret_standby();
-               }
-               if (do_drive_cmd(fd, args, 0)) {
-                       err = errno;
-                       perror(" HDIO_DRIVE_CMD(setidle) failed");
-               }
-       }
        if (set_busstate) {
                if (get_busstate)
                        printf(" setting bus state to %d (%s)\n", busstate, 
busstate_str(busstate));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/hdparm.lsm new/hdparm-9.42/hdparm.lsm
--- old/hdparm-9.39/hdparm.lsm  2012-02-03 04:26:50.000000000 +0100
+++ new/hdparm-9.42/hdparm.lsm  2012-09-28 20:12:45.000000000 +0200
@@ -1,9 +1,12 @@
 Begin4
 Title:         hdparm
-Version:       9.39
-Entered-date:  2012-02-02
+Version:       9.42
+Entered-date:  2012-09-28
 Description:   hdparm - get/set hard disk parameters for Linux SATA/IDE drives.
-               v9.38 Added -R, courtesy of Gordan Bobic
+               v9.42 lots of fixes from the sourceforge queue
+               v9.41 updated SCT identification, other small fixes.
+               v9.40 internal release
+               v9.39 Added -R, courtesy of Gordan Bobic
                v9.38 Added -J, fixed erase timeouts, updated wiper.sh
                v9.37 Enable --fibmap to work on RAID1; other tweaks
                v9.36 manpage updates, wiper.sh version 3.1
@@ -113,7 +116,7 @@
 Maintained-by: ml...@pobox.com (Mark Lord)
 Primary-site:  http://sourceforge.net/projects/hdparm/
 Alternate-site:        http://www.ibiblio.org/pub/Linux/system/hardware
-               127K hdparm-9.39.tar.gz
+               127K hdparm-9.42.tar.gz
                4K hdparm.lsm
 Platforms:     Linux
 Copying-policy:        BSD License
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/identify.c new/hdparm-9.42/identify.c
--- old/hdparm-9.39/identify.c  2011-12-04 23:49:22.000000000 +0100
+++ new/hdparm-9.42/identify.c  2012-09-28 18:55:17.000000000 +0200
@@ -514,8 +514,8 @@
        "SCT Data Tables (AC5)",                        /* word 206 bit  5 */
        "SCT Features Control (AC4)",                   /* word 206 bit  4 */
        "SCT Error Recovery Control (AC3)",             /* word 206 bit  3 */
-       "SCT LBA Segment Access (AC2)",                 /* word 206 bit  2 */
-       "SCT Long Sector Access (AC1)",                 /* word 206 bit  1 */
+       "SCT Write Same (AC2)",                         /* word 206 bit  2 */
+       "SCT Read/Write Long (AC1), obsolete",          /* word 206 bit  1: 
obsolete per T13/e08153r1 */
        "SMART Command Transport (SCT) feature set"     /* word 206 bit  0 */
 };
 
@@ -1473,7 +1473,7 @@
        }
        putchar('\n');
 
-       if (dco[8] && 0x1f) {
+       if (dco[8] & 0x1f) {
                printf("\tSATA command/feature sets:\n\t\t");
                if (dco[0] < 2)
                        printf(" (?):");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/sgio.h new/hdparm-9.42/sgio.h
--- old/hdparm-9.39/sgio.h      2012-01-06 15:45:00.000000000 +0100
+++ new/hdparm-9.42/sgio.h      2012-09-28 19:25:46.000000000 +0200
@@ -115,7 +115,8 @@
        TASKFILE_DPHASE_PIO_OUT = 4,    /* ide: TASKFILE_OUT */
 };
 
-struct reg_flags {
+union reg_flags {
+       unsigned all                            :16;
        union {
                unsigned lob_all                : 8;
                struct {
@@ -142,7 +143,7 @@
                        unsigned command        : 1;
                } hob;
        };
-};
+} __attribute__((packed));
 
 struct taskfile_regs {
        __u8    data;
@@ -158,8 +159,8 @@
 struct hdio_taskfile {
        struct taskfile_regs    lob;
        struct taskfile_regs    hob;
-       struct reg_flags        oflags;
-       struct reg_flags        iflags;
+       union reg_flags         oflags;
+       union reg_flags         iflags;
        int                     dphase;
        int                     cmd_req;     /* IDE command_type */
        unsigned long           obytes;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/sgio.h.xx new/hdparm-9.42/sgio.h.xx
--- old/hdparm-9.39/sgio.h.xx   1970-01-01 01:00:00.000000000 +0100
+++ new/hdparm-9.42/sgio.h.xx   2012-09-28 19:25:46.000000000 +0200
@@ -0,0 +1,233 @@
+/* prototypes and stuff for ATA command ioctls */
+
+#include <linux/types.h>
+
+enum {
+       ATA_OP_DSM                      = 0x06, // Data Set Management (TRIM)
+       ATA_OP_READ_PIO                 = 0x20,
+       ATA_OP_READ_PIO_ONCE            = 0x21,
+       ATA_OP_READ_LONG                = 0x22,
+       ATA_OP_READ_LONG_ONCE           = 0x23,
+       ATA_OP_READ_PIO_EXT             = 0x24,
+       ATA_OP_READ_DMA_EXT             = 0x25,
+       ATA_OP_READ_FPDMA               = 0x60, // NCQ
+       ATA_OP_WRITE_PIO                = 0x30,
+       ATA_OP_WRITE_LONG               = 0x32,
+       ATA_OP_WRITE_LONG_ONCE          = 0x33,
+       ATA_OP_WRITE_PIO_EXT            = 0x34,
+       ATA_OP_WRITE_DMA_EXT            = 0x35,
+       ATA_OP_WRITE_FPDMA              = 0x61, // NCQ
+       ATA_OP_READ_VERIFY              = 0x40,
+       ATA_OP_READ_VERIFY_ONCE         = 0x41,
+       ATA_OP_READ_VERIFY_EXT          = 0x42,
+       ATA_OP_WRITE_UNC_EXT            = 0x45, // lba48, no data, uses feat reg
+       ATA_OP_FORMAT_TRACK             = 0x50,
+       ATA_OP_DOWNLOAD_MICROCODE       = 0x92,
+       ATA_OP_STANDBYNOW2              = 0x94,
+       ATA_OP_CHECKPOWERMODE2          = 0x98,
+       ATA_OP_SLEEPNOW2                = 0x99,
+       ATA_OP_PIDENTIFY                = 0xa1,
+       ATA_OP_READ_NATIVE_MAX          = 0xf8,
+       ATA_OP_READ_NATIVE_MAX_EXT      = 0x27,
+       ATA_OP_SMART                    = 0xb0,
+       ATA_OP_DCO                      = 0xb1,
+       ATA_OP_ERASE_SECTORS            = 0xc0,
+       ATA_OP_READ_DMA                 = 0xc8,
+       ATA_OP_WRITE_DMA                = 0xca,
+       ATA_OP_DOORLOCK                 = 0xde,
+       ATA_OP_DOORUNLOCK               = 0xdf,
+       ATA_OP_STANDBYNOW1              = 0xe0,
+       ATA_OP_IDLEIMMEDIATE            = 0xe1,
+       ATA_OP_SETIDLE                  = 0xe3,
+       ATA_OP_SET_MAX                  = 0xf9,
+       ATA_OP_SET_MAX_EXT              = 0x37,
+       ATA_OP_SET_MULTIPLE             = 0xc6,
+       ATA_OP_CHECKPOWERMODE1          = 0xe5,
+       ATA_OP_SLEEPNOW1                = 0xe6,
+       ATA_OP_FLUSHCACHE               = 0xe7,
+       ATA_OP_FLUSHCACHE_EXT           = 0xea,
+       ATA_OP_IDENTIFY                 = 0xec,
+       ATA_OP_SETFEATURES              = 0xef,
+       ATA_OP_SECURITY_SET_PASS        = 0xf1,
+       ATA_OP_SECURITY_UNLOCK          = 0xf2,
+       ATA_OP_SECURITY_ERASE_PREPARE   = 0xf3,
+       ATA_OP_SECURITY_ERASE_UNIT      = 0xf4,
+       ATA_OP_SECURITY_FREEZE_LOCK     = 0xf5,
+       ATA_OP_SECURITY_DISABLE         = 0xf6,
+       ATA_OP_VENDOR_SPECIFIC_0x80     = 0x80,
+};
+
+/*
+ * Some useful ATA register bits
+ */
+enum {
+       ATA_USING_LBA           = (1 << 6),
+       ATA_STAT_DRQ            = (1 << 3),
+       ATA_STAT_ERR            = (1 << 0),
+};
+
+/*
+ * Useful parameters for init_hdio_taskfile():
+ */
+enum { RW_READ                 = 0,
+       RW_WRITE                = 1,
+       LBA28_OK                = 0,
+       LBA48_FORCE             = 1,
+};
+
+/*
+ * Definitions and structures for use with SG_IO + ATA_16:
+ */
+struct ata_lba_regs {
+       __u8    feat;
+       __u8    nsect;
+       __u8    lbal;
+       __u8    lbam;
+       __u8    lbah;
+};
+struct ata_tf {
+       __u8                    dev;
+       __u8                    command;
+       __u8                    error;
+       __u8                    status;
+       __u8                    is_lba48;
+       struct ata_lba_regs     lob;
+       struct ata_lba_regs     hob;
+};
+
+/*
+ * Definitions and structures for use with HDIO_DRIVE_TASKFILE:
+ */
+
+enum {
+       /*
+        * These (redundantly) specify the category of the request
+        */
+       TASKFILE_CMD_REQ_NODATA = 0,    /* ide: IDE_DRIVE_TASK_NO_DATA */
+       TASKFILE_CMD_REQ_IN     = 2,    /* ide: IDE_DRIVE_TASK_IN */
+       TASKFILE_CMD_REQ_OUT    = 3,    /* ide: IDE_DRIVE_TASK_OUT */
+       TASKFILE_CMD_REQ_RAW_OUT= 4,    /* ide: IDE_DRIVE_TASK_RAW_WRITE */
+       /*
+        * These specify the method of transfer (pio, dma, multi, ..)
+        */
+       TASKFILE_DPHASE_NONE    = 0,    /* ide: TASKFILE_IN */
+       TASKFILE_DPHASE_PIO_IN  = 1,    /* ide: TASKFILE_IN */
+       TASKFILE_DPHASE_PIO_OUT = 4,    /* ide: TASKFILE_OUT */
+};
+
+union reg_flags {
+       unsigned all                            :16;
+       union {
+               unsigned lob_all                : 8;
+               struct {
+                       unsigned data           : 1;
+                       unsigned feat           : 1;
+                       unsigned lbal           : 1;
+                       unsigned nsect          : 1;
+                       unsigned lbam           : 1;
+                       unsigned lbah           : 1;
+                       unsigned dev            : 1;
+                       unsigned command        : 1;
+               } lob;
+       };
+       union {
+               unsigned hob_all                : 8;
+               struct {
+                       unsigned data           : 1;
+                       unsigned feat           : 1;
+                       unsigned lbal           : 1;
+                       unsigned nsect          : 1;
+                       unsigned lbam           : 1;
+                       unsigned lbah           : 1;
+                       unsigned dev            : 1;
+                       unsigned command        : 1;
+               } hob;
+       };
+} __attribute__((packed));
+
+struct taskfile_regs {
+       __u8    data;
+       __u8    feat;
+       __u8    nsect;
+       __u8    lbal;
+       __u8    lbam;
+       __u8    lbah;
+       __u8    dev;
+       __u8    command;
+};
+
+struct hdio_taskfile {
+       struct taskfile_regs    lob;
+       struct taskfile_regs    hob;
+       union reg_flags         oflags;
+       union reg_flags         iflags;
+       int                     dphase;
+       int                     cmd_req;     /* IDE command_type */
+       unsigned long           obytes;
+       unsigned long           ibytes;
+       __u16                   data[0];
+};
+
+struct scsi_sg_io_hdr {
+       int                     interface_id;
+       int                     dxfer_direction;
+       unsigned char           cmd_len;
+       unsigned char           mx_sb_len;
+       unsigned short          iovec_count;
+       unsigned int            dxfer_len;
+       void *                  dxferp;
+       unsigned char *         cmdp;
+       void *                  sbp;
+       unsigned int            timeout;
+       unsigned int            flags;
+       int                     pack_id;
+       void *                  usr_ptr;
+       unsigned char           status;
+       unsigned char           masked_status;
+       unsigned char           msg_status;
+       unsigned char           sb_len_wr;
+       unsigned short          host_status;
+       unsigned short          driver_status;
+       int                     resid;
+       unsigned int            duration;
+       unsigned int            info;
+};
+
+#ifndef SG_DXFER_NONE
+       #define SG_DXFER_NONE           -1
+       #define SG_DXFER_TO_DEV         -2
+       #define SG_DXFER_FROM_DEV       -3
+       #define SG_DXFER_TO_FROM_DEV    -4
+#endif
+
+#define SG_READ                        0
+#define SG_WRITE               1
+
+#define SG_PIO                 0
+#define SG_DMA                 1
+
+#define SG_CHECK_CONDITION     0x02
+#define SG_DRIVER_SENSE                0x08
+
+#define SG_ATA_16              0x85
+#define SG_ATA_16_LEN          16
+
+#define SG_ATA_12              0xa1
+#define SG_ATA_12_LEN          12
+
+#define SG_ATA_LBA48           1
+#define SG_ATA_PROTO_NON_DATA  ( 3 << 1)
+#define SG_ATA_PROTO_PIO_IN    ( 4 << 1)
+#define SG_ATA_PROTO_PIO_OUT   ( 5 << 1)
+#define SG_ATA_PROTO_DMA       ( 6 << 1)
+#define SG_ATA_PROTO_UDMA_IN   (11 << 1) /* not yet supported in libata */
+#define SG_ATA_PROTO_UDMA_OUT  (12 << 1) /* not yet supported in libata */
+
+void tf_init (struct ata_tf *tf, __u8 ata_op, __u64 lba, unsigned int nsect);
+__u64 tf_to_lba (struct ata_tf *tf);
+int sg16 (int fd, int rw, int dma, struct ata_tf *tf, void *data, unsigned int 
data_bytes, unsigned int timeout_secs);
+int do_drive_cmd (int fd, unsigned char *args, unsigned int timeout);
+int do_taskfile_cmd (int fd, struct hdio_taskfile *r, unsigned int 
timeout_secs);
+int dev_has_sgio (int fd);
+void init_hdio_taskfile (struct hdio_taskfile *r, __u8 ata_op, int rw, int 
force_lba48,
+                               __u64 lba, unsigned int nsect, int data_bytes);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/wiper/Changelog 
new/hdparm-9.42/wiper/Changelog
--- old/hdparm-9.39/wiper/Changelog     2011-02-21 15:59:43.000000000 +0100
+++ new/hdparm-9.42/wiper/Changelog     2012-09-28 19:33:15.000000000 +0200
@@ -1,3 +1,5 @@
+wiper.sh-3.5
+       - don't skip Group 0 on ext* filesystems
 wiper.sh-3.4
        - updated to allow all SCSI_DISK_MAJOR numbers, not just "8"
 wiper.sh-3.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/wiper/contrib/README.contrib 
new/hdparm-9.42/wiper/contrib/README.contrib
--- old/hdparm-9.39/wiper/contrib/README.contrib        2010-11-07 
16:06:44.000000000 +0100
+++ new/hdparm-9.42/wiper/contrib/README.contrib        2012-09-28 
18:47:18.000000000 +0200
@@ -1,7 +1,7 @@
 Contributed scripts and notes from others (untested by me).
 ===========================================================
 
-raid1ext4trim.sh-1.4
+raid1ext4trim.sh-1.5
        Similar to wiper.sh, but for ext4/RAID1 mirrors.
        By Chris Caputo <ccap...@alt.net>.
        Adapted from wiper.sh (ver 2.6 by Mark Lord).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/wiper/contrib/raid1ext4trim.sh-1.4 
new/hdparm-9.42/wiper/contrib/raid1ext4trim.sh-1.4
--- old/hdparm-9.39/wiper/contrib/raid1ext4trim.sh-1.4  2010-11-07 
16:05:35.000000000 +0100
+++ new/hdparm-9.42/wiper/contrib/raid1ext4trim.sh-1.4  1970-01-01 
01:00:00.000000000 +0100
@@ -1,407 +0,0 @@
-#!/bin/bash
-#
-# SSD TRIM utility for live RAID1 mirrored ext4 drives.
-#
-# By Chris Caputo.  Adapted from wiper.sh (ver 2.6) by Mark Lord.
-
-VERSION=1.4
-
-# Copyright (C) 2010 Chris Caputo.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License Version 2,
-# as published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it would be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-function usage_error(){
-       echo "Usage:"
-       echo " ${0##*/} [--verbose] [--commit] [--reserve=#megs] 
[--max-ranges=#ranges] <raid_dev> <fsdir>"
-       echo "Examples:"
-       echo " ${0##*/} --verbose --commit --reserve=100 --max-ranges=512 md0 /"
-       echo " ${0##*/} --verbose --verbose md1 /boot"
-       echo 
-       echo "Note: For best results, this script should be run on each 
ext4-based filesystem present on a RAID1 array."
-       echo
-       exit 1
-}
-
-echo "${0##*/}: TRIM utility for live RAID1 ext4 SATA SSDs, version $VERSION, 
by Chris Caputo, based on Mark Lord's wiper.sh."
-echo
-
-## Parameter parsing for the main script.
-##
-
-export verbose=0
-commit=""
-reservemegs=0
-max_ranges=0
-argc=$#
-raiddev=""
-fsdir=""
-while [ $argc -gt 0 ]; do
-       if [ "$1" = "--commit" ]; then
-               commit=yes
-       elif [ "$1" = "--verbose" ]; then
-               verbose=$((verbose + 1))
-       elif [[ "$1" =~ --reserve=[[:digit:]] ]]; then
-               reservemegs=${1##--reserve=}
-       elif [[ "$1" =~ --max-ranges=[[:digit:]] ]]; then
-               max_ranges=${1##--max-ranges=}
-       elif [ "$1" = "" ]; then
-               usage_error
-       else
-               if [ "$raiddev" = "" ]; then
-                       raiddev=${1##*/}
-               elif [ "$fsdir" = "" ]; then
-                       fsdir=$1
-               else
-                       echo "$1: too many arguments, aborting."
-                       exit 1
-               fi
-       fi
-       argc=$((argc - 1))
-       shift
-done
-[ "$raiddev" = "" ] && usage_error
-[ "$fsdir" = "" ] && usage_error
-
-## Check --reserve number.
-##
-
-isdigit ()    # Tests whether *entire string* is numerical.
-{             # In other words, tests for integer variable.
-       [ $# -eq 1 ] || return -1
-
-       case $1 in
-               *[!0-9]*|"") return -1;;
-               *) return 0;;
-       esac
-}
-
-if ! isdigit "$reservemegs" ; then
-       echo "'$reservemegs' is not numerical"
-       exit 1
-fi
-if ! isdigit "$max_ranges" ; then
-       echo "'$max_ranges' is not numerical"
-       exit 1
-fi
-
-if [ $reservemegs -eq 0 ]; then
-       echo "Reserve defaulting to 10 megabytes."
-       reservemegs=10
-fi
-reservekilos=$((reservemegs * 1024))
-
-## Find a required program, or else give a nicer error message than we'd 
otherwise see:
-##
-function find_prog(){
-       prog="$1"
-       if [ ! -x "$prog" ]; then
-               prog="${prog##*/}"
-               p=`type -f -P "$prog" 2>/dev/null`
-               if [ "$p" = "" ]; then
-                       echo "$1: needed but not found, aborting."
-                       exit 1
-               fi
-               prog="$p"
-               [ $verbose -gt 0 ] && echo "  --> using $prog instead of $1"
-       fi
-       echo "$prog"
-}
-
-## Ensure we have most of the necessary utilities available before trying to 
proceed:
-##
-hash -r  ## Refresh bash's cached PATH entries
-HDPARM=`find_prog /sbin/hdparm` || exit 1
-GAWK=`find_prog /usr/bin/gawk`  || exit 1
-GREP=`find_prog /bin/grep`      || exit 1
-ID=`find_prog /usr/bin/id`      || exit 1
-LS=`find_prog /bin/ls`          || exit 1
-DF=`find_prog /bin/df`          || exit 1
-RM=`find_prog /bin/rm`          || exit 1
-
-[ $verbose -gt 1 ] && HDPARM="$HDPARM --verbose"
-
-## I suppose this will confuse the three SELinux users out there:
-##
-if [ `$ID -u` -ne 0 ]; then
-       echo "Only the super-user can use this (try \"sudo $0\" instead), 
aborting."
-       exit 1
-fi
-
-## We need a very modern hdparm, for its --fallocate and 
--trim-sector-ranges-stdin flags:
-## Version 9.25 added automatic determination of safe max-size of TRIM 
commands.
-##
-HDPVER=`$HDPARM -V | $GAWK '{gsub("[^0-9.]","",$2); if ($2 > 0) print ($2 * 
100); else print 0; exit(0)}'`
-if [ $HDPVER -lt 925 ]; then
-       echo "$HDPARM: version >= 9.25 is required, aborting."
-       exit 1
-fi
-
-## Check that this is a RAID1 device.
-##
-if ! $GREP raid1 /sys/block/$raiddev/md/level 1>/dev/null ; then
-       echo "$raiddev is not a RAID1 array."
-       exit 1
-fi
-
-## Get list of slave devices in the RAID1 mirror.
-##
-slaves=(`$LS /sys/block/$raiddev/slaves`)
-#slaves=(sda sdb sdc)
-#slaves=(md0)
-
-## Check for DEVTYPE disk and TRIM support on each slave.
-##
-index=0
-for slave in "${slaves[@]}"
-do
-       # Check that slave is of DEVTYPE disk.
-       if ! $GREP "DEVTYPE=disk" /sys/block/$slave/uevent 1>/dev/null ; then
-               echo "$slave is not a whole disk. This program only works with 
full-disk RAID1, not RAID1 partitions."
-               exit 1
-       fi
-
-       # Check that slave has TRIM support.  Exclude if not.
-       if ! $HDPARM -I /dev/$slave | $GREP -i '[       ][*][   ]*Data Set 
Management TRIM supported' &>/dev/null ; then
-               echo "$slave doesn't appear to support TRIM, per $HDPARM. 
Excluding."
-               unset slaves[index]
-       fi
-               
-       let "index = $index + 1"
-done
-if [ "${slaves[0]}" = "" ]; then
-       echo "No constituent of $raiddev array supports TRIM.  Aborting."
-       exit 1
-fi
-
-## Check that fsdir is on an ext4 volume.
-##
-lines=`$DF --type=ext4 $fsdir 2>/dev/null | $GREP -v ^Filesystem | wc -l`
-if [ $lines -ne 1 ]; then
-       echo "'$fsdir' does not appear to be on an ext4 filesystem.  Aborting."
-       exit 1
-fi
-
-## Check that fsdir is a directory.
-##
-if [ ! -d $fsdir ]; then
-       echo "'$fsdir' is not a directory.  Aborting."
-       exit 1
-fi
-
-## Check free space & calculate tmpfile size.
-##
-freesize=`$DF -P -B 1024 $fsdir | $GAWK '{r=$4}END{print r}'`
-if [ "$freesize" = "" ]; then
-       echo "'$fsdir' is unknown to '$DF'.  Aborting."
-       exit 1
-fi
-if [ $freesize -lt $reservekilos ]; then
-       echo "'$fsdir' available space of $freesize KB is less than the 
$reservekilos KB to be reserved for the TRIM operation.  Aborting." >&2
-       exit 1
-fi
-tmpsize=$((freesize - reservekilos)) 
-tmpfile="$fsdir/${0##*/}_TMPFILE.$$"
-
-## Clean up tmpfile (if any) and exit:
-##
-function do_cleanup(){
-       if [ -e $tmpfile ]; then
-               echo "Removing temporary file '$tmpfile'..."
-               $RM -f $tmpfile
-               if [ -e $tmpfile ]; then
-                       echo "Failed to remove '$tmpfile'!!!"
-               fi
-       fi
-       [ $1 -eq 0 ] && echo "Done."
-       [ $1 -eq 0 ] || echo "Aborted." >&2
-       exit $1
-}
-
-## Prepare signal handling, in case we get interrupted while $tmpfile exists:
-##
-function do_abort(){
-       echo
-       do_cleanup 1
-}
-trap do_abort SIGTERM
-trap do_abort SIGQUIT
-trap do_abort SIGINT
-trap do_abort SIGHUP
-trap do_abort SIGPIPE
-
-## Do the fallocate.
-## This is where we finally discover whether the filesystem actually
-## supports --fallocate or not.  Some folks will be disappointed here.
-##
-## Note that --fallocate does not actually write any file data to fsdev,
-## but rather simply allocates formerly-free space to the tmpfile.
-##
-echo -n "Creating temporary file (${tmpsize} KB '$tmpfile') ... "
-if ! $HDPARM --fallocate "${tmpsize}" $tmpfile ; then
-       echo "This kernel may not support 'fallocate'.  Aborting."
-       exit 1
-fi
-echo
-
-## Verify that slaves and RAID1 mirror have same base LBA.  First add a test
-## string to the tmpfile.  "date" is used since it is ever changing.
-##
-TESTSTR=`date`
-echo "$TESTSTR" >> $tmpfile
-sync    # this is critical
-SECTOR_BYTES=`$HDPARM --fibmap $tmpfile | \
-               $GREP "byte sectors"    | \
-               $GAWK '{print $9}'`
-LAST_EXTENT_SECTOR_COUNT=`$HDPARM --fibmap $tmpfile | \
-                               tail -1              | \
-                               $GAWK '{print $4}'`
-LAST_EXTENT_LBA=`$HDPARM --fibmap $tmpfile | tail -1 | $GAWK '{print $2}'`
-
-## Verify the test string is in the extent read.
-if ! dd iflag=direct status=noxfer bs=$SECTOR_BYTES 
count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$raiddev 
2>/dev/null | $GREP "$TESTSTR" &>/dev/null ; then
-       echo "Test string was not found in last extent of tmpfile, as it should 
have been.  Aborting."
-       do_cleanup 1
-fi
-
-## Now compare the mirror and the slaves to make sure they have the same data 
at the same LBA.
-##
-refchksum=`dd iflag=direct status=noxfer bs=$SECTOR_BYTES 
count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$raiddev 
2>/dev/null | sha1sum`
-index=0
-for slave in "${slaves[@]}"
-do
-       chksum=`dd iflag=direct status=noxfer bs=$SECTOR_BYTES 
count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$slave 
2>/dev/null | sha1sum`
-
-       if [ "$chksum" != "$refchksum" ]; then
-               echo "Direct I/O of last extent of tmpfile on $slave doesn't 
match that of $raiddev.  Excluding."
-               unset slaves[index]
-       fi
-               
-       let "index = $index + 1"
-done
-if [ "${slaves[0]}" = "" ]; then
-       echo "No constituent of $raiddev array has a matching checksum.  
Aborting."
-       do_cleanup 1
-fi
-
-echo "TRIMable constituents of $raiddev: ${slaves[@]}"
-
-## If they specified "--commit" on the command line, then prompt for 
confirmation first:
-##
-if [ "$commit" = "yes" ]; then
-       echo "Beginning TRIM operations..."
-else
-       echo "This will be a DRY-RUN only.  Use --commit to do it for real."
-       echo "Simulating TRIM operations..."
-fi
-get_trimlist="$HDPARM --fibmap $tmpfile"
-[ $verbose -gt 0 ] && echo "get_trimlist=$get_trimlist"
-
-
-## Begin gawk program
-GAWKPROG='
-       function append_range (lba,count  ,this_count){
-               nsectors += count;
-               while (count > 0) {
-                       this_count  = (count > 65535) ? 65535 : count
-                       printf "%u:%u \n", lba, this_count
-                       if (verbose > 1)
-                               printf "%u:%u ", lba, this_count > "/dev/stderr"
-                       lba        += this_count
-                       count      -= this_count
-                       nranges++;
-               }
-       }
-       {  ## Output from "hdparm --fibmap", in absolute sectors:
-               if (NF == 4 && $2 ~ "^[1-9][0-9]*$")
-               append_range($2,$4)
-               next
-       }
-       END {
-               if (verbose > 1)
-                       printf "\n" > "/dev/stderr"
-               if (err == 0 && commit != "yes")
-                       printf "(dry-run) trimming %u sectors from %u 
ranges\n", nsectors, nranges > "/dev/stderr"
-               exit err
-       }'
-## End gawk program
-
-## Run TRIM on each slave.  Batch as requested.
-sync
-index=0
-for slave in "${slaves[@]}"
-do
-       echo "TRIM beginning on $slave..."
-
-       if [ "$commit" = "yes" ]; then
-               TRIM="$HDPARM --please-destroy-my-drive \
-                               --trim-sector-ranges-stdin /dev/$slave"
-       else
-               TRIM="$GAWK {}"
-       fi
-
-       ## Different SSD's have a different maximum number of ranges they'll
-       ## accept in a single TRIM command.
-       if [ $max_ranges -eq 0 ] ; then
-               model=`$HDPARM -I /dev/$slave | $GAWK '/Model Number/ { print 
$NF }'`
-               case "$model" in
-                       SSDSA[12]*)  slave_max_range=512 ;; # Intel X18-M/X25-M
-                       OCZ-VERTEX2) slave_max_range=64 ;; # OCZ Vertex2
-                       *)           slave_max_range=65535
-               esac
-       else
-               slave_max_range=$max_ranges
-       fi
-       [ $verbose -gt 0 ] && echo "$slave: max-ranges = $slave_max_range"
-
-       $get_trimlist 2>/dev/null | $GAWK \
-               -v commit="$commit"       \
-               -v verbose="$verbose"     \
-               "$GAWKPROG" |             \
-               if true; then
-                       i=0
-                       while read range; do
-                               (( i++ ))
-                               if (( i <= $slave_max_range )); then
-                                       ranges=$ranges" "$range
-                               else
-                                       [ $verbose -gt 0 ] && echo -e "Trim 
ranges:" $ranges
-                                       echo $ranges | $TRIM
-                                       ret=$?
-                                       if [ $ret -ne 0 ] ; then
-                                               do_cleanup $ret
-                                       fi
-                                       ranges=$range
-                                       i=1
-                               fi
-                       done
-                       [ $verbose -gt 0 ] && echo -e "Trim ranges:" $ranges
-                       echo $ranges | $TRIM
-                       ret=$?
-                       if [ $ret -ne 0 ] ; then
-                               do_cleanup $ret
-                       fi
-                       ranges=""
-               fi
-                               
-       ret=$?
-       if [ $ret -ne 0 ] ; then
-               echo "TRIM failed on $slave.  Aborting."
-               do_cleanup $ret
-       else
-               echo "TRIM finished successfully on $slave."
-       fi
-done
-
-do_cleanup 0
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/wiper/contrib/raid1ext4trim.sh-1.5 
new/hdparm-9.42/wiper/contrib/raid1ext4trim.sh-1.5
--- old/hdparm-9.39/wiper/contrib/raid1ext4trim.sh-1.5  1970-01-01 
01:00:00.000000000 +0100
+++ new/hdparm-9.42/wiper/contrib/raid1ext4trim.sh-1.5  2012-09-28 
18:46:21.000000000 +0200
@@ -0,0 +1,407 @@
+#!/bin/bash
+#
+# SSD TRIM utility for live RAID1 mirrored ext4 drives.
+#
+# By Chris Caputo.  Adapted from wiper.sh (ver 2.6) by Mark Lord.
+
+VERSION=1.5
+
+# Copyright (C) 2010-2012 Chris Caputo.  All rights reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License Version 2,
+# as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+function usage_error(){
+       echo "Usage:"
+       echo " ${0##*/} [--verbose] [--commit] [--reserve=#megs] 
[--max-ranges=#ranges] <raid_dev> <fsdir>"
+       echo "Examples:"
+       echo " ${0##*/} --verbose --commit --reserve=100 --max-ranges=512 md0 /"
+       echo " ${0##*/} --verbose --verbose md1 /boot"
+       echo 
+       echo "Note: For best results, this script should be run on each 
ext4-based filesystem present on a RAID1 array."
+       echo
+       exit 1
+}
+
+echo "${0##*/}: TRIM utility for live RAID1 ext4 SATA SSDs, version $VERSION, 
by Chris Caputo, based on Mark Lord's wiper.sh."
+echo
+
+## Parameter parsing for the main script.
+##
+
+export verbose=0
+commit=""
+reservemegs=0
+max_ranges=0
+argc=$#
+raiddev=""
+fsdir=""
+while [ $argc -gt 0 ]; do
+       if [ "$1" = "--commit" ]; then
+               commit=yes
+       elif [ "$1" = "--verbose" ]; then
+               verbose=$((verbose + 1))
+       elif [[ "$1" =~ --reserve= ]]; then
+               reservemegs=${1##--reserve=}
+       elif [[ "$1" =~ --max-ranges= ]]; then
+               max_ranges=${1##--max-ranges=}
+       elif [ "$1" = "" ]; then
+               usage_error
+       else
+               if [ "$raiddev" = "" ]; then
+                       raiddev=${1##*/}
+               elif [ "$fsdir" = "" ]; then
+                       fsdir=$1
+               else
+                       echo "$1: too many arguments, aborting."
+                       exit 1
+               fi
+       fi
+       argc=$((argc - 1))
+       shift
+done
+[ "$raiddev" = "" ] && usage_error
+[ "$fsdir" = "" ] && usage_error
+
+## Check --reserve number.
+##
+
+isdigit ()    # Tests whether *entire string* is numerical.
+{             # In other words, tests for integer variable.
+       [ $# -eq 1 ] || return 1
+
+       case $1 in
+               *[!0-9]*|"") return 1;;
+               *) return 0;;
+       esac
+}
+
+if ! isdigit "$reservemegs" ; then
+       echo "'$reservemegs' is not numerical"
+       exit 1
+fi
+if ! isdigit "$max_ranges" ; then
+       echo "'$max_ranges' is not numerical"
+       exit 1
+fi
+
+if [ $reservemegs -eq 0 ]; then
+       echo "Reserve defaulting to 10 megabytes."
+       reservemegs=10
+fi
+reservekilos=$((reservemegs * 1024))
+
+## Find a required program, or else give a nicer error message than we'd 
otherwise see:
+##
+function find_prog(){
+       prog="$1"
+       if [ ! -x "$prog" ]; then
+               prog="${prog##*/}"
+               p=`type -f -P "$prog" 2>/dev/null`
+               if [ "$p" = "" ]; then
+                       echo "$1: needed but not found, aborting."
+                       exit 1
+               fi
+               prog="$p"
+               [ $verbose -gt 0 ] && echo "  --> using $prog instead of $1"
+       fi
+       echo "$prog"
+}
+
+## Ensure we have most of the necessary utilities available before trying to 
proceed:
+##
+hash -r  ## Refresh bash's cached PATH entries
+HDPARM=`find_prog /sbin/hdparm` || exit 1
+GAWK=`find_prog /usr/bin/gawk`  || exit 1
+GREP=`find_prog /bin/grep`      || exit 1
+ID=`find_prog /usr/bin/id`      || exit 1
+LS=`find_prog /bin/ls`          || exit 1
+DF=`find_prog /bin/df`          || exit 1
+RM=`find_prog /bin/rm`          || exit 1
+
+[ $verbose -gt 1 ] && HDPARM="$HDPARM --verbose"
+
+## I suppose this will confuse the three SELinux users out there:
+##
+if [ `$ID -u` -ne 0 ]; then
+       echo "Only the super-user can use this (try \"sudo $0\" instead), 
aborting."
+       exit 1
+fi
+
+## We need a very modern hdparm, for its --fallocate and 
--trim-sector-ranges-stdin flags:
+## Version 9.25 added automatic determination of safe max-size of TRIM 
commands.
+##
+HDPVER=`$HDPARM -V | $GAWK '{gsub("[^0-9.]","",$2); if ($2 > 0) print ($2 * 
100); else print 0; exit(0)}'`
+if [ $HDPVER -lt 925 ]; then
+       echo "$HDPARM: version >= 9.25 is required, aborting."
+       exit 1
+fi
+
+## Check that this is a RAID1 device.
+##
+if ! $GREP raid1 /sys/block/$raiddev/md/level 1>/dev/null ; then
+       echo "$raiddev is not a RAID1 array."
+       exit 1
+fi
+
+## Get list of slave devices in the RAID1 mirror.
+##
+slaves=(`$LS /sys/block/$raiddev/slaves`)
+#slaves=(sda sdb sdc)
+#slaves=(md0)
+
+## Check for DEVTYPE disk and TRIM support on each slave.
+##
+index=0
+for slave in "${slaves[@]}"
+do
+       # Check that slave is of DEVTYPE disk.
+       if ! $GREP "DEVTYPE=disk" /sys/block/$slave/uevent 1>/dev/null ; then
+               echo "$slave is not a whole disk. This program only works with 
full-disk RAID1, not RAID1 partitions."
+               exit 1
+       fi
+
+       # Check that slave has TRIM support.  Exclude if not.
+       if ! $HDPARM -I /dev/$slave | $GREP -i '[       ][*][   ]*Data Set 
Management TRIM supported' &>/dev/null ; then
+               echo "$slave doesn't appear to support TRIM, per $HDPARM. 
Excluding."
+               unset slaves[index]
+       fi
+               
+       let "index = $index + 1"
+done
+if [ "${slaves[0]}" = "" ]; then
+       echo "No constituent of $raiddev array supports TRIM.  Aborting."
+       exit 1
+fi
+
+## Check that fsdir is on an ext4 volume.
+##
+lines=`$DF --type=ext4 $fsdir 2>/dev/null | $GREP -v ^Filesystem | wc -l`
+if [ $lines -ne 1 ]; then
+       echo "'$fsdir' does not appear to be on an ext4 filesystem.  Aborting."
+       exit 1
+fi
+
+## Check that fsdir is a directory.
+##
+if [ ! -d $fsdir ]; then
+       echo "'$fsdir' is not a directory.  Aborting."
+       exit 1
+fi
+
+## Check free space & calculate tmpfile size.
+##
+freesize=`$DF -P -B 1024 $fsdir | $GAWK '{r=$4}END{print r}'`
+if [ "$freesize" = "" ]; then
+       echo "'$fsdir' is unknown to '$DF'.  Aborting."
+       exit 1
+fi
+if [ $freesize -lt $reservekilos ]; then
+       echo "'$fsdir' available space of $freesize KB is less than the 
$reservekilos KB to be reserved for the TRIM operation.  Aborting." >&2
+       exit 1
+fi
+tmpsize=$((freesize - reservekilos)) 
+tmpfile="$fsdir/${0##*/}_TMPFILE.$$"
+
+## Clean up tmpfile (if any) and exit:
+##
+function do_cleanup(){
+       if [ -e $tmpfile ]; then
+               echo "Removing temporary file '$tmpfile'..."
+               $RM -f $tmpfile
+               if [ -e $tmpfile ]; then
+                       echo "Failed to remove '$tmpfile'!!!"
+               fi
+       fi
+       [ $1 -eq 0 ] && echo "Done."
+       [ $1 -eq 0 ] || echo "Aborted." >&2
+       exit $1
+}
+
+## Prepare signal handling, in case we get interrupted while $tmpfile exists:
+##
+function do_abort(){
+       echo
+       do_cleanup 1
+}
+trap do_abort SIGTERM
+trap do_abort SIGQUIT
+trap do_abort SIGINT
+trap do_abort SIGHUP
+trap do_abort SIGPIPE
+
+## Do the fallocate.
+## This is where we finally discover whether the filesystem actually
+## supports --fallocate or not.  Some folks will be disappointed here.
+##
+## Note that --fallocate does not actually write any file data to fsdev,
+## but rather simply allocates formerly-free space to the tmpfile.
+##
+echo -n "Creating temporary file (${tmpsize} KB '$tmpfile') ... "
+if ! $HDPARM --fallocate "${tmpsize}" $tmpfile ; then
+       echo "This kernel may not support 'fallocate'.  Aborting."
+       exit 1
+fi
+echo
+
+## Verify that slaves and RAID1 mirror have same base LBA.  First add a test
+## string to the tmpfile.  "date" is used since it is ever changing.
+##
+TESTSTR=`date`
+echo "$TESTSTR" >> $tmpfile
+sync    # this is critical
+SECTOR_BYTES=`$HDPARM --fibmap $tmpfile | \
+               $GREP "byte sectors"    | \
+               $GAWK '{print $9}'`
+LAST_EXTENT_SECTOR_COUNT=`$HDPARM --fibmap $tmpfile | \
+                               tail -1              | \
+                               $GAWK '{print $4}'`
+LAST_EXTENT_LBA=`$HDPARM --fibmap $tmpfile | tail -1 | $GAWK '{print $2}'`
+
+## Verify the test string is in the extent read.
+if ! dd iflag=direct status=noxfer bs=$SECTOR_BYTES 
count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$raiddev 
2>/dev/null | $GREP "$TESTSTR" &>/dev/null ; then
+       echo "Test string was not found in last extent of tmpfile, as it should 
have been.  Aborting."
+       do_cleanup 1
+fi
+
+## Now compare the mirror and the slaves to make sure they have the same data 
at the same LBA.
+##
+refchksum=`dd iflag=direct status=noxfer bs=$SECTOR_BYTES 
count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$raiddev 
2>/dev/null | sha1sum`
+index=0
+for slave in "${slaves[@]}"
+do
+       chksum=`dd iflag=direct status=noxfer bs=$SECTOR_BYTES 
count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$slave 
2>/dev/null | sha1sum`
+
+       if [ "$chksum" != "$refchksum" ]; then
+               echo "Direct I/O of last extent of tmpfile on $slave doesn't 
match that of $raiddev.  Excluding."
+               unset slaves[index]
+       fi
+               
+       let "index = $index + 1"
+done
+if [ "${slaves[0]}" = "" ]; then
+       echo "No constituent of $raiddev array has a matching checksum.  
Aborting."
+       do_cleanup 1
+fi
+
+echo "TRIMable constituents of $raiddev: ${slaves[@]}"
+
+## If they specified "--commit" on the command line, then prompt for 
confirmation first:
+##
+if [ "$commit" = "yes" ]; then
+       echo "Beginning TRIM operations..."
+else
+       echo "This will be a DRY-RUN only.  Use --commit to do it for real."
+       echo "Simulating TRIM operations..."
+fi
+get_trimlist="$HDPARM --fibmap $tmpfile"
+[ $verbose -gt 0 ] && echo "get_trimlist=$get_trimlist"
+
+
+## Begin gawk program
+GAWKPROG='
+       function append_range (lba,count  ,this_count){
+               nsectors += count;
+               while (count > 0) {
+                       this_count  = (count > 65535) ? 65535 : count
+                       printf "%u:%u \n", lba, this_count
+                       if (verbose > 1)
+                               printf "%u:%u ", lba, this_count > "/dev/stderr"
+                       lba        += this_count
+                       count      -= this_count
+                       nranges++;
+               }
+       }
+       {  ## Output from "hdparm --fibmap", in absolute sectors:
+               if (NF == 4 && $2 ~ "^[1-9][0-9]*$")
+               append_range($2,$4)
+               next
+       }
+       END {
+               if (verbose > 1)
+                       printf "\n" > "/dev/stderr"
+               if (err == 0 && commit != "yes")
+                       printf "(dry-run) trimming %u sectors from %u 
ranges\n", nsectors, nranges > "/dev/stderr"
+               exit err
+       }'
+## End gawk program
+
+## Run TRIM on each slave.  Batch as requested.
+sync
+index=0
+for slave in "${slaves[@]}"
+do
+       echo "TRIM beginning on $slave..."
+
+       if [ "$commit" = "yes" ]; then
+               TRIM="$HDPARM --please-destroy-my-drive \
+                               --trim-sector-ranges-stdin /dev/$slave"
+       else
+               TRIM="$GAWK {}"
+       fi
+
+       ## Different SSD's have a different maximum number of ranges they'll
+       ## accept in a single TRIM command.
+       if [ $max_ranges -eq 0 ] ; then
+               model=`$HDPARM -I /dev/$slave | $GAWK '/Model Number/ { print 
$NF }'`
+               case "$model" in
+                       SSDSA[12]*)  slave_max_range=512 ;; # Intel X18-M/X25-M
+                       OCZ-VERTEX2) slave_max_range=64 ;; # OCZ Vertex2
+                       *)           slave_max_range=65535
+               esac
+       else
+               slave_max_range=$max_ranges
+       fi
+       [ $verbose -gt 0 ] && echo "$slave: max-ranges = $slave_max_range"
+
+       $get_trimlist 2>/dev/null | $GAWK \
+               -v commit="$commit"       \
+               -v verbose="$verbose"     \
+               "$GAWKPROG" |             \
+               if true; then
+                       i=0
+                       while read range; do
+                               (( i++ ))
+                               if (( i <= $slave_max_range )); then
+                                       ranges=$ranges" "$range
+                               else
+                                       [ $verbose -gt 0 ] && echo -e "Trim 
ranges:" $ranges
+                                       echo $ranges | $TRIM
+                                       ret=$?
+                                       if [ $ret -ne 0 ] ; then
+                                               do_cleanup $ret
+                                       fi
+                                       ranges=$range
+                                       i=1
+                               fi
+                       done
+                       [ $verbose -gt 0 ] && echo -e "Trim ranges:" $ranges
+                       echo $ranges | $TRIM
+                       ret=$?
+                       if [ $ret -ne 0 ] ; then
+                               do_cleanup $ret
+                       fi
+                       ranges=""
+               fi
+                               
+       ret=$?
+       if [ $ret -ne 0 ] ; then
+               echo "TRIM failed on $slave.  Aborting."
+               do_cleanup $ret
+       else
+               echo "TRIM finished successfully on $slave."
+       fi
+done
+
+do_cleanup 0
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hdparm-9.39/wiper/wiper.sh 
new/hdparm-9.42/wiper/wiper.sh
--- old/hdparm-9.39/wiper/wiper.sh      2011-02-21 15:58:26.000000000 +0100
+++ new/hdparm-9.42/wiper/wiper.sh      2012-09-28 20:08:37.000000000 +0200
@@ -2,7 +2,7 @@
 #
 # SATA SSD free-space TRIM utility, by Mark Lord <ml...@pobox.com>
 
-VERSION=3.4 
+VERSION=3.5 
 
 # Copyright (C) 2009-2010 Mark Lord.  All rights reserved.
 #
@@ -252,6 +252,11 @@
 ## because that's the pattern such systems also use in /proc/mounts.
 ## Later, at time of use, we'll try harder to find the real rootdev.
 ##
+## FIXME: apparently this doesn't work on SuSE Linux, though.
+## So for there, we'll likely need to read /etc/mtab,
+## or be a lot more clever and get it somehow from statfs or something.
+## FIXME: or use target from /dev/root symlink for Gentoo as well.
+##
 function match_rootdev() {
        rdev=""
        rdevno="$1"
@@ -793,7 +798,7 @@
                blksects = $NF / 512
                next
        }
-       /^Group [1-9][0-9]*:/ { ## Second stage output from dumpe2fs:
+       /^Group [0-9][0-9]*:/ { ## Second stage output from dumpe2fs:
                in_groups = 1
                next
        }

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to