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