aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Zarochentsev <zam@namesys.com>2006-03-25 06:06:59 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-25 11:22:51 -0500
commita44c94a7b82a425b73384c104d5cb3dd3caa075e (patch)
treeda86b5245bea89942f2639fec2d6f7378a117836
parent23f9e0f891c9b159a199629d4426f6ae0c383508 (diff)
[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>
-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,
2227 journal->j_start = cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb); 2227 journal->j_start = cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb);
2228 journal->j_last_flush_trans_id = trans_id; 2228 journal->j_last_flush_trans_id = trans_id;
2229 journal->j_trans_id = trans_id + 1; 2229 journal->j_trans_id = trans_id + 1;
2230 /* check for trans_id overflow */
2231 if (journal->j_trans_id == 0)
2232 journal->j_trans_id = 10;
2230 brelse(c_bh); 2233 brelse(c_bh);
2231 brelse(d_bh); 2234 brelse(d_bh);
2232 kfree(log_blocks); 2235 kfree(log_blocks);
@@ -2450,6 +2453,9 @@ static int journal_read(struct super_block *p_s_sb)
2450 journal->j_start = le32_to_cpu(jh->j_first_unflushed_offset); 2453 journal->j_start = le32_to_cpu(jh->j_first_unflushed_offset);
2451 journal->j_trans_id = 2454 journal->j_trans_id =
2452 le32_to_cpu(jh->j_last_flush_trans_id) + 1; 2455 le32_to_cpu(jh->j_last_flush_trans_id) + 1;
2456 /* check for trans_id overflow */
2457 if (journal->j_trans_id == 0)
2458 journal->j_trans_id = 10;
2453 journal->j_last_flush_trans_id = 2459 journal->j_last_flush_trans_id =
2454 le32_to_cpu(jh->j_last_flush_trans_id); 2460 le32_to_cpu(jh->j_last_flush_trans_id);
2455 journal->j_mount_id = le32_to_cpu(jh->j_mount_id) + 1; 2461 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,
3873 int cur_write_start = 0; /* start index of current log write */ 3879 int cur_write_start = 0; /* start index of current log write */
3874 int old_start; 3880 int old_start;
3875 int i; 3881 int i;
3876 int flush = flags & FLUSH_ALL; 3882 int flush;
3877 int wait_on_commit = flags & WAIT; 3883 int wait_on_commit;
3878 struct reiserfs_journal_list *jl, *temp_jl; 3884 struct reiserfs_journal_list *jl, *temp_jl;
3879 struct list_head *entry, *safe; 3885 struct list_head *entry, *safe;
3880 unsigned long jindex; 3886 unsigned long jindex;
@@ -3884,6 +3890,13 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
3884 BUG_ON(th->t_refcount > 1); 3890 BUG_ON(th->t_refcount > 1);
3885 BUG_ON(!th->t_trans_id); 3891 BUG_ON(!th->t_trans_id);
3886 3892
3893 /* protect flush_older_commits from doing mistakes if the
3894 transaction ID counter gets overflowed. */
3895 if (th->t_trans_id == ~0UL)
3896 flags |= FLUSH_ALL | COMMIT_NOW | WAIT;
3897 flush = flags & FLUSH_ALL;
3898 wait_on_commit = flags & WAIT;
3899
3887 put_fs_excl(); 3900 put_fs_excl();
3888 current->journal_info = th->t_handle_save; 3901 current->journal_info = th->t_handle_save;
3889 reiserfs_check_lock_depth(p_s_sb, "journal end"); 3902 reiserfs_check_lock_depth(p_s_sb, "journal end");
@@ -4105,7 +4118,9 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
4105 journal->j_first = NULL; 4118 journal->j_first = NULL;
4106 journal->j_len = 0; 4119 journal->j_len = 0;
4107 journal->j_trans_start_time = 0; 4120 journal->j_trans_start_time = 0;
4108 journal->j_trans_id++; 4121 /* check for trans_id overflow */
4122 if (++journal->j_trans_id == 0)
4123 journal->j_trans_id = 10;
4109 journal->j_current_jl->j_trans_id = journal->j_trans_id; 4124 journal->j_current_jl->j_trans_id = journal->j_trans_id;
4110 journal->j_must_wait = 0; 4125 journal->j_must_wait = 0;
4111 journal->j_len_alloc = 0; 4126 journal->j_len_alloc = 0;