[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>
This commit is contained in:
Родитель
23f9e0f891
Коммит
a44c94a7b8
|
@ -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_start = cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb);
|
||||||
journal->j_last_flush_trans_id = trans_id;
|
journal->j_last_flush_trans_id = trans_id;
|
||||||
journal->j_trans_id = trans_id + 1;
|
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(c_bh);
|
||||||
brelse(d_bh);
|
brelse(d_bh);
|
||||||
kfree(log_blocks);
|
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_start = le32_to_cpu(jh->j_first_unflushed_offset);
|
||||||
journal->j_trans_id =
|
journal->j_trans_id =
|
||||||
le32_to_cpu(jh->j_last_flush_trans_id) + 1;
|
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 =
|
journal->j_last_flush_trans_id =
|
||||||
le32_to_cpu(jh->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;
|
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 cur_write_start = 0; /* start index of current log write */
|
||||||
int old_start;
|
int old_start;
|
||||||
int i;
|
int i;
|
||||||
int flush = flags & FLUSH_ALL;
|
int flush;
|
||||||
int wait_on_commit = flags & WAIT;
|
int wait_on_commit;
|
||||||
struct reiserfs_journal_list *jl, *temp_jl;
|
struct reiserfs_journal_list *jl, *temp_jl;
|
||||||
struct list_head *entry, *safe;
|
struct list_head *entry, *safe;
|
||||||
unsigned long jindex;
|
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_refcount > 1);
|
||||||
BUG_ON(!th->t_trans_id);
|
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();
|
put_fs_excl();
|
||||||
current->journal_info = th->t_handle_save;
|
current->journal_info = th->t_handle_save;
|
||||||
reiserfs_check_lock_depth(p_s_sb, "journal end");
|
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_first = NULL;
|
||||||
journal->j_len = 0;
|
journal->j_len = 0;
|
||||||
journal->j_trans_start_time = 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_current_jl->j_trans_id = journal->j_trans_id;
|
||||||
journal->j_must_wait = 0;
|
journal->j_must_wait = 0;
|
||||||
journal->j_len_alloc = 0;
|
journal->j_len_alloc = 0;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче