summaryrefslogtreecommitdiff
path: root/fs/reiserfs/journal.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs/journal.c')
-rw-r--r--fs/reiserfs/journal.c103
1 files changed, 59 insertions, 44 deletions
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 9b3672d69367..ad8cbc49883a 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -718,8 +718,7 @@ static int add_to_chunk(struct buffer_chunk *chunk, struct buffer_head *bh,
spinlock_t * lock, void (fn) (struct buffer_chunk *))
{
int ret = 0;
- if (chunk->nr >= CHUNK_SIZE)
- BUG();
+ BUG_ON(chunk->nr >= CHUNK_SIZE);
chunk->bh[chunk->nr++] = bh;
if (chunk->nr >= CHUNK_SIZE) {
ret = 1;
@@ -788,8 +787,7 @@ static inline int __add_jh(struct reiserfs_journal *j, struct buffer_head *bh,
/* buffer must be locked for __add_jh, should be able to have
* two adds at the same time
*/
- if (bh->b_private)
- BUG();
+ BUG_ON(bh->b_private);
jh->bh = bh;
bh->b_private = jh;
}
@@ -1186,6 +1184,21 @@ static struct reiserfs_journal_list *find_newer_jl_for_cn(struct
return NULL;
}
+static int newer_jl_done(struct reiserfs_journal_cnode *cn)
+{
+ struct super_block *sb = cn->sb;
+ b_blocknr_t blocknr = cn->blocknr;
+
+ cn = cn->hprev;
+ while (cn) {
+ if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist &&
+ atomic_read(&cn->jlist->j_commit_left) != 0)
+ return 0;
+ cn = cn->hprev;
+ }
+ return 1;
+}
+
static void remove_journal_hash(struct super_block *,
struct reiserfs_journal_cnode **,
struct reiserfs_journal_list *, unsigned long,
@@ -1604,6 +1617,31 @@ static int flush_journal_list(struct super_block *s,
return err;
}
+static int test_transaction(struct super_block *s,
+ struct reiserfs_journal_list *jl)
+{
+ struct reiserfs_journal_cnode *cn;
+
+ if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0)
+ return 1;
+
+ cn = jl->j_realblock;
+ while (cn) {
+ /* if the blocknr == 0, this has been cleared from the hash,
+ ** skip it
+ */
+ if (cn->blocknr == 0) {
+ goto next;
+ }
+ if (cn->bh && !newer_jl_done(cn))
+ return 0;
+ next:
+ cn = cn->next;
+ cond_resched();
+ }
+ return 0;
+}
+
static int write_one_transaction(struct super_block *s,
struct reiserfs_journal_list *jl,
struct buffer_chunk *chunk)
@@ -2927,8 +2965,7 @@ static int do_journal_begin_r(struct reiserfs_transaction_handle *th,
int retval;
reiserfs_check_lock_depth(p_s_sb, "journal_begin");
- if (nblocks > journal->j_trans_max)
- BUG();
+ BUG_ON(nblocks > journal->j_trans_max);
PROC_INFO_INC(p_s_sb, journal.journal_being);
/* set here for journal_join */
@@ -3044,9 +3081,8 @@ struct reiserfs_transaction_handle *reiserfs_persistent_transaction(struct
if (reiserfs_transaction_running(s)) {
th = current->journal_info;
th->t_refcount++;
- if (th->t_refcount < 2) {
- BUG();
- }
+ BUG_ON(th->t_refcount < 2);
+
return th;
}
th = kmalloc(sizeof(struct reiserfs_transaction_handle), GFP_NOFS);
@@ -3086,9 +3122,7 @@ static int journal_join(struct reiserfs_transaction_handle *th,
** pointer
*/
th->t_handle_save = cur_th;
- if (cur_th && cur_th->t_refcount > 1) {
- BUG();
- }
+ BUG_ON(cur_th && cur_th->t_refcount > 1);
return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_JOIN);
}
@@ -3101,9 +3135,7 @@ int journal_join_abort(struct reiserfs_transaction_handle *th,
** pointer
*/
th->t_handle_save = cur_th;
- if (cur_th && cur_th->t_refcount > 1) {
- BUG();
- }
+ BUG_ON(cur_th && cur_th->t_refcount > 1);
return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_ABORT);
}
@@ -3138,8 +3170,7 @@ int journal_begin(struct reiserfs_transaction_handle *th,
current->journal_info = th;
}
ret = do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_REG);
- if (current->journal_info != th)
- BUG();
+ BUG_ON(current->journal_info != th);
/* I guess this boils down to being the reciprocal of clm-2100 above.
* If do_journal_begin_r fails, we need to put it back, since journal_end
@@ -3284,8 +3315,7 @@ int journal_end(struct reiserfs_transaction_handle *th,
/* we aren't allowed to close a nested transaction on a different
** filesystem from the one in the task struct
*/
- if (cur_th->t_super != th->t_super)
- BUG();
+ BUG_ON(cur_th->t_super != th->t_super);
if (th != cur_th) {
memcpy(current->journal_info, th, sizeof(*th));
@@ -3404,9 +3434,7 @@ int journal_end_sync(struct reiserfs_transaction_handle *th,
BUG_ON(!th->t_trans_id);
/* you can sync while nested, very, very bad */
- if (th->t_refcount > 1) {
- BUG();
- }
+ BUG_ON(th->t_refcount > 1);
if (journal->j_len == 0) {
reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb),
1);
@@ -3433,16 +3461,6 @@ static void flush_async_commits(void *p)
flush_commit_list(p_s_sb, jl, 1);
}
unlock_kernel();
- /*
- * this is a little racey, but there's no harm in missing
- * the filemap_fdata_write
- */
- if (!atomic_read(&journal->j_async_throttle)
- && !reiserfs_is_journal_aborted(journal)) {
- atomic_inc(&journal->j_async_throttle);
- filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping);
- atomic_dec(&journal->j_async_throttle);
- }
}
/*
@@ -3526,9 +3544,8 @@ static int check_journal_end(struct reiserfs_transaction_handle *th,
** will be dealt with by next transaction that actually writes something, but should be taken
** care of in this trans
*/
- if (journal->j_len == 0) {
- BUG();
- }
+ BUG_ON(journal->j_len == 0);
+
/* if wcount > 0, and we are called to with flush or commit_now,
** we wait on j_join_wait. We will wake up when the last writer has
** finished the transaction, and started it on its way to the disk.
@@ -3562,9 +3579,8 @@ static int check_journal_end(struct reiserfs_transaction_handle *th,
unlock_journal(p_s_sb);
}
}
- if (journal->j_trans_id == trans_id) {
- BUG();
- }
+ BUG_ON(journal->j_trans_id == trans_id);
+
if (commit_now
&& journal_list_still_alive(p_s_sb, trans_id)
&& wait_on_commit) {
@@ -3844,7 +3860,9 @@ static void flush_old_journal_lists(struct super_block *s)
entry = journal->j_journal_list.next;
jl = JOURNAL_LIST_ENTRY(entry);
/* this check should always be run, to send old lists to disk */
- if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4))) {
+ if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4)) &&
+ atomic_read(&jl->j_commit_left) == 0 &&
+ test_transaction(s, jl)) {
flush_used_journal_lists(s, jl);
} else {
break;
@@ -4042,9 +4060,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
set_commit_trans_len(commit, journal->j_len);
/* special check in case all buffers in the journal were marked for not logging */
- if (journal->j_len == 0) {
- BUG();
- }
+ BUG_ON(journal->j_len == 0);
/* we're about to dirty all the log blocks, mark the description block
* dirty now too. Don't mark the commit block dirty until all the
@@ -4141,8 +4157,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
journal, jl, &jl->j_tail_bh_list);
lock_kernel();
}
- if (!list_empty(&jl->j_tail_bh_list))
- BUG();
+ BUG_ON(!list_empty(&jl->j_tail_bh_list));
up(&jl->j_commit_lock);
/* honor the flush wishes from the caller, simple commits can