Commit 3307fbd1 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ext3: move lock_kernel() down into the JBD layer.

This is the start of the ext3 scalability rework.  It basically comes in two
halves:

- ext3 BKL/lock_super removal and scalable inode/block allocators

- JBD locking rework.

The ext3 scalability work was completed a couple of months ago.

The JBD rework has been stable for a couple of weeks now.  My gut feeling is
that there should be one, maybe two bugs left in it, but no problems have
been discovered...


Performance-wise, throughput is increased by up to 2x on dual CPU.  10x on
16-way has been measured.  Given that current ext3 is able to chew two whole
CPUs spinning on locks on a 4-way, that wasn't especially suprising.

These patches were prepared by Alex Tomas <bzzz@tmi.comex.ru> and myself.


First patch: ext3 lock_kernel() removal.

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