jh = next_jh; 
static int __cleanup_transaction(journal_t *journal, transaction_t *transaction){	struct journal_head *jh, *next_jh, *last_jh;	struct buffer_head *bh;	int ret = 0;	assert_spin_locked(&journal->j_list_lock);	jh = transaction->t_checkpoint_list;	if (!jh)		return 0;	last_jh = jh->b_cpprev;	next_jh = jh;	do {		jh = next_jh;		bh = jh2bh(jh);		if (buffer_locked(bh)) {			atomic_inc(&bh->b_count);			spin_unlock(&journal->j_list_lock);			wait_on_buffer(bh);			/* the journal_head may have gone by now */			BUFFER_TRACE(bh, "brelse");			__brelse(bh);			goto out_return_1;		}		/*		 * This is foul		 */		if (!jbd_trylock_bh_state(bh)) {			jbd_sync_bh(journal, bh);			goto out_return_1;		}		if (jh->b_transaction != NULL) {			transaction_t *t = jh->b_transaction;			tid_t tid = t->t_tid;			spin_unlock(&journal->j_list_lock);			jbd_unlock_bh_state(bh);			log_start_commit(journal, tid);			log_wait_commit(journal, tid);			goto out_return_1;		}		/*		 * AKPM: I think the buffer_jbddirty test is redundant - it		 * shouldn't have NULL b_transaction?		 */		next_jh = jh->b_cpnext;		if (!buffer_dirty(bh) && !buffer_jbddirty(bh)) {			BUFFER_TRACE(bh, "remove from checkpoint");			__journal_remove_checkpoint(jh);			jbd_unlock_bh_state(bh);			journal_remove_journal_head(bh);			__brelse(bh);			ret = 1;		} else {			jbd_unlock_bh_state(bh);		}		jh = next_jh;	} while (jh != last_jh);	return ret;out_return_1:	spin_lock(&journal->j_list_lock);	return 1;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/7e3b11a9be6ac94bf4af81757b6a10e7e65b846f/checkpoint.c/clean/fs/jbd/checkpoint.c