The only reason why ext3 takes lock_kernel() is because it is requires by the
JBD API.

The patch removes the lock_kernels() from ext3 and pushes them down into JBD
itself.



 fs/ext3/inode.c      |   39 -----------------------------
 fs/ext3/namei.c      |   68 +++++++++------------------------------------------
 fs/ext3/super.c      |   27 ++++++--------------
 fs/ext3/xattr.c      |    2 -
 fs/jbd/journal.c     |   16 +++++++++++-
 fs/jbd/transaction.c |   33 +++++++++++++++++++-----
 6 files changed, 63 insertions(+), 122 deletions(-)

diff -puN fs/ext3/inode.c~ext3-no-bkl fs/ext3/inode.c
--- 25/fs/ext3/inode.c~ext3-no-bkl	2003-06-07 15:31:57.000000000 -0700
+++ 25-akpm/fs/ext3/inode.c	2003-06-07 15:40:51.000000000 -0700
@@ -199,7 +199,6 @@ void ext3_delete_inode (struct inode * i
 	if (is_bad_inode(inode))
 		goto no_delete;
 
-	lock_kernel();
 	handle = start_transaction(inode);
 	if (IS_ERR(handle)) {
 		/* If we're going to skip the normal cleanup, we still
@@ -208,7 +207,6 @@ void ext3_delete_inode (struct inode * i
 		ext3_orphan_del(NULL, inode);
 
 		ext3_std_error(inode->i_sb, PTR_ERR(handle));
-		unlock_kernel();
 		goto no_delete;
 	}
 	
@@ -241,7 +239,6 @@ void ext3_delete_inode (struct inode * i
 	else
 		ext3_free_inode(handle, inode);
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return;
 no_delete:
 	clear_inode(inode);	/* We must guarantee clearing of inode... */
@@ -251,7 +248,6 @@ void ext3_discard_prealloc (struct inode
 {
 #ifdef EXT3_PREALLOCATE
 	struct ext3_inode_info *ei = EXT3_I(inode);
-	lock_kernel();
 	/* Writer: ->i_prealloc* */
 	if (ei->i_prealloc_count) {
 		unsigned short total = ei->i_prealloc_count;
@@ -261,7 +257,6 @@ void ext3_discard_prealloc (struct inode
 		/* Writer: end */
 		ext3_free_blocks (inode, block, total);
 	}
-	unlock_kernel();
 #endif
 }
 
@@ -781,7 +776,6 @@ ext3_get_block_handle(handle_t *handle, 
 	if (depth == 0)
 		goto out;
 
-	lock_kernel();
 reread:
 	partial = ext3_get_branch(inode, depth, offsets, chain, &err);
 
@@ -806,7 +800,6 @@ cleanup:
 			partial--;
 		}
 		BUFFER_TRACE(bh_result, "returned");
-		unlock_kernel();
 out:
 		return err;
 	}
@@ -894,7 +887,6 @@ ext3_direct_io_get_blocks(struct inode *
 	handle_t *handle = journal_current_handle();
 	int ret = 0;
 
-	lock_kernel();
 	if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
 		/*
 		 * Getting low on buffer credits...
@@ -911,7 +903,6 @@ ext3_direct_io_get_blocks(struct inode *
 					bh_result, create, 0);
 	if (ret == 0)
 		bh_result->b_size = (1 << inode->i_blkbits);
-	unlock_kernel();
 	return ret;
 }
 
@@ -944,7 +935,6 @@ struct buffer_head *ext3_getblk(handle_t
 			   For now, regular file writes use
 			   ext3_get_block instead, so it's not a
 			   problem. */
-			lock_kernel();
 			lock_buffer(bh);
 			BUFFER_TRACE(bh, "call get_create_access");
 			fatal = ext3_journal_get_create_access(handle, bh);
@@ -957,7 +947,6 @@ struct buffer_head *ext3_getblk(handle_t
 			BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
 			err = ext3_journal_dirty_metadata(handle, bh);
 			if (!fatal) fatal = err;
-			unlock_kernel();
 		} else {
 			BUFFER_TRACE(bh, "not a new buffer");
 		}
@@ -1094,15 +1083,12 @@ static int ext3_prepare_write(struct fil
 	int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
 	handle_t *handle;
 
-	lock_kernel();
 	handle = ext3_journal_start(inode, needed_blocks);
 	if (IS_ERR(handle)) {
 		ret = PTR_ERR(handle);
 		goto out;
 	}
-	unlock_kernel();
 	ret = block_prepare_write(page, from, to, ext3_get_block);
-	lock_kernel();
 	if (ret != 0)
 		goto prepare_write_failed;
 
@@ -1114,7 +1100,6 @@ prepare_write_failed:
 	if (ret)
 		ext3_journal_stop(handle);
 out:
-	unlock_kernel();
 	return ret;
 }
 
@@ -1150,7 +1135,6 @@ static int ext3_commit_write(struct file
 	struct inode *inode = page->mapping->host;
 	int ret = 0, ret2;
 
-	lock_kernel();
 	if (ext3_should_journal_data(inode)) {
 		/*
 		 * Here we duplicate the generic_commit_write() functionality
@@ -1192,7 +1176,6 @@ static int ext3_commit_write(struct file
 		}
 	}
 	ret2 = ext3_journal_stop(handle);
-	unlock_kernel();
 	if (!ret)
 		ret = ret2;
 	return ret;
@@ -1334,7 +1317,6 @@ static int ext3_writepage(struct page *p
 	 * for a different filesystem.  One *could* look for a
 	 * nested transaction opportunity.
 	 */
-	lock_kernel();
 	if (ext3_journal_current_handle())
 		goto out_fail;
 
@@ -1349,8 +1331,6 @@ static int ext3_writepage(struct page *p
 	order_data = ext3_should_order_data(inode) ||
 			ext3_should_journal_data(inode);
 
-	unlock_kernel();
-
 	page_bufs = NULL;	/* Purely to prevent compiler warning */
 
 	/* bget() all the buffers */
@@ -1377,7 +1357,6 @@ static int ext3_writepage(struct page *p
 	 */
 
 	handle = ext3_journal_current_handle();
-	lock_kernel();
 
 	/*
 	 * And attach them to the current transaction.  But only if 
@@ -1399,13 +1378,10 @@ static int ext3_writepage(struct page *p
 	err = ext3_journal_stop(handle);
 	if (!ret)
 		ret = err;
-	unlock_kernel();
 	return ret;
 
 out_fail:
 	
-	unlock_kernel();
-
 	/*
 	 * We have to fail this writepage to avoid cross-fs transactions.
 	 * Put the page back on mapping->dirty_pages.  The page's buffers'
@@ -1463,17 +1439,13 @@ static int ext3_direct_IO(int rw, struct
 	if (rw == WRITE) {
 		loff_t final_size = offset + count;
 
-		lock_kernel();
 		handle = ext3_journal_start(inode, DIO_CREDITS);
-		unlock_kernel();
 		if (IS_ERR(handle)) {
 			ret = PTR_ERR(handle);
 			goto out;
 		}
 		if (final_size > inode->i_size) {
-			lock_kernel();
 			ret = ext3_orphan_add(handle, inode);
-			unlock_kernel();
 			if (ret)
 				goto out_stop;
 			orphan = 1;
@@ -1488,7 +1460,6 @@ out_stop:
 	if (handle) {
 		int err;
 
-		lock_kernel();
 		if (orphan) 
 			ext3_orphan_del(handle, inode);
 		if (orphan && ret > 0) {
@@ -1504,7 +1475,6 @@ out_stop:
 		err = ext3_journal_stop(handle);
 		if (ret == 0)
 			ret = err;
-		unlock_kernel();
 	}
 out:
 	return ret;
@@ -2034,12 +2004,10 @@ void ext3_truncate(struct inode * inode)
 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
 		return;
 
-	lock_kernel();
 	ext3_discard_prealloc(inode);
 
 	handle = start_transaction(inode);
 	if (IS_ERR(handle)) {
-		unlock_kernel();
 		return;		/* AKPM: return what? */
 	}
 
@@ -2163,7 +2131,6 @@ out_stop:
 		ext3_orphan_del(handle, inode);
 
 	ext3_journal_stop(handle);
-	unlock_kernel();
 }
 
 /* 
@@ -2576,8 +2543,6 @@ int ext3_setattr(struct dentry *dentry, 
 			return error;
 	}
 
-	lock_kernel();
-
 	if (S_ISREG(inode->i_mode) &&
 	    attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) {
 		handle_t *handle;
@@ -2609,7 +2574,6 @@ int ext3_setattr(struct dentry *dentry, 
 
 err_out:
 	ext3_std_error(inode->i_sb, error);
-	unlock_kernel();
 	if (!error)
 		error = rc;
 	return error;
@@ -2755,7 +2719,6 @@ void ext3_dirty_inode(struct inode *inod
 	handle_t *current_handle = ext3_journal_current_handle();
 	handle_t *handle;
 
-	lock_kernel();
 	handle = ext3_journal_start(inode, 2);
 	if (IS_ERR(handle))
 		goto out;
@@ -2771,7 +2734,7 @@ void ext3_dirty_inode(struct inode *inod
 	}
 	ext3_journal_stop(handle);
 out:
-	unlock_kernel();
+	return;
 }
 
 #ifdef AKPM
diff -puN fs/ext3/namei.c~ext3-no-bkl fs/ext3/namei.c
--- 25/fs/ext3/namei.c~ext3-no-bkl	2003-06-07 15:31:57.000000000 -0700
+++ 25-akpm/fs/ext3/namei.c	2003-06-07 15:40:50.000000000 -0700
@@ -981,7 +981,6 @@ static struct dentry *ext3_lookup(struct
 	if (dentry->d_name.len > EXT3_NAME_LEN)
 		return ERR_PTR(-ENAMETOOLONG);
 
-	lock_kernel();
 	bh = ext3_find_entry(dentry, &de);
 	inode = NULL;
 	if (bh) {
@@ -989,12 +988,9 @@ static struct dentry *ext3_lookup(struct
 		brelse (bh);
 		inode = iget(dir->i_sb, ino);
 
-		if (!inode) {
-			unlock_kernel();
+		if (!inode)
 			return ERR_PTR(-EACCES);
-		}
 	}
-	unlock_kernel();
 	if (inode)
 		return d_splice_alias(inode, dentry);
 	d_add(dentry, inode);
@@ -1015,17 +1011,13 @@ struct dentry *ext3_get_parent(struct de
 	dotdot.d_name.len = 2;
 	dotdot.d_parent = child; /* confusing, isn't it! */
 
-	lock_kernel();
 	bh = ext3_find_entry(&dotdot, &de);
 	inode = NULL;
-	if (!bh) {
-		unlock_kernel();
+	if (!bh)
 		return ERR_PTR(-ENOENT);
-	}
 	ino = le32_to_cpu(de->inode);
 	brelse(bh);
 	inode = iget(child->d_inode->i_sb, ino);
-	unlock_kernel();
 
 	if (!inode)
 		return ERR_PTR(-EACCES);
@@ -1639,13 +1631,10 @@ static int ext3_create (struct inode * d
 	struct inode * inode;
 	int err;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -1662,7 +1651,6 @@ static int ext3_create (struct inode * d
 		err = ext3_add_nondir(handle, dentry, inode);
 	}
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return err;
 }
 
@@ -1673,13 +1661,10 @@ static int ext3_mknod (struct inode * di
 	struct inode *inode;
 	int err;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
 			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -1694,7 +1679,6 @@ static int ext3_mknod (struct inode * di
 		err = ext3_add_nondir(handle, dentry, inode);
 	}
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return err;
 }
 
@@ -1709,13 +1693,10 @@ static int ext3_mkdir(struct inode * dir
 	if (dir->i_nlink >= EXT3_LINK_MAX)
 		return -EMLINK;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -1768,7 +1749,6 @@ static int ext3_mkdir(struct inode * dir
 	d_instantiate(dentry, inode);
 out_stop:
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return err;
 }
 
@@ -1993,12 +1973,9 @@ static int ext3_rmdir (struct inode * di
 	struct ext3_dir_entry_2 * de;
 	handle_t *handle;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	retval = -ENOENT;
 	bh = ext3_find_entry (dentry, &de);
@@ -2042,7 +2019,6 @@ static int ext3_rmdir (struct inode * di
 end_rmdir:
 	ext3_journal_stop(handle);
 	brelse (bh);
-	unlock_kernel();
 	return retval;
 }
 
@@ -2054,12 +2030,9 @@ static int ext3_unlink(struct inode * di
 	struct ext3_dir_entry_2 * de;
 	handle_t *handle;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -2097,7 +2070,6 @@ static int ext3_unlink(struct inode * di
 
 end_unlink:
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	brelse (bh);
 	return retval;
 }
@@ -2113,13 +2085,10 @@ static int ext3_symlink (struct inode * 
 	if (l > dir->i_sb->s_blocksize)
 		return -ENAMETOOLONG;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
 			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -2156,7 +2125,6 @@ static int ext3_symlink (struct inode * 
 	err = ext3_add_nondir(handle, dentry, inode);
 out_stop:
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return err;
 }
 
@@ -2167,18 +2135,13 @@ static int ext3_link (struct dentry * ol
 	struct inode *inode = old_dentry->d_inode;
 	int err;
 
-	lock_kernel();
-	if (inode->i_nlink >= EXT3_LINK_MAX) {
-		unlock_kernel();
+	if (inode->i_nlink >= EXT3_LINK_MAX)
 		return -EMLINK;
-	}
 
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -2189,7 +2152,6 @@ static int ext3_link (struct dentry * ol
 
 	err = ext3_add_nondir(handle, dentry, inode);
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return err;
 }
 
@@ -2212,13 +2174,10 @@ static int ext3_rename (struct inode * o
 
 	old_bh = new_bh = dir_bh = NULL;
 
-	lock_kernel();
 	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
 			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
 		handle->h_sync = 1;
@@ -2346,7 +2305,6 @@ end_rename:
 	brelse (old_bh);
 	brelse (new_bh);
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return retval;
 }
 
@@ -2378,6 +2336,4 @@ struct inode_operations ext3_special_ino
 	.listxattr	= ext3_listxattr,
 	.removexattr	= ext3_removexattr,
 	.permission	= ext3_permission,
-};
-
- 
+}; 
diff -puN fs/ext3/super.c~ext3-no-bkl fs/ext3/super.c
--- 25/fs/ext3/super.c~ext3-no-bkl	2003-06-07 15:31:57.000000000 -0700
+++ 25-akpm/fs/ext3/super.c	2003-06-07 15:40:56.000000000 -0700
@@ -1777,9 +1777,7 @@ int ext3_force_commit(struct super_block
 
 	journal = EXT3_SB(sb)->s_journal;
 	sb->s_dirt = 0;
-	lock_kernel();	/* important: lock down j_running_transaction */
 	ret = ext3_journal_force_commit(journal);
-	unlock_kernel();
 	return ret;
 }
 
@@ -1794,24 +1792,20 @@ int ext3_force_commit(struct super_block
 
 void ext3_write_super (struct super_block * sb)
 {
-	lock_kernel();	
 	if (down_trylock(&sb->s_lock) == 0)
 		BUG();
 	sb->s_dirt = 0;
 	log_start_commit(EXT3_SB(sb)->s_journal, NULL);
-	unlock_kernel();
 }
 
 static int ext3_sync_fs(struct super_block *sb, int wait)
 {
 	tid_t target;
 
-	lock_kernel();	
 	sb->s_dirt = 0;
 	target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
 	if (wait)
 		log_wait_commit(EXT3_SB(sb)->s_journal, target);
-	unlock_kernel();
 	return 0;
 }
 
@@ -1823,7 +1817,6 @@ void ext3_write_super_lockfs(struct supe
 {
 	sb->s_dirt = 0;
 
-	lock_kernel();		/* 2.4.5 forgot to do this for us */
 	if (!(sb->s_flags & MS_RDONLY)) {
 		journal_t *journal = EXT3_SB(sb)->s_journal;
 
@@ -1835,7 +1828,6 @@ void ext3_write_super_lockfs(struct supe
 		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
 		ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
 	}
-	unlock_kernel();
 }
 
 /*
@@ -1845,14 +1837,12 @@ void ext3_write_super_lockfs(struct supe
 void ext3_unlockfs(struct super_block *sb)
 {
 	if (!(sb->s_flags & MS_RDONLY)) {
-		lock_kernel();
 		lock_super(sb);
 		/* Reser the needs_recovery flag before the fs is unlocked. */
 		EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
 		ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
 		unlock_super(sb);
 		journal_unlock_updates(EXT3_SB(sb)->s_journal);
-		unlock_kernel();
 	}
 }
 
@@ -1997,7 +1987,9 @@ static int (*old_sync_dquot)(struct dquo
 
 static int ext3_sync_dquot(struct dquot *dquot)
 {
-	int nblocks, ret;
+	int nblocks;
+	int ret;
+	int err;
 	handle_t *handle;
 	struct quota_info *dqops = sb_dqopt(dquot->dq_sb);
 	struct inode *qinode;
@@ -2012,18 +2004,17 @@ static int ext3_sync_dquot(struct dquot 
 		default:
 			nblocks = EXT3_MAX_TRANS_DATA;
 	}
-	lock_kernel();
 	qinode = dqops->files[dquot->dq_type]->f_dentry->d_inode;
 	handle = ext3_journal_start(qinode, nblocks);
 	if (IS_ERR(handle)) {
-		unlock_kernel();
-		return PTR_ERR(handle);
+		ret = PTR_ERR(handle);
+		goto out;
 	}
-	unlock_kernel();
 	ret = old_sync_dquot(dquot);
-	lock_kernel();
-	ret = ext3_journal_stop(handle);
-	unlock_kernel();
+	err = ext3_journal_stop(handle);
+	if (ret == 0)
+		ret = err;
+out:
 	return ret;
 }
 #endif
diff -puN fs/ext3/xattr.c~ext3-no-bkl fs/ext3/xattr.c
--- 25/fs/ext3/xattr.c~ext3-no-bkl	2003-06-07 15:31:57.000000000 -0700
+++ 25-akpm/fs/ext3/xattr.c	2003-06-07 15:31:57.000000000 -0700
@@ -849,7 +849,6 @@ ext3_xattr_set(struct inode *inode, int 
 	handle_t *handle;
 	int error, error2;
 
-	lock_kernel();
 	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
 	if (IS_ERR(handle))
 		error = PTR_ERR(handle);
@@ -857,7 +856,6 @@ ext3_xattr_set(struct inode *inode, int 
 		error = ext3_xattr_set_handle(handle, inode, name_index, name,
 					      value, value_len, flags);
 	error2 = ext3_journal_stop(handle);
-	unlock_kernel();
 
 	return error ? error : error2;
 }
diff -puN fs/jbd/journal.c~ext3-no-bkl fs/jbd/journal.c
--- 25/fs/jbd/journal.c~ext3-no-bkl	2003-06-07 15:31:57.000000000 -0700
+++ 25-akpm/fs/jbd/journal.c	2003-06-07 15:40:56.000000000 -0700
@@ -531,9 +531,11 @@ int log_space_left (journal_t *journal)
  */
 tid_t log_start_commit (journal_t *journal, transaction_t *transaction)
 {
-	tid_t target = journal->j_commit_request;
+	tid_t target;
 
 	lock_kernel(); /* Protect journal->j_running_transaction */
+
+	target = journal->j_commit_request;
 	
 	/*
 	 * A NULL transaction asks us to commit the currently running
@@ -968,10 +970,12 @@ void journal_update_superblock(journal_t
 	 * any future commit will have to be careful to update the
 	 * superblock again to re-record the true start of the log. */
 
+	lock_kernel();
 	if (sb->s_start)
 		journal->j_flags &= ~JFS_FLUSHED;
 	else
 		journal->j_flags |= JFS_FLUSHED;
+	unlock_kernel();
 }
 
 
@@ -1437,10 +1441,12 @@ void __journal_abort_hard (journal_t *jo
 	printk (KERN_ERR "Aborting journal on device %s.\n",
 		journal_dev_name(journal, b));
 
+	lock_kernel();
 	journal->j_flags |= JFS_ABORT;
 	transaction = journal->j_running_transaction;
 	if (transaction)
 		log_start_commit(journal, transaction);
+	unlock_kernel();
 }
 
 /* Soft abort: record the abort error status in the journal superblock,
@@ -1450,6 +1456,7 @@ void __journal_abort_soft (journal_t *jo
 	if (journal->j_flags & JFS_ABORT)
 		return;
 
+	lock_kernel();
 	if (!journal->j_errno)
 		journal->j_errno = errno;
 
@@ -1457,6 +1464,7 @@ void __journal_abort_soft (journal_t *jo
 
 	if (errno)
 		journal_update_superblock(journal, 1);
+	unlock_kernel();
 }
 
 /**
@@ -1528,10 +1536,12 @@ int journal_errno (journal_t *journal)
 	int err;
 
 	lock_journal(journal);
+	lock_kernel();
 	if (journal->j_flags & JFS_ABORT)
 		err = -EROFS;
 	else
 		err = journal->j_errno;
+	unlock_kernel();
 	unlock_journal(journal);
 	return err;
 }
@@ -1549,10 +1559,12 @@ int journal_clear_err (journal_t *journa
 	int err = 0;
 
 	lock_journal(journal);
+	lock_kernel();
 	if (journal->j_flags & JFS_ABORT)
 		err = -EROFS;
 	else
 		journal->j_errno = 0;
+	unlock_kernel();
 	unlock_journal(journal);
 	return err;
 }
@@ -1567,8 +1579,10 @@ int journal_clear_err (journal_t *journa
 void journal_ack_err (journal_t *journal)
 {
 	lock_journal(journal);
+	lock_kernel();
 	if (journal->j_errno)
 		journal->j_flags |= JFS_ACK_ERR;
+	unlock_kernel();
 	unlock_journal(journal);
 }
 
diff -puN fs/jbd/transaction.c~ext3-no-bkl fs/jbd/transaction.c
--- 25/fs/jbd/transaction.c~ext3-no-bkl	2003-06-07 15:31:57.000000000 -0700
+++ 25-akpm/fs/jbd/transaction.c	2003-06-07 15:40:56.000000000 -0700
@@ -256,13 +256,14 @@ handle_t *journal_start(journal_t *journ
 
 	current->journal_info = handle;
 
+	lock_kernel();
 	err = start_this_handle(journal, handle);
+	unlock_kernel();
 	if (err < 0) {
 		jbd_free_handle(handle);
 		current->journal_info = NULL;
-		return ERR_PTR(err);
+		handle = ERR_PTR(err);
 	}
-
 	return handle;
 }
 
@@ -307,19 +308,20 @@ int journal_extend (handle_t *handle, in
 			  "transaction not running\n", handle, nblocks);
 		goto error_out;
 	}
-	
+
+	lock_kernel();	
 	wanted = transaction->t_outstanding_credits + nblocks;
 	
 	if (wanted > journal->j_max_transaction_buffers) {
 		jbd_debug(3, "denied handle %p %d blocks: "
 			  "transaction too large\n", handle, nblocks);
-		goto error_out;
+		goto unlock;
 	}
 
 	if (wanted > log_space_left(journal)) {
 		jbd_debug(3, "denied handle %p %d blocks: "
 			  "insufficient log space\n", handle, nblocks);
-		goto error_out;
+		goto unlock;
 	}
 	
 	handle->h_buffer_credits += nblocks;
@@ -327,7 +329,8 @@ int journal_extend (handle_t *handle, in
 	result = 0;
 
 	jbd_debug(3, "extended handle %p by %d\n", handle, nblocks);
-	
+unlock:
+	unlock_kernel();
 error_out:
 	unlock_journal (journal);
 	return result;
@@ -366,6 +369,7 @@ int journal_restart(handle_t *handle, in
 	J_ASSERT (transaction->t_updates > 0);
 	J_ASSERT (journal_current_handle() == handle);
 
+	lock_kernel();
 	transaction->t_outstanding_credits -= handle->h_buffer_credits;
 	transaction->t_updates--;
 
@@ -377,6 +381,7 @@ int journal_restart(handle_t *handle, in
 
 	handle->h_buffer_credits = nblocks;
 	ret = start_this_handle(journal, handle);
+	unlock_kernel();
 	return ret;
 }
 
@@ -394,7 +399,10 @@ int journal_restart(handle_t *handle, in
 void journal_lock_updates (journal_t *journal)
 {
 	lock_journal(journal);
+
+	lock_kernel();
 	++journal->j_barrier_count;
+	unlock_kernel();
 
 	/* Wait until there are no running updates */
 	while (1) {
@@ -433,7 +441,9 @@ void journal_unlock_updates (journal_t *
 	J_ASSERT (journal->j_barrier_count != 0);
 	
 	up(&journal->j_barrier);
+	lock_kernel();
 	--journal->j_barrier_count;
+	unlock_kernel();
 	wake_up(&journal->j_wait_transaction_locked);
 	unlock_journal(journal);
 }
@@ -710,7 +720,9 @@ int journal_get_write_access (handle_t *
 	 * log thread also manipulates.  Make sure that the buffer
 	 * completes any outstanding IO before proceeding. */
 	lock_journal(journal);
+	lock_kernel();
 	rc = do_get_write_access(handle, jh, 0);
+	unlock_kernel();
 	journal_unlock_journal_head(jh);
 	unlock_journal(journal);
 	return rc;
@@ -786,8 +798,10 @@ int journal_get_create_access (handle_t 
 	 * which hits an assertion error.
 	 */
 	JBUFFER_TRACE(jh, "cancelling revoke");
+	lock_kernel();
 	journal_cancel_revoke(handle, jh);
 	journal_unlock_journal_head(jh);
+	unlock_kernel();
 out:
 	unlock_journal(journal);
 	return err;
@@ -832,6 +846,7 @@ int journal_get_undo_access (handle_t *h
 	/* Do this first --- it can drop the journal lock, so we want to
 	 * make sure that obtaining the committed_data is done
 	 * atomically wrt. completion of any outstanding commits. */
+	lock_kernel();
 	err = do_get_write_access (handle, jh, 1);
 	if (err)
 		goto out;
@@ -855,6 +870,7 @@ int journal_get_undo_access (handle_t *h
 	}
 
 out:
+	unlock_kernel();
 	if (!err)
 		J_ASSERT_JH(jh, jh->b_committed_data);
 	journal_unlock_journal_head(jh);
@@ -1302,8 +1318,10 @@ void journal_callback_set(handle_t *hand
 			  void (*func)(struct journal_callback *jcb, int error),
 			  struct journal_callback *jcb)
 {
+	lock_kernel();
 	list_add_tail(&jcb->jcb_list, &handle->h_jcb);
 	jcb->jcb_func = func;
+	unlock_kernel();
 }
 
 
@@ -1366,6 +1384,7 @@ int journal_stop(handle_t *handle)
 	}
 
 	current->journal_info = NULL;
+	lock_kernel();
 	transaction->t_outstanding_credits -= handle->h_buffer_credits;
 	transaction->t_updates--;
 	if (!transaction->t_updates) {
@@ -1404,6 +1423,7 @@ int journal_stop(handle_t *handle)
 		if (handle->h_sync && !(current->flags & PF_MEMALLOC))
 			err = log_wait_commit(journal, tid);
 	}
+	unlock_kernel();
 	jbd_free_handle(handle);
 	return err;
 }
@@ -1985,7 +2005,6 @@ void __journal_refile_buffer(struct jour
 	int was_dirty;
 
 	assert_spin_locked(&journal_datalist_lock);
-	J_ASSERT_JH(jh, kernel_locked());
 
 	/* If the buffer is now unused, just drop it. */
 	if (jh->b_next_transaction == NULL) {

_