summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAlexander Zarochentsev <zam@namesys.com>2006-03-25 03:06:59 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-25 08:22:51 -0800
commita44c94a7b82a425b73384c104d5cb3dd3caa075e (patch)
treeda86b5245bea89942f2639fec2d6f7378a117836 /fs
parent23f9e0f891c9b159a199629d4426f6ae0c383508 (diff)
downloadlinux-a44c94a7b82a425b73384c104d5cb3dd3caa075e.tar.bz2
[PATCH] reiserfs: handle trans_id overflow
Reiserfs does not handle transaction ID overflow correctly. Transaction ID == 0 causes reiserfs to crash. The patch fixes all places where the transaction ID is incremented. Signed-off-by: Alexander Zarochentsev <zam@namesys.com> Signed-off-by: Hans Reiser <reiser@namesys.com> Cc: Chris Mason <mason@suse.com> Cc: Jeff Mahoney <jeffm@suse.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/reiserfs/journal.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 5a9d2722fa0a..1b73529b8099 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2227,6 +2227,9 @@ static int journal_read_transaction(struct super_block *p_s_sb,
journal->j_start = cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb);
journal->j_last_flush_trans_id = trans_id;
journal->j_trans_id = trans_id + 1;
+ /* check for trans_id overflow */
+ if (journal->j_trans_id == 0)
+ journal->j_trans_id = 10;
brelse(c_bh);
brelse(d_bh);
kfree(log_blocks);
@@ -2450,6 +2453,9 @@ static int journal_read(struct super_block *p_s_sb)
journal->j_start = le32_to_cpu(jh->j_first_unflushed_offset);
journal->j_trans_id =
le32_to_cpu(jh->j_last_flush_trans_id) + 1;
+ /* check for trans_id overflow */
+ if (journal->j_trans_id == 0)
+ journal->j_trans_id = 10;
journal->j_last_flush_trans_id =
le32_to_cpu(jh->j_last_flush_trans_id);
journal->j_mount_id = le32_to_cpu(jh->j_mount_id) + 1;
@@ -3873,8 +3879,8 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
int cur_write_start = 0; /* start index of current log write */
int old_start;
int i;
- int flush = flags & FLUSH_ALL;
- int wait_on_commit = flags & WAIT;
+ int flush;
+ int wait_on_commit;
struct reiserfs_journal_list *jl, *temp_jl;
struct list_head *entry, *safe;
unsigned long jindex;
@@ -3884,6 +3890,13 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
BUG_ON(th->t_refcount > 1);
BUG_ON(!th->t_trans_id);
+ /* protect flush_older_commits from doing mistakes if the
+ transaction ID counter gets overflowed. */
+ if (th->t_trans_id == ~0UL)
+ flags |= FLUSH_ALL | COMMIT_NOW | WAIT;
+ flush = flags & FLUSH_ALL;
+ wait_on_commit = flags & WAIT;
+
put_fs_excl();
current->journal_info = th->t_handle_save;
reiserfs_check_lock_depth(p_s_sb, "journal end");
@@ -4105,7 +4118,9 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
journal->j_first = NULL;
journal->j_len = 0;
journal->j_trans_start_time = 0;
- journal->j_trans_id++;
+ /* check for trans_id overflow */
+ if (++journal->j_trans_id == 0)
+ journal->j_trans_id = 10;
journal->j_current_jl->j_trans_id = journal->j_trans_id;
journal->j_must_wait = 0;
journal->j_len_alloc = 0;