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.
This commit is contained in:
Pádraig Brady 2014-04-03 13:47:48 +01:00
parent d0294ff3b9
commit 217618e8bf
3 changed files with 13 additions and 10 deletions

3
NEWS
View File

@ -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.

View File

@ -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;
}
}
}

View File

@ -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