ALT Linux repositórios
Group :: Sistema/Kernel e hardware
RPM: reiserfsprogs
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: reiserfsprogs-progress.diff
Download
Download
From: Jeff Mahoney <jeffm@suse.com>
Subject: [PATCH] reiserprogs: add spinner and progress bar for -a mode
This patch implements a progress bar with percentages and a plain spinner
for when progress wants to be demonstrated but percentages aren't known.
These are used during journal replay and for the internal tree check.
diff -ruNp reiserfsprogs-3.6.19/fsck/check_tree.c reiserfsprogs-3.6.19.devel/fsck/check_tree.c
--- reiserfsprogs-3.6.19/fsck/check_tree.c 2004-09-29 15:52:20.000000000 -0400
+++ reiserfsprogs-3.6.19.devel/fsck/check_tree.c 2007-02-08 18:57:45.000000000 -0500
@@ -1124,7 +1124,7 @@ void check_fs_tree (reiserfs_filsys_t *
{
before_check_fs_tree (fs);
- fsck_progress ("Checking internal tree..");
+ fsck_progress ("Checking internal tree.. ");
pass_through_tree (fs, bad_node, bad_path, fsck_mode(fs) == FSCK_AUTO ? 2 : -1);
/* internal tree is correct (including all objects have correct
sequences of items) */
diff -ruNp reiserfsprogs-3.6.19/fsck/ustree.c reiserfsprogs-3.6.19.devel/fsck/ustree.c
--- reiserfsprogs-3.6.19/fsck/ustree.c 2004-05-24 18:11:43.000000000 -0400
+++ reiserfsprogs-3.6.19.devel/fsck/ustree.c 2007-02-08 18:55:30.000000000 -0500
@@ -4,6 +4,7 @@
*/
#include "fsck.h"
+#include "progbar.h"
struct tree_balance * cur_tb = 0;
@@ -196,6 +197,9 @@ void pass_through_tree (reiserfs_filsys_
int h = 0;
unsigned long block = get_sb_root_block (fs->fs_ondisk_sb);
int problem;
+ struct spinner spinner;
+
+ spinner_init(&spinner, fsck_progress_file(fs));
if (block >= get_sb_block_count (fs->fs_ondisk_sb) || not_data_block (fs, block)) {
@@ -223,6 +227,8 @@ void pass_through_tree (reiserfs_filsys_
}
problem = 1;
} else {
+
+ spinner_touch(&spinner);
path[h] = bread (fs->fs_dev, block, fs->fs_blocksize);
if (path[h] == 0)
/* FIXME: handle case when read failed */
@@ -279,4 +285,5 @@ void pass_through_tree (reiserfs_filsys_
block = first_child (path[h]);
h ++;
}
+ spinner_clear(&spinner);
}
diff -ruNp reiserfsprogs-3.6.19/include/progbar.h reiserfsprogs-3.6.19.devel/include/progbar.h
--- reiserfsprogs-3.6.19/include/progbar.h 1969-12-31 19:00:00.000000000 -0500
+++ reiserfsprogs-3.6.19.devel/include/progbar.h 2007-02-08 18:53:54.000000000 -0500
@@ -0,0 +1,32 @@
+#ifndef _PROGBAR_H_
+#define _PROGBAR_H_
+
+enum {
+ E2F_FLAG_PROG_SUPPRESS = 1,
+ E2F_FLAG_PROG_BAR = 2,
+};
+
+struct progbar {
+ char units[16];
+ int progress_pos;
+ int progress_last_percent;
+ time_t progress_last_time;
+ int flags;
+ FILE *file;
+};
+
+struct spinner {
+ int count;
+ FILE *file;
+};
+
+void progbar_init(struct progbar *ctx, const char *units, FILE *fp);
+void progbar_clear(struct progbar * ctx);
+int progbar_update(struct progbar * ctx, const char *label, int curr, int max,
+ unsigned int dpynum);
+
+void spinner_init(struct spinner *spinner, FILE *fp);
+void spinner_touch(struct spinner *spinner);
+void spinner_clear(struct spinner *spinner);
+
+#endif /* _PROGBAR_H_ */
diff -ruNp reiserfsprogs-3.6.19/lib/Makefile.am reiserfsprogs-3.6.19.devel/lib/Makefile.am
--- reiserfsprogs-3.6.19/lib/Makefile.am 2004-02-17 06:35:12.000000000 -0500
+++ reiserfsprogs-3.6.19.devel/lib/Makefile.am 2007-02-08 17:02:19.000000000 -0500
@@ -1,5 +1,5 @@
noinst_LIBRARIES = libmisc.a
-libmisc_a_SOURCES = io.c misc.c
+libmisc_a_SOURCES = io.c misc.c progbar.c
##reiserfs.c
diff -ruNp reiserfsprogs-3.6.19/lib/progbar.c reiserfsprogs-3.6.19.devel/lib/progbar.c
--- reiserfsprogs-3.6.19/lib/progbar.c 1969-12-31 19:00:00.000000000 -0500
+++ reiserfsprogs-3.6.19.devel/lib/progbar.c 2007-02-08 18:53:44.000000000 -0500
@@ -0,0 +1,117 @@
+#include <stdio.h>
+#include <sys/time.h>
+#include <string.h>
+
+#include "progbar.h"
+
+static char bar[128], spaces[128];
+static const char spinner[] = "\\|/-";
+
+void progbar_init(struct progbar *ctx, const char *units, FILE *fp)
+{
+ memset(ctx, 0, sizeof (*ctx));
+ if (!bar[0])
+ memset(bar, '=', sizeof(bar)-1);
+ if (!spaces[0])
+ memset(spaces, ' ', sizeof(spaces)-1);
+ strncpy(ctx->units, units, sizeof(ctx->units));
+ ctx->file = fp;
+}
+
+
+void progbar_clear(struct progbar * ctx)
+{
+ if (!(ctx->flags & E2F_FLAG_PROG_BAR))
+ return;
+
+ fprintf(ctx->file, "\r%*s\r", 80, " ");
+ fflush(ctx->file);
+ ctx->flags &= ~E2F_FLAG_PROG_BAR;
+}
+
+int progbar_update(struct progbar * ctx, const char *label, int curr, int max,
+ unsigned int dpynum)
+{
+ int i;
+ unsigned int tick;
+ struct timeval tv;
+ int dpywidth;
+ int fixed_percent;
+ float percent = ((float) curr) / ((float) max) * 100;
+
+ if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
+ return 0;
+
+ /*
+ * Calculate the new progress position. If the
+ * percentage hasn't changed, then we skip out right
+ * away.
+ */
+ fixed_percent = (int) ((10 * percent) + 0.5);
+ if (ctx->progress_last_percent == fixed_percent)
+ return 0;
+ ctx->progress_last_percent = fixed_percent;
+
+ /*
+ * If we've already updated the spinner once within
+ * the last 1/8th of a second, no point doing it
+ * again.
+ */
+ gettimeofday(&tv, NULL);
+ tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
+ if ((tick == ctx->progress_last_time) &&
+ (fixed_percent != 0) && (fixed_percent != 1000))
+ return 0;
+ ctx->progress_last_time = tick;
+
+ /*
+ * Advance the spinner, and note that the progress bar
+ * will be on the screen
+ */
+ ctx->progress_pos = (ctx->progress_pos+1) & 3;
+ ctx->flags |= E2F_FLAG_PROG_BAR;
+
+ dpywidth = 66 - strlen(label);
+ dpywidth = 8 * (dpywidth / 8);
+ if (dpynum)
+ dpywidth -= 8;
+
+ i = ((percent * dpywidth) + 50) / 100;
+ fprintf(ctx->file, "\r%s: |%s%s", label,
+ bar + (sizeof(bar) - (i+1)),
+ spaces + (sizeof(spaces) - (dpywidth - i + 1)));
+ if (fixed_percent == 1000)
+ fputc('|', ctx->file);
+ else
+ fputc(spinner[ctx->progress_pos & 3], ctx->file);
+ fprintf(ctx->file, " %4.1f%% ", percent);
+ if (dpynum)
+ fprintf(ctx->file, "%u%s\r", dpynum, ctx->units);
+ else
+ fputs(" \r", ctx->file);
+
+ if (fixed_percent == 1000)
+ progbar_clear(ctx);
+ fflush(ctx->file);
+
+ return 0;
+}
+
+void
+spinner_init(struct spinner *ctx, FILE *fp)
+{
+ memset(ctx, 0, sizeof (*ctx));
+ ctx->file = fp;
+}
+
+void
+spinner_touch(struct spinner *ctx)
+{
+ fprintf(ctx->file, "%c", spinner[ctx->count++ % 4]);
+}
+
+void
+spinner_clear(struct spinner *ctx)
+{
+ fputs("", ctx->file);
+}
diff -ruNp reiserfsprogs-3.6.19/reiserfscore/journal.c reiserfsprogs-3.6.19.devel/reiserfscore/journal.c
--- reiserfsprogs-3.6.19/reiserfscore/journal.c 2007-02-08 15:00:28.000000000 -0500
+++ reiserfsprogs-3.6.19.devel/reiserfscore/journal.c 2007-02-08 18:32:52.000000000 -0500
@@ -6,6 +6,7 @@
#define _GNU_SOURCE
#include "includes.h"
+#include "progbar.h"
/* compares description block with commit block. returns 0 if they differ, 1
if they match */
@@ -799,6 +800,8 @@ int replay_journal (reiserfs_filsys_t *
struct reiserfs_journal_header * j_head;
reiserfs_trans_t cur, newest, control;
int replayed, ret;
+ struct progbar progbar;
+ int trans_count;
if (!reiserfs_journal_opened (fs))
reiserfs_panic ("replay_journal: journal is not opened");
@@ -806,7 +809,8 @@ int replay_journal (reiserfs_filsys_t *
if (!is_opened_rw (fs))
reiserfs_panic ("replay_journal: fs is not opened with write perms");
- reiserfs_warning (stderr, "Replaying journal..\n");
+
+ reiserfs_warning (stderr, "Replaying journal: ");
bh = fs->fs_jh_bh;
j_head = (struct reiserfs_journal_header *)(bh->b_data);
@@ -819,12 +823,15 @@ int replay_journal (reiserfs_filsys_t *
return 0;
}
+ trans_count = newest.trans_id - cur.trans_id;
+
/* Smth strange with journal header or journal. We cannot say for sure what was the last
replaied transaction, but relying on JH data is preferable. */
replayed = 0;
ret = TRANS_FOUND;
+ progbar_init(&progbar, " trans", stderr);
/* Looking to the first valid not replayed transaction. */
while (1) {
if (cur.mount_id == control.mount_id &&
@@ -842,6 +849,7 @@ int replay_journal (reiserfs_filsys_t *
break;
if (!transaction_check_content(fs, &cur)) {
+ progbar_clear(&progbar);
reiserfs_warning (stderr, "Trans broken: mountid %lu, transid %lu, desc %lu, "
"len %lu, commit %lu, next trans offset %lu\n", cur.mount_id, cur.trans_id,
cur.desc_blocknr, cur.trans_len, cur.commit_blocknr, cur.next_trans_offset);
@@ -859,10 +867,14 @@ int replay_journal (reiserfs_filsys_t *
control = cur;
replayed ++;
+ progbar_update(&progbar, "Replaying journal", replayed, trans_count,
+ replayed);
+
ret = next_transaction (fs, &cur, newest);
}
+ progbar_clear(&progbar);
- reiserfs_warning (stderr, "Reiserfs journal '%s' in blocks [%u..%u]: %d "
+ reiserfs_warning (stderr, "\rReplaying journal: Done.\nReiserfs journal '%s' in blocks [%u..%u]: %d "
"transactions replayed\n", fs->fs_j_file_name,
get_jp_journal_1st_block(sb_jp(fs->fs_ondisk_sb)),
get_jp_journal_1st_block(sb_jp(fs->fs_ondisk_sb)) +