aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Leschuck <vleschuk@gmail.com>2013-08-23 10:26:32 -0400
committerJeff Mahoney <jeffm@suse.de>2013-08-23 10:26:41 -0400
commit14e8805a0835776167cf435aaf91a56b74746d2f (patch)
tree0d8bdadbefce90f0f4d134ccf17fe1adf1a8d8ed
parentd83a36e872d3409a0a1e3f3cc713674df97ba2f5 (diff)
downloadreiserfsprogs-14e8805a0835776167cf435aaf91a56b74746d2f.tar.gz
journal: fix division by 0 with one transaction in log
We have met a situation when reiserfsck segfaulted on one of our partitions. I have performed a small research and the cause appeared to be wrong detection of transaction count. Our FS had only one journal transaction, however trans_count which was passed to progbar_update() as maximum transaction value was detected as (last_transaction - first_transaction) which in our case was 0. Thus progbar_update() resulted in segmentation fault: (gdb) bt "Replaying journal", curr=1, max=0, dpynum=1) at progbar.c:80 Here is part of debugreiserfs -j output Journal header (block #8210 of ./partition.bug): j_last_flush_trans_id 0 j_first_unflushed_offset 0 j_mount_id 10 Device [0x0] Magic [0x4f0a099e] Size 8193 blocks (including 1 for journal header) (first block 18) Max transaction length 1024 blocks Max batch size 900 blocks Max commit age 30 Mountid 10, transid 10, desc 18, length 2, commit 21 I successfully reproduced it on versions 3.6.21 (which we were using) and 3.6.23 (which I believe is the latest). Attaching patch. Let me know your opinion. If I am wrong, please comment, if I am correct, feel free to include patch into sources. Thanks. Signed-off-by: Victor Leschuk <vleschuk@gmail.com> Signed-off-by: Jeff Mahoney <jeffm@suse.com>
-rw-r--r--lib/progbar.c3
-rw-r--r--reiserfscore/journal.c5
2 files changed, 5 insertions, 3 deletions
diff --git a/lib/progbar.c b/lib/progbar.c
index fde2e70..9ecc803 100644
--- a/lib/progbar.c
+++ b/lib/progbar.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
+#include <assert.h>
#include "progbar.h"
@@ -37,6 +38,8 @@ int progbar_update(struct progbar * ctx, const char *label, int curr, int max,
struct timeval tv;
int dpywidth;
int fixed_percent;
+ assert (curr >= 0);
+ assert (max > 0);
float percent = ((float) curr) / ((float) max) * 100;
if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
diff --git a/reiserfscore/journal.c b/reiserfscore/journal.c
index a3ebcde..00e1939 100644
--- a/reiserfscore/journal.c
+++ b/reiserfscore/journal.c
@@ -818,13 +818,12 @@ int replay_journal (reiserfs_filsys_t * fs)
control.trans_id = get_jh_last_flushed (j_head);
control.desc_blocknr = get_jh_replay_start_offset (j_head);
- if (!get_boundary_transactions (fs, &cur, &newest)) {
+ trans_count = get_boundary_transactions (fs, &cur, &newest);
+ if (!trans_count) {
reiserfs_warning (stderr, "No transactions found\n");
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. */