aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-05-08 08:53:52 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2009-09-14 01:18:20 -0400
commitd6f5b0aa08078c3dabe377d5b1a6077e9c9352d3 (patch)
treeb5d6bd99e007c57a6cd4953368202d99a41141cd /fs
parent09eb47a7c52ad535aafca889e0b936c445c375ce (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/reiserfs/inode.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 6114050f342e..853f4f6fe920 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2681,6 +2681,8 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2681 int update_sd = 0; 2681 int update_sd = 0;
2682 struct reiserfs_transaction_handle *th; 2682 struct reiserfs_transaction_handle *th;
2683 unsigned start; 2683 unsigned start;
2684 int lock_depth = 0;
2685 bool locked = false;
2684 2686
2685 if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND) 2687 if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND)
2686 pos ++; 2688 pos ++;
@@ -2707,9 +2709,11 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2707 ** to do the i_size updates here. 2709 ** to do the i_size updates here.
2708 */ 2710 */
2709 pos += copied; 2711 pos += copied;
2712
2710 if (pos > inode->i_size) { 2713 if (pos > inode->i_size) {
2711 struct reiserfs_transaction_handle myth; 2714 struct reiserfs_transaction_handle myth;
2712 reiserfs_write_lock(inode->i_sb); 2715 lock_depth = reiserfs_write_lock_once(inode->i_sb);
2716 locked = true;
2713 /* If the file have grown beyond the border where it 2717 /* If the file have grown beyond the border where it
2714 can have a tail, unmark it as needing a tail 2718 can have a tail, unmark it as needing a tail
2715 packing */ 2719 packing */
@@ -2720,10 +2724,9 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2720 REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; 2724 REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
2721 2725
2722 ret = journal_begin(&myth, inode->i_sb, 1); 2726 ret = journal_begin(&myth, inode->i_sb, 1);
2723 if (ret) { 2727 if (ret)
2724 reiserfs_write_unlock(inode->i_sb);
2725 goto journal_error; 2728 goto journal_error;
2726 } 2729
2727 reiserfs_update_inode_transaction(inode); 2730 reiserfs_update_inode_transaction(inode);
2728 inode->i_size = pos; 2731 inode->i_size = pos;
2729 /* 2732 /*
@@ -2735,34 +2738,36 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2735 reiserfs_update_sd(&myth, inode); 2738 reiserfs_update_sd(&myth, inode);
2736 update_sd = 1; 2739 update_sd = 1;
2737 ret = journal_end(&myth, inode->i_sb, 1); 2740 ret = journal_end(&myth, inode->i_sb, 1);
2738 reiserfs_write_unlock(inode->i_sb);
2739 if (ret) 2741 if (ret)
2740 goto journal_error; 2742 goto journal_error;
2741 } 2743 }
2742 if (th) { 2744 if (th) {
2743 reiserfs_write_lock(inode->i_sb); 2745 if (!locked) {
2746 lock_depth = reiserfs_write_lock_once(inode->i_sb);
2747 locked = true;
2748 }
2744 if (!update_sd) 2749 if (!update_sd)
2745 mark_inode_dirty(inode); 2750 mark_inode_dirty(inode);
2746 ret = reiserfs_end_persistent_transaction(th); 2751 ret = reiserfs_end_persistent_transaction(th);
2747 reiserfs_write_unlock(inode->i_sb);
2748 if (ret) 2752 if (ret)
2749 goto out; 2753 goto out;
2750 } 2754 }
2751 2755
2752 out: 2756 out:
2757 if (locked)
2758 reiserfs_write_unlock_once(inode->i_sb, lock_depth);
2753 unlock_page(page); 2759 unlock_page(page);
2754 page_cache_release(page); 2760 page_cache_release(page);
2755 return ret == 0 ? copied : ret; 2761 return ret == 0 ? copied : ret;
2756 2762
2757 journal_error: 2763 journal_error:
2764 reiserfs_write_unlock_once(inode->i_sb, lock_depth);
2765 locked = false;
2758 if (th) { 2766 if (th) {
2759 reiserfs_write_lock(inode->i_sb);
2760 if (!update_sd) 2767 if (!update_sd)
2761 reiserfs_update_sd(th, inode); 2768 reiserfs_update_sd(th, inode);
2762 ret = reiserfs_end_persistent_transaction(th); 2769 ret = reiserfs_end_persistent_transaction(th);
2763 reiserfs_write_unlock(inode->i_sb);
2764 } 2770 }
2765
2766 goto out; 2771 goto out;
2767} 2772}
2768 2773