Hello Developers,

some disks can be very slow with direct I/O and shred. I developed a small patch that adds a new
option -i, --nodirectio to disable direct I/O.

Regards Andreas

diff -ur coreutils-8.23-orig/src/shred.c coreutils-8.23/src/shred.c
--- coreutils-8.23-orig/src/shred.c     2014-07-11 13:00:07.000000000 +0200
+++ coreutils-8.23/src/shred.c  2015-09-23 20:05:44.000000000 +0200
@@ -135,6 +135,7 @@
   bool verbose;                /* -v flag: Print progress */
   bool exact;          /* -x flag: Do not round up file size */
   bool zero_fill;      /* -z flag: Add a final zero pass */
+  bool nodirectio;     /* -i flag: Do not use direct IO */
 };
 
 /* For long options that have no equivalent short option, use a
@@ -154,6 +155,7 @@
   {"remove", optional_argument, NULL, 'u'},
   {"verbose", no_argument, NULL, 'v'},
   {"zero", no_argument, NULL, 'z'},
+  {"nodirectio", no_argument, NULL, 'i'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -176,6 +178,7 @@
 
       printf (_("\
   -f, --force    change permissions to allow writing if necessary\n\
+  -i, --nodirectio  do not use direct IO (O_DIRECT)\n\
   -n, --iterations=N  overwrite N times instead of the default (%d)\n\
       --random-source=FILE  get random bytes from FILE\n\
   -s, --size=N   shred this many bytes (suffixes like K, M, G accepted)\n\
@@ -418,7 +421,8 @@
 static int
 dopass (int fd, struct stat const *st, char const *qname, off_t *sizep,
         int type, struct randread_source *s,
-        unsigned long int k, unsigned long int n)
+        unsigned long int k, unsigned long int n,
+        struct Options const *flags)
 {
   off_t size = *sizep;
   off_t offset;                        /* Current file posiiton */
@@ -452,7 +456,7 @@
   /* As a performance tweak, avoid direct I/O for small sizes,
      as it's just a performance rather then security consideration,
      and direct I/O can often be unsupported for small non aligned sizes.  */
-  bool try_without_directio = 0 < size && size < output_size;
+  bool try_without_directio = (0 < size && size < output_size) || 
flags->nodirectio;
   if (! try_without_directio)
     direct_mode (fd, true);
 
@@ -949,7 +953,7 @@
           int err = 0;
           int type = i < flags->n_iterations ? passarray[i] : 0;
 
-          err = dopass (fd, &st, qname, &pass_size, type, rs, i + 1, pn);
+          err = dopass (fd, &st, qname, &pass_size, type, rs, i + 1, pn, 
flags);
 
           if (err)
             {
@@ -1218,8 +1222,9 @@
 
   flags.n_iterations = DEFAULT_PASSES;
   flags.size = -1;
+  flags.nodirectio = false;
 
-  while ((c = getopt_long (argc, argv, "fn:s:uvxz", long_opts, NULL)) != -1)
+  while ((c = getopt_long (argc, argv, "fn:s:uvxzi", long_opts, NULL)) != -1)
     {
       switch (c)
         {
@@ -1280,6 +1285,10 @@
           flags.zero_fill = true;
           break;
 
+        case 'i':
+          flags.nodirectio = true;
+          break;
+
         case_GETOPT_HELP_CHAR;
 
         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);

Reply via email to