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