aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/disk-io.c13
-rw-r--r--fs/btrfs/disk-io.h2
-rw-r--r--fs/btrfs/extent_io.c14
-rw-r--r--fs/btrfs/extent_io.h3
4 files changed, 22 insertions, 10 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 51372a521167..6f58911ece0d 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2735,7 +2735,8 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid)
2735 return ret; 2735 return ret;
2736} 2736}
2737 2737
2738int btree_lock_page_hook(struct page *page) 2738static int btree_lock_page_hook(struct page *page, void *data,
2739 void (*flush_fn)(void *))
2739{ 2740{
2740 struct inode *inode = page->mapping->host; 2741 struct inode *inode = page->mapping->host;
2741 struct btrfs_root *root = BTRFS_I(inode)->root; 2742 struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -2752,7 +2753,10 @@ int btree_lock_page_hook(struct page *page)
2752 if (!eb) 2753 if (!eb)
2753 goto out; 2754 goto out;
2754 2755
2755 btrfs_tree_lock(eb); 2756 if (!btrfs_try_tree_write_lock(eb)) {
2757 flush_fn(data);
2758 btrfs_tree_lock(eb);
2759 }
2756 btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); 2760 btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
2757 2761
2758 if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) { 2762 if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
@@ -2767,7 +2771,10 @@ int btree_lock_page_hook(struct page *page)
2767 btrfs_tree_unlock(eb); 2771 btrfs_tree_unlock(eb);
2768 free_extent_buffer(eb); 2772 free_extent_buffer(eb);
2769out: 2773out:
2770 lock_page(page); 2774 if (!trylock_page(page)) {
2775 flush_fn(data);
2776 lock_page(page);
2777 }
2771 return 0; 2778 return 0;
2772} 2779}
2773 2780
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index bec3ea4bd67f..e678539c8519 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -83,8 +83,6 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
83 struct btrfs_fs_info *fs_info); 83 struct btrfs_fs_info *fs_info);
84int btrfs_add_log_tree(struct btrfs_trans_handle *trans, 84int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
85 struct btrfs_root *root); 85 struct btrfs_root *root);
86int btree_lock_page_hook(struct page *page);
87
88 86
89#ifdef CONFIG_DEBUG_LOCK_ALLOC 87#ifdef CONFIG_DEBUG_LOCK_ALLOC
90void btrfs_init_lockdep(void); 88void btrfs_init_lockdep(void);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index f284d4e5f447..b40ba75f4483 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2613,10 +2613,16 @@ retry:
2613 * swizzled back from swapper_space to tmpfs file 2613 * swizzled back from swapper_space to tmpfs file
2614 * mapping 2614 * mapping
2615 */ 2615 */
2616 if (tree->ops && tree->ops->write_cache_pages_lock_hook) 2616 if (tree->ops &&
2617 tree->ops->write_cache_pages_lock_hook(page); 2617 tree->ops->write_cache_pages_lock_hook) {
2618 else 2618 tree->ops->write_cache_pages_lock_hook(page,
2619 lock_page(page); 2619 data, flush_fn);
2620 } else {
2621 if (!trylock_page(page)) {
2622 flush_fn(data);
2623 lock_page(page);
2624 }
2625 }
2620 2626
2621 if (unlikely(page->mapping != mapping)) { 2627 if (unlikely(page->mapping != mapping)) {
2622 unlock_page(page); 2628 unlock_page(page);
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 325a346369da..cbd4824a7c94 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -86,7 +86,8 @@ struct extent_io_ops {
86 struct extent_state *other); 86 struct extent_state *other);
87 void (*split_extent_hook)(struct inode *inode, 87 void (*split_extent_hook)(struct inode *inode,
88 struct extent_state *orig, u64 split); 88 struct extent_state *orig, u64 split);
89 int (*write_cache_pages_lock_hook)(struct page *page); 89 int (*write_cache_pages_lock_hook)(struct page *page, void *data,
90 void (*flush_fn)(void *));
90}; 91};
91 92
92struct extent_io_tree { 93struct extent_io_tree {