aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--deadshred.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/deadshred.c b/deadshred.c
index b849fc7..50528c4 100644
--- a/deadshred.c
+++ b/deadshred.c
@@ -130,13 +130,23 @@ ensure_random(size_t needed)
static void
-add_span(off_t off, off_t amount, size_t blocksize)
+add_span(off_t off, off_t amount, size_t blocksize, int try_join)
{
off_t end = off + amount;
while ((off_t)(blocksize >> 1) >= amount)
blocksize >>= 1;
+ if (try_join) {
+ if (off == spans[nspans - 1U].end || end == spans[nspans - 1U].start) {
+ spans[nspans - 1U].start = MIN(off, spans[nspans - 1U].start);
+ spans[nspans - 1U].end = MAX(end, spans[nspans - 1U].end);
+ spans[nspans - 1U].bad += amount;
+ spans[nspans - 1U].blocksize = MAX(blocksize, spans[nspans - 1U].blocksize);
+ return;
+ }
+ }
+
if (nspans == spans_size) {
spans_size += 1024;
spans = ereallocarray(spans, spans_size, sizeof(*spans));
@@ -434,7 +444,7 @@ print_progress(int done, const struct timespec *now)
sprintf(bufi == 0 ? buf1 : buf2,
"%ji bytes (%s, %s, %.2lf %%) of %s (%s) shredded\033[K\n"
- "failed writes: %ju; bad sections: %ju (%s, %s)\033[K\n"
+ "failed writes: %ju; bad sections: %ju (%ji bytes, %s, %s)\033[K\n"
"time spent shredding: %s; performance: %s\033[K\n"
"time since last successful write: %s\033[K\n"
"maximum time until a successful write: %s\033[K\n"
@@ -450,6 +460,7 @@ print_progress(int done, const struct timespec *now)
/* } line 2 { */
bad_writes,
bad_sections,
+ (intmax_t)bad_bytes,
humansize1000(bad_bytes, subbuf3),
humansize1024(bad_bytes, subbuf4),
/* } line 3 { */
@@ -554,6 +565,7 @@ shredspan(int fd, struct span *span, const char *fname)
ssize_t r;
struct timespec now, when = {0, 0};
int bad = span->bad > 0;
+ int first_fail = 1;
pthread_mutex_lock(&progress_mutex);
@@ -602,7 +614,8 @@ shredspan(int fd, struct span *span, const char *fname)
pthread_mutex_lock(&progress_mutex);
if (errno != EIO)
weprintf("pwrite %s <buffer> %zu %ji:", fname, (size_t)n, (intmax_t)off);
- add_span(off, n, span->blocksize == 1U ? 1U : span->blocksize);
+ add_span(off, n, span->blocksize == 1U ? 1U : span->blocksize >> 1, !first_fail);
+ first_fail = 0;
if (direction == FORWARDS)
off += n;
if (!span->bad)
@@ -621,7 +634,8 @@ shredspan(int fd, struct span *span, const char *fname)
off += (off_t)r;
} else if ((off_t)r < n) {
n -= (off_t)r;
- add_span(off + (off_t)r, n, span->blocksize == 1U ? 1U : span->blocksize);
+ add_span(off + (off_t)r, n, span->blocksize == 1U ? 1U : span->blocksize >> 1, !first_fail);
+ first_fail = 0;
if (direction == FORWARDS)
off += n;
if (!span->bad)
@@ -804,12 +818,14 @@ main(int argc, char *argv[])
while (nspans) {
size_t old_nspans = nspans;
- for (i = 0; i < old_nspans; i++)
+ for (i = 0; i < old_nspans && !exiting; i++)
shredspan(fd, &spans[i], argv[0]);
+ if (exiting) {
+ memmove(&spans[0], &spans[i], (nspans -= i) * sizeof(*spans));
+ break;
+ }
for (i = 0, j = nspans, nspans -= old_nspans; i < nspans;)
spans[i++] = spans[--j];
- if (exiting)
- break;
direction ^= 1;
pass_nr++;
}