diff options
-rw-r--r-- | fs/btrfs/disk-io.c | 13 | ||||
-rw-r--r-- | fs/btrfs/disk-io.h | 2 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 14 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 3 |
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 | ||
2738 | int btree_lock_page_hook(struct page *page) | 2738 | static 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); |
2769 | out: | 2773 | out: |
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); |
84 | int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | 84 | int btrfs_add_log_tree(struct btrfs_trans_handle *trans, |
85 | struct btrfs_root *root); | 85 | struct btrfs_root *root); |
86 | int btree_lock_page_hook(struct page *page); | ||
87 | |||
88 | 86 | ||
89 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 87 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
90 | void btrfs_init_lockdep(void); | 88 | void 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 | ||
92 | struct extent_io_tree { | 93 | struct extent_io_tree { |