Skip to content

Commit

Permalink
btrfs-progs: scrub: show the scrubbing rate and estimated time to finish
Browse files Browse the repository at this point in the history
The estimation is based on the allocated bytes, so it might be
overestimated.  Scrub reports the size of all bytes scrubbed, taking
into account the replication, so we're comparing that with total sum
over all devices that we get from DEV_INFO, in the same units.

Example output:

scrub status for xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
        scrub started at Fri May 31 15:56:57 2019, running for 0:04:31
        total 62.55GiB scrubbed at rate 236.37MiB/s, time left: 0:12:31
        no errors found

Pull-request: #177
Signed-off-by: Grzegorz Kowal <grzegorz@amuncode.org>
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
gkowal authored and kdave committed Jul 3, 2019
1 parent 604ffe8 commit 832da8c
Showing 1 changed file with 39 additions and 13 deletions.
52 changes: 39 additions & 13 deletions cmds-scrub.c
Expand Up @@ -134,10 +134,19 @@ static void print_scrub_full(struct btrfs_scrub_progress *sp)
printf(" %s=%llu", desc, test); \
} while (0)

static void print_scrub_summary(struct btrfs_scrub_progress *p)
static void print_scrub_summary(struct btrfs_scrub_progress *p, struct scrub_stats *s, u64 bytes_total)
{
u64 err_cnt;
u64 err_cnt2;
u64 bytes_scrubbed;
u64 bytes_per_sec = 0;
u64 sec_left = 0;

bytes_scrubbed = p->data_bytes_scrubbed + p->tree_bytes_scrubbed;
if (s->duration > 0)
bytes_per_sec = bytes_scrubbed / s->duration;
if (bytes_per_sec > 0)
sec_left = (bytes_total - bytes_scrubbed) / bytes_per_sec;

err_cnt = p->read_errors +
p->csum_errors +
Expand All @@ -150,9 +159,18 @@ static void print_scrub_summary(struct btrfs_scrub_progress *p)
printf("*** WARNING: memory allocation failed while scrubbing. "
"results may be inaccurate\n");

printf("\ttotal bytes scrubbed: %s with %llu errors\n",
pretty_size(p->data_bytes_scrubbed + p->tree_bytes_scrubbed),
max(err_cnt, err_cnt2));
if (s->in_progress) {
printf(
"\ttotal %s scrubbed at rate %s/s, time left: %llu:%02llu:%02llu\n",
pretty_size(bytes_scrubbed),
pretty_size(bytes_per_sec),
sec_left / 3600, (sec_left / 60) % 60, sec_left % 60);
} else {
printf("\ttotal %s scrubbed at rate %s/s\n",
pretty_size(bytes_scrubbed),
pretty_size(bytes_per_sec));
}


if (err_cnt || err_cnt2) {
printf("\terror details:");
Expand All @@ -164,6 +182,8 @@ static void print_scrub_summary(struct btrfs_scrub_progress *p)
printf("\tcorrected errors: %llu, uncorrectable errors: %llu, "
"unverified errors: %llu\n", p->corrected_errors,
p->uncorrectable_errors, p->unverified_errors);
} else {
printf("\tno errors found\n");
}
}

Expand Down Expand Up @@ -251,13 +271,13 @@ static void _print_scrub_ss(struct scrub_stats *ss)
gmtime_r(&seconds, &tm);
strftime(t, sizeof(t), "%M:%S", &tm);
if (ss->in_progress)
printf(", running for %02u:%s\n", hours, t);
printf(", running for %u:%s\n", hours, t);
else if (ss->canceled)
printf(" and was aborted after %02u:%s\n", hours, t);
printf(" and was aborted after %u:%s\n", hours, t);
else if (ss->finished)
printf(" and finished after %02u:%s\n", hours, t);
printf(" and finished after %u:%s\n", hours, t);
else
printf(", interrupted after %02u:%s, not running\n",
printf(", interrupted after %u:%s, not running\n",
hours, t);
}

Expand All @@ -274,18 +294,18 @@ static void print_scrub_dev(struct btrfs_ioctl_dev_info_args *di,
if (raw)
print_scrub_full(p);
else
print_scrub_summary(p);
print_scrub_summary(p, ss, di->bytes_used);
}
}

static void print_fs_stat(struct scrub_fs_stat *fs_stat, int raw)
static void print_fs_stat(struct scrub_fs_stat *fs_stat, int raw, u64 bytes_total)
{
_print_scrub_ss(&fs_stat->s);

if (raw)
print_scrub_full(&fs_stat->p);
else
print_scrub_summary(&fs_stat->p);
print_scrub_summary(&fs_stat->p, &fs_stat->s, bytes_total);
}

static void free_history(struct scrub_file_record **last_scrubs)
Expand Down Expand Up @@ -1487,6 +1507,8 @@ static int scrub_start(const struct cmd_struct *cmd, int argc, char **argv,

if (do_print) {
const char *append = "done";
u64 total_bytes_used = 0;

if (!do_stats_per_dev)
init_fs_stat(&fs_stat);
for (i = 0; i < fi_args.num_devices; ++i) {
Expand All @@ -1502,10 +1524,11 @@ static int scrub_start(const struct cmd_struct *cmd, int argc, char **argv,
add_to_fs_stat(&sp[i].scrub_args.progress,
&sp[i].stats, &fs_stat);
}
total_bytes_used += di_args[i].bytes_used;
}
if (!do_stats_per_dev) {
printf("scrub %s for %s\n", append, fsid);
print_fs_stat(&fs_stat, print_raw);
print_fs_stat(&fs_stat, print_raw, total_bytes_used);
}
}

Expand Down Expand Up @@ -1771,6 +1794,8 @@ static int cmd_scrub_status(const struct cmd_struct *cmd, int argc, char **argv)
&last_scrub->stats);
}
} else {
u64 total_bytes_used = 0;

init_fs_stat(&fs_stat);
fs_stat.s.in_progress = in_progress;
for (i = 0; i < fi_args.num_devices; ++i) {
Expand All @@ -1780,8 +1805,9 @@ static int cmd_scrub_status(const struct cmd_struct *cmd, int argc, char **argv)
continue;
add_to_fs_stat(&last_scrub->p, &last_scrub->stats,
&fs_stat);
total_bytes_used += di_args[i].bytes_used;
}
print_fs_stat(&fs_stat, print_raw);
print_fs_stat(&fs_stat, print_raw, total_bytes_used);
}

out:
Expand Down

0 comments on commit 832da8c

Please sign in to comment.