diff options
author | Pádraig Brady <P@draigBrady.com> | 2014-04-03 13:47:48 +0100 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2014-04-04 05:32:41 +0100 |
commit | 217618e8bf10a09270291b9825f3181ed2f83dbf (patch) | |
tree | 2dda4cac20c6f65fee545800279cf5f995ede4fa | |
parent | d0294ff3b90430750a631556277c75f1a555dd44 (diff) | |
download | coreutils-217618e8bf10a09270291b9825f3181ed2f83dbf.tar.xz |
shred: avoid a data pass on empty files
* src/shred.c (do_wipefd): Don't increase the size written
for an empty file up to a full block. Also increase the size
to OFF_T_MAX in the edge case where we do overflow.
* NEWS: Mention the shred improvements from recent changes.
* tests/misc/shred-passes.sh: Adjust as we no longer
write a BLKSIZE of data for empty files.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | src/shred.c | 10 | ||||
-rwxr-xr-x | tests/misc/shred-passes.sh | 10 |
3 files changed, 13 insertions, 10 deletions
@@ -57,6 +57,9 @@ GNU coreutils NEWS -*- outline -*- causing name look-up errors. Also look-ups are first done outside the chroot, in case the look-up within the chroot fails due to library conflicts etc. + shred now supports multiple passes on GNU/Linux tape devices by rewinding + the tape before each pass. Also redundant writes to empty files are avoided. + split avoids unnecessary input buffering, immediately writing input to output which is significant with --filter or when writing to fifos or stdout etc. diff --git a/src/shred.c b/src/shred.c index 732d3afb1..ed370513d 100644 --- a/src/shred.c +++ b/src/shred.c @@ -428,7 +428,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, size_t soff; /* Offset into buffer for next write */ ssize_t ssize; /* Return value from write */ - /* Do nothing for --size=0 or regular empty files with --exact. */ + /* Do nothing for --size=0 or regular empty files. */ if (size == 0) return 0; @@ -887,15 +887,15 @@ do_wipefd (int fd, char const *qname, struct randint_source *s, if (! flags->exact) { - /* Round up to the nearest blocksize. If the file is - empty output a block anyway, in case the file system - stores small files in the inode. */ + /* Round up to the nearest blocksize to clear slack space. */ off_t remainder = size % ST_BLKSIZE (st); - if (remainder != 0 || size == 0) + if (remainder != 0) { off_t size_incr = ST_BLKSIZE (st) - remainder; if (! INT_ADD_OVERFLOW (size, size_incr)) size += size_incr; + else + size = OFF_T_MAX; } } } diff --git a/tests/misc/shred-passes.sh b/tests/misc/shred-passes.sh index bbd12880c..268af950f 100755 --- a/tests/misc/shred-passes.sh +++ b/tests/misc/shred-passes.sh @@ -20,9 +20,9 @@ print_ver_ shred -# shred a single letter, zero length file which should result in +# shred a single letter, which should result in # 3 random passes and a single rename. -touch f || framework_failure_ +printf 1 > f || framework_failure_ echo "\ shred: f: pass 1/3 (random)... shred: f: pass 2/3 (random)... @@ -35,15 +35,15 @@ shred -v -u f 2>out || fail=1 compare exp out || fail=1 -# Likewise but with --exact to bypass the -# data passes for the zero length file +# Likewise but for a zero length file +# to bypass the data passes touch f || framework_failure_ echo "\ shred: f: removing shred: f: renamed to 0 shred: f: removed" > exp || framework_failure_ -shred -x -v -u f 2>out || fail=1 +shred -v -u f 2>out || fail=1 compare exp out || fail=1 |