diff -urpN --exclude-from=/home/davej/.exclude bk-linus/fs/jbd/checkpoint.c linux-2.5/fs/jbd/checkpoint.c --- bk-linus/fs/jbd/checkpoint.c 2002-11-21 02:20:15.000000000 +0000 +++ linux-2.5/fs/jbd/checkpoint.c 2002-11-21 18:02:15.000000000 +0000 @@ -443,11 +443,8 @@ int __journal_clean_checkpoint_list(jour struct journal_head *last_jh = jh->b_cpprev; struct journal_head *next_jh = jh; do { - struct buffer_head *bh; - jh = next_jh; next_jh = jh->b_cpnext; - bh = jh2bh(jh); ret += __try_to_free_cp_buf(jh); } while (jh != last_jh); } diff -urpN --exclude-from=/home/davej/.exclude bk-linus/fs/jbd/commit.c linux-2.5/fs/jbd/commit.c --- bk-linus/fs/jbd/commit.c 2002-11-21 02:20:15.000000000 +0000 +++ linux-2.5/fs/jbd/commit.c 2002-11-21 18:02:15.000000000 +0000 @@ -25,7 +25,7 @@ extern spinlock_t journal_datalist_lock; /* * Default IO end handler for temporary BJ_IO buffer_heads. */ -static void journal_end_buffer_io_sync(struct buffer_head *bh, int uptodate) +void journal_end_buffer_io_sync(struct buffer_head *bh, int uptodate) { BUFFER_TRACE(bh, ""); if (uptodate) @@ -406,6 +406,7 @@ sync_datalist_empty: flags = journal_write_metadata_buffer(commit_transaction, jh, &new_jh, blocknr); set_bit(BH_JWrite, &jh2bh(new_jh)->b_state); + set_bit(BH_Lock, &jh2bh(new_jh)->b_state); wbuf[bufs++] = jh2bh(new_jh); /* Record the new block's tag in the current descriptor @@ -557,8 +558,7 @@ start_journal_io: journal_unfile_buffer(jh); jh->b_transaction = NULL; journal_unlock_journal_head(jh); - __brelse(bh); /* One for getblk */ - /* AKPM: bforget here */ + put_bh(bh); /* One for getblk */ } jbd_debug(3, "JBD: commit phase 6\n"); @@ -594,9 +594,10 @@ start_journal_io: { struct buffer_head *bh = jh2bh(descriptor); set_buffer_uptodate(bh); - ll_rw_block(WRITE, 1, &bh); + bh->b_end_io = journal_end_buffer_io_sync; + submit_bh(WRITE, bh); wait_on_buffer(bh); - __brelse(bh); /* One for getblk() */ + put_bh(bh); /* One for getblk() */ journal_unlock_journal_head(descriptor); } diff -urpN --exclude-from=/home/davej/.exclude bk-linus/fs/jbd/journal.c linux-2.5/fs/jbd/journal.c --- bk-linus/fs/jbd/journal.c 2002-11-21 02:20:15.000000000 +0000 +++ linux-2.5/fs/jbd/journal.c 2002-11-21 18:02:16.000000000 +0000 @@ -661,6 +661,8 @@ int journal_bmap(journal_t *journal, uns * We play buffer_head aliasing tricks to write data/metadata blocks to * the journal without copying their contents, but for journal * descriptor blocks we do need to generate bona fide buffers. + * + * We return a jh whose bh is locked and ready to be populated. */ struct journal_head * journal_get_descriptor_buffer(journal_t *journal) @@ -675,7 +677,7 @@ struct journal_head * journal_get_descri return NULL; bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); - bh->b_state |= (1 << BH_Dirty); + lock_buffer(bh); BUFFER_TRACE(bh, "return this buffer"); return journal_add_journal_head(bh); } diff -urpN --exclude-from=/home/davej/.exclude bk-linus/fs/jbd/revoke.c linux-2.5/fs/jbd/revoke.c --- bk-linus/fs/jbd/revoke.c 2002-11-21 02:20:16.000000000 +0000 +++ linux-2.5/fs/jbd/revoke.c 2002-11-21 18:02:16.000000000 +0000 @@ -530,6 +530,7 @@ static void flush_descriptor(journal_t * if (is_journal_aborted(journal)) { JBUFFER_TRACE(descriptor, "brelse"); + unlock_buffer(jh2bh(descriptor)); __brelse(jh2bh(descriptor)); return; } @@ -541,7 +542,8 @@ static void flush_descriptor(journal_t * struct buffer_head *bh = jh2bh(descriptor); BUFFER_TRACE(bh, "write"); set_buffer_uptodate(bh); - ll_rw_block (WRITE, 1, &bh); + bh->b_end_io = journal_end_buffer_io_sync; + submit_bh(WRITE, bh); } } diff -urpN --exclude-from=/home/davej/.exclude bk-linus/fs/jbd/transaction.c linux-2.5/fs/jbd/transaction.c --- bk-linus/fs/jbd/transaction.c 2002-11-21 02:20:16.000000000 +0000 +++ linux-2.5/fs/jbd/transaction.c 2002-11-21 18:02:16.000000000 +0000 @@ -105,6 +105,8 @@ repeat: lock_journal(journal); +repeat_locked: + if (is_journal_aborted(journal) || (journal->j_errno != 0 && !(journal->j_flags & JFS_ACK_ERR))) { unlock_journal(journal); @@ -118,7 +120,6 @@ repeat: goto repeat; } -repeat_locked: if (!journal->j_running_transaction) get_transaction(journal, 0); /* @@@ Error? */ diff -urpN --exclude-from=/home/davej/.exclude bk-linus/include/linux/jbd.h linux-2.5/include/linux/jbd.h --- bk-linus/include/linux/jbd.h 2002-11-21 02:23:56.000000000 +0000 +++ linux-2.5/include/linux/jbd.h 2002-11-21 18:04:46.000000000 +0000 @@ -585,6 +585,7 @@ extern struct journal_head * journal_get int journal_next_log_block(journal_t *, unsigned long *); /* Commit management */ +void journal_end_buffer_io_sync(struct buffer_head *bh, int uptodate); extern void journal_commit_transaction(journal_t *); /* Checkpoint list management */ @@ -822,8 +823,6 @@ extern int journal_blocks_per_page(struc #define BJ_Reserved 8 /* Buffer is reserved for access by journal */ #define BJ_Types 9 -extern int jbd_blocks_per_page(struct inode *inode); - #ifdef __KERNEL__ extern spinlock_t jh_splice_lock;