diff options
Diffstat (limited to 'fs/btrfs/file.c')
| -rw-r--r-- | fs/btrfs/file.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 6ed434ac037f..29ff749ff4ca 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/writeback.h> | 28 | #include <linux/writeback.h> |
| 29 | #include <linux/statfs.h> | 29 | #include <linux/statfs.h> |
| 30 | #include <linux/compat.h> | 30 | #include <linux/compat.h> |
| 31 | #include <linux/slab.h> | ||
| 31 | #include "ctree.h" | 32 | #include "ctree.h" |
| 32 | #include "disk-io.h" | 33 | #include "disk-io.h" |
| 33 | #include "transaction.h" | 34 | #include "transaction.h" |
| @@ -123,7 +124,8 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
| 123 | root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | 124 | root->sectorsize - 1) & ~((u64)root->sectorsize - 1); |
| 124 | 125 | ||
| 125 | end_of_last_block = start_pos + num_bytes - 1; | 126 | end_of_last_block = start_pos + num_bytes - 1; |
| 126 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block); | 127 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, |
| 128 | NULL); | ||
| 127 | if (err) | 129 | if (err) |
| 128 | return err; | 130 | return err; |
| 129 | 131 | ||
| @@ -753,6 +755,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, | |||
| 753 | loff_t pos, unsigned long first_index, | 755 | loff_t pos, unsigned long first_index, |
| 754 | unsigned long last_index, size_t write_bytes) | 756 | unsigned long last_index, size_t write_bytes) |
| 755 | { | 757 | { |
| 758 | struct extent_state *cached_state = NULL; | ||
| 756 | int i; | 759 | int i; |
| 757 | unsigned long index = pos >> PAGE_CACHE_SHIFT; | 760 | unsigned long index = pos >> PAGE_CACHE_SHIFT; |
| 758 | struct inode *inode = fdentry(file)->d_inode; | 761 | struct inode *inode = fdentry(file)->d_inode; |
| @@ -781,16 +784,18 @@ again: | |||
| 781 | } | 784 | } |
| 782 | if (start_pos < inode->i_size) { | 785 | if (start_pos < inode->i_size) { |
| 783 | struct btrfs_ordered_extent *ordered; | 786 | struct btrfs_ordered_extent *ordered; |
| 784 | lock_extent(&BTRFS_I(inode)->io_tree, | 787 | lock_extent_bits(&BTRFS_I(inode)->io_tree, |
| 785 | start_pos, last_pos - 1, GFP_NOFS); | 788 | start_pos, last_pos - 1, 0, &cached_state, |
| 789 | GFP_NOFS); | ||
| 786 | ordered = btrfs_lookup_first_ordered_extent(inode, | 790 | ordered = btrfs_lookup_first_ordered_extent(inode, |
| 787 | last_pos - 1); | 791 | last_pos - 1); |
| 788 | if (ordered && | 792 | if (ordered && |
| 789 | ordered->file_offset + ordered->len > start_pos && | 793 | ordered->file_offset + ordered->len > start_pos && |
| 790 | ordered->file_offset < last_pos) { | 794 | ordered->file_offset < last_pos) { |
| 791 | btrfs_put_ordered_extent(ordered); | 795 | btrfs_put_ordered_extent(ordered); |
| 792 | unlock_extent(&BTRFS_I(inode)->io_tree, | 796 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, |
| 793 | start_pos, last_pos - 1, GFP_NOFS); | 797 | start_pos, last_pos - 1, |
| 798 | &cached_state, GFP_NOFS); | ||
| 794 | for (i = 0; i < num_pages; i++) { | 799 | for (i = 0; i < num_pages; i++) { |
| 795 | unlock_page(pages[i]); | 800 | unlock_page(pages[i]); |
| 796 | page_cache_release(pages[i]); | 801 | page_cache_release(pages[i]); |
| @@ -802,12 +807,13 @@ again: | |||
| 802 | if (ordered) | 807 | if (ordered) |
| 803 | btrfs_put_ordered_extent(ordered); | 808 | btrfs_put_ordered_extent(ordered); |
| 804 | 809 | ||
| 805 | clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, | 810 | clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos, |
| 806 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC | | 811 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC | |
| 807 | EXTENT_DO_ACCOUNTING, | 812 | EXTENT_DO_ACCOUNTING, 0, 0, &cached_state, |
| 808 | GFP_NOFS); | 813 | GFP_NOFS); |
| 809 | unlock_extent(&BTRFS_I(inode)->io_tree, | 814 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, |
| 810 | start_pos, last_pos - 1, GFP_NOFS); | 815 | start_pos, last_pos - 1, &cached_state, |
| 816 | GFP_NOFS); | ||
| 811 | } | 817 | } |
| 812 | for (i = 0; i < num_pages; i++) { | 818 | for (i = 0; i < num_pages; i++) { |
| 813 | clear_page_dirty_for_io(pages[i]); | 819 | clear_page_dirty_for_io(pages[i]); |
