(tv_hi->tv_usec - tv_lo->tv_usec)/1.0e6);
}
-static void carefully_write(int fd, const void *buf, size_t sz)
-{
- const unsigned char *p = buf;
- ssize_t n;
-
- if (fd < 0) return;
- while (sz) {
- n = write(fd, p, sz);
- if (n < 0) {
- if (errno == EINTR) continue;
- bail_syserr(errno, "failed to write to output file");
- }
- if (!n) bail("unexpected short write to output file");
- p += n; sz -= n;
- }
-}
-
-static void open_file_on_demand(const char *file, FILE **fp_inout,
- const char *what)
-{
- FILE *fp;
-
- if (!*fp_inout) {
- fp = fopen(file, "w");
- if (!fp)
- bail_syserr(errno, "failed to open %s file `%s'", what, file);
- fprintf(fp, "## %s\n\n", what);
- *fp_inout = fp;
- }
-}
-
-static void check_write(FILE *fp, const char *what)
-{
- fflush(fp);
- if (ferror(fp)) bail_syserr(errno, "error writing %s file", what);
-}
-
-static void carefully_fclose(FILE *fp, const char *what)
-{
- if (fp && (ferror(fp) || fclose(fp)))
- bail_syserr(errno, "error writing %s file", what);
-}
-
#define DEFVEC(vtype, etype) \
typedef struct { etype *v; size_t n, sz; } vtype
#define VEC_INIT { 0, 0, 0 }
progress_shownotice(render, bg, 7);
}
+static double alpha = 0.1;
+
static void update_progress(secaddr pos)
{
struct timeval now;
gettimeofday(&now, 0);
t = tvdiff(&last_time, &now);
-#define ALPHA 0.1
-#define BETA (1 - ALPHA)
+#define BETA (1 - alpha)
if (t) {
g = wcount ? pow(BETA, t) : 0.0; f = (1 - g)/(1 - BETA);
last_time = now; last_pos = pos;
}
-#undef ALPHA
#undef BETA
throbix++; if (!throbber[throbix]) throbix = 0;
recovered(bad_lo, end); *pos_inout = end;
return (0);
}
- step = step_factor*(bad_hi - bad_lo);
+ step = (step_factor - 1)*(bad_hi - bad_lo);
if (step < step_min) step = step_min;
if (step_max && step > step_max) step = step_max;
- if (step > end - bad_lo) step = end - bad_lo;
- pos = bad_lo + step - 1;
+ if (step > end - bad_hi) step = end - bad_hi;
+ pos = bad_hi + step - 1;
want = run_length_wanted(pos, step, end);
n = recovery_read(&r, pos, want);
#ifdef DEBUG
step_max = parse_int(&p, 1, SECLIMIT - 1, "step maximum");
else if (SKIP_PREFIX("retry"))
max_retries = parse_int(&p, 0, INT_MAX, "retries");
+ else if (SKIP_PREFIX("alpha"))
+ alpha = parse_float(&p, 0, 1, "average decay factor");
else if (SKIP_PREFIX("_badwait"))
bad_block_delay = parse_float(&p, 0, DBL_MAX, "bad-block delay");
else if (SKIP_PREFIX("_blkwait"))
ev = &eventq.v[i];
switch (ev->ev) {
case EV_WRITE: start = ev->pos; f |= f_write; break;
- case EV_STOP:
- nsectors += ev->pos - start; f &= ~f_write; break;
+ case EV_STOP: nsectors += ev->pos - start; f &= ~f_write; break;
}
if (ev->pos >= limit) break;
if (f&f_fixup) start = ev->pos;
copy_progress.render = render_copy_progress;
progress_additem(&progress, ©_progress);
- if (nsectors != limit) {
+ if (nsectors == limit - start)
+ { ndone = start; nsectors = limit; }
+ else {
disc_progress.render = render_disc_progress;
progress_additem(&progress, &disc_progress);
}
if (f&f_stats) {
gettimeofday(&tv1, 0); t = tvdiff(&tv0, &tv1);
+ if (nsectors == limit - start) { ndone -= start; nsectors -= start; }
tot = scale_bytes((double)nsectors*SECTORSZ, &totunit);
rate = scale_bytes((double)nsectors*SECTORSZ/t, &rateunit);
moan("all done: %.1f %sB in %s -- %.1f %sB/s",