Skip to content

Commit

Permalink
kill-the-bkl/reiserfs: factorize the locking in reiserfs_write_end()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Frederic Weisbecker committed Sep 14, 2009
1 parent 09eb47a commit d6f5b0a
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions fs/reiserfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 ++;
Expand All @@ -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 */
Expand All @@ -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;
/*
Expand All @@ -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;
}

Expand Down

0 comments on commit d6f5b0a

Please sign in to comment.