forked from Minki/linux
kill-the-bkl/reiserfs: factorize the locking in reiserfs_write_end()
reiserfs_write_end() is a hot path in reiserfs. We have two wasteful write lock lock/release inside that can be gathered without changing the code logic. This patch factorizes them out in a single protected section, reducing the number of contentions inside. [ Impact: reduce lock contention in a reiserfs hotpath ] Cc: Jeff Mahoney <jeffm@suse.com> Cc: Chris Mason <chris.mason@oracle.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Alexander Beregalov <a.beregalov@gmail.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
This commit is contained in:
parent
09eb47a7c5
commit
d6f5b0aa08
@ -2681,6 +2681,8 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
|
||||
int update_sd = 0;
|
||||
struct reiserfs_transaction_handle *th;
|
||||
unsigned start;
|
||||
int lock_depth = 0;
|
||||
bool locked = false;
|
||||
|
||||
if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND)
|
||||
pos ++;
|
||||
@ -2707,9 +2709,11 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
|
||||
** to do the i_size updates here.
|
||||
*/
|
||||
pos += copied;
|
||||
|
||||
if (pos > inode->i_size) {
|
||||
struct reiserfs_transaction_handle myth;
|
||||
reiserfs_write_lock(inode->i_sb);
|
||||
lock_depth = reiserfs_write_lock_once(inode->i_sb);
|
||||
locked = true;
|
||||
/* If the file have grown beyond the border where it
|
||||
can have a tail, unmark it as needing a tail
|
||||
packing */
|
||||
@ -2720,10 +2724,9 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
|
||||
REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
|
||||
|
||||
ret = journal_begin(&myth, inode->i_sb, 1);
|
||||
if (ret) {
|
||||
reiserfs_write_unlock(inode->i_sb);
|
||||
if (ret)
|
||||
goto journal_error;
|
||||
}
|
||||
|
||||
reiserfs_update_inode_transaction(inode);
|
||||
inode->i_size = pos;
|
||||
/*
|
||||
@ -2735,34 +2738,36 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
|
||||
reiserfs_update_sd(&myth, inode);
|
||||
update_sd = 1;
|
||||
ret = journal_end(&myth, inode->i_sb, 1);
|
||||
reiserfs_write_unlock(inode->i_sb);
|
||||
if (ret)
|
||||
goto journal_error;
|
||||
}
|
||||
if (th) {
|
||||
reiserfs_write_lock(inode->i_sb);
|
||||
if (!locked) {
|
||||
lock_depth = reiserfs_write_lock_once(inode->i_sb);
|
||||
locked = true;
|
||||
}
|
||||
if (!update_sd)
|
||||
mark_inode_dirty(inode);
|
||||
ret = reiserfs_end_persistent_transaction(th);
|
||||
reiserfs_write_unlock(inode->i_sb);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (locked)
|
||||
reiserfs_write_unlock_once(inode->i_sb, lock_depth);
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
return ret == 0 ? copied : ret;
|
||||
|
||||
journal_error:
|
||||
reiserfs_write_unlock_once(inode->i_sb, lock_depth);
|
||||
locked = false;
|
||||
if (th) {
|
||||
reiserfs_write_lock(inode->i_sb);
|
||||
if (!update_sd)
|
||||
reiserfs_update_sd(th, inode);
|
||||
ret = reiserfs_end_persistent_transaction(th);
|
||||
reiserfs_write_unlock(inode->i_sb);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user