aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c24
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]);