aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index fada9c22a021..535cee47fcfb 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3379,11 +3379,13 @@ static int noinline relocate_data_extent(struct inode *reloc_inode,
3379 struct btrfs_root *root = BTRFS_I(reloc_inode)->root; 3379 struct btrfs_root *root = BTRFS_I(reloc_inode)->root;
3380 struct extent_map_tree *em_tree = &BTRFS_I(reloc_inode)->extent_tree; 3380 struct extent_map_tree *em_tree = &BTRFS_I(reloc_inode)->extent_tree;
3381 struct extent_map *em; 3381 struct extent_map *em;
3382 u64 start = extent_key->objectid - offset;
3383 u64 end = start + extent_key->offset - 1;
3382 3384
3383 em = alloc_extent_map(GFP_NOFS); 3385 em = alloc_extent_map(GFP_NOFS);
3384 BUG_ON(!em || IS_ERR(em)); 3386 BUG_ON(!em || IS_ERR(em));
3385 3387
3386 em->start = extent_key->objectid - offset; 3388 em->start = start;
3387 em->len = extent_key->offset; 3389 em->len = extent_key->offset;
3388 em->block_len = extent_key->offset; 3390 em->block_len = extent_key->offset;
3389 em->block_start = extent_key->objectid; 3391 em->block_start = extent_key->objectid;
@@ -3391,7 +3393,7 @@ static int noinline relocate_data_extent(struct inode *reloc_inode,
3391 set_bit(EXTENT_FLAG_PINNED, &em->flags); 3393 set_bit(EXTENT_FLAG_PINNED, &em->flags);
3392 3394
3393 /* setup extent map to cheat btrfs_readpage */ 3395 /* setup extent map to cheat btrfs_readpage */
3394 mutex_lock(&BTRFS_I(reloc_inode)->extent_mutex); 3396 lock_extent(&BTRFS_I(reloc_inode)->io_tree, start, end, GFP_NOFS);
3395 while (1) { 3397 while (1) {
3396 int ret; 3398 int ret;
3397 spin_lock(&em_tree->lock); 3399 spin_lock(&em_tree->lock);
@@ -3401,13 +3403,11 @@ static int noinline relocate_data_extent(struct inode *reloc_inode,
3401 free_extent_map(em); 3403 free_extent_map(em);
3402 break; 3404 break;
3403 } 3405 }
3404 btrfs_drop_extent_cache(reloc_inode, em->start, 3406 btrfs_drop_extent_cache(reloc_inode, start, end, 0);
3405 em->start + em->len - 1, 0);
3406 } 3407 }
3407 mutex_unlock(&BTRFS_I(reloc_inode)->extent_mutex); 3408 unlock_extent(&BTRFS_I(reloc_inode)->io_tree, start, end, GFP_NOFS);
3408 3409
3409 return relocate_inode_pages(reloc_inode, extent_key->objectid - offset, 3410 return relocate_inode_pages(reloc_inode, start, extent_key->offset);
3410 extent_key->offset);
3411} 3411}
3412 3412
3413struct btrfs_ref_path { 3413struct btrfs_ref_path {
@@ -3831,7 +3831,6 @@ next:
3831 * the file extent item was modified by someone 3831 * the file extent item was modified by someone
3832 * before the extent got locked. 3832 * before the extent got locked.
3833 */ 3833 */
3834 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
3835 unlock_extent(&BTRFS_I(inode)->io_tree, lock_start, 3834 unlock_extent(&BTRFS_I(inode)->io_tree, lock_start,
3836 lock_end, GFP_NOFS); 3835 lock_end, GFP_NOFS);
3837 extent_locked = 0; 3836 extent_locked = 0;
@@ -3896,8 +3895,12 @@ next:
3896 lock_start = key.offset; 3895 lock_start = key.offset;
3897 lock_end = lock_start + num_bytes - 1; 3896 lock_end = lock_start + num_bytes - 1;
3898 } else { 3897 } else {
3899 BUG_ON(lock_start != key.offset); 3898 if (lock_start > key.offset ||
3900 BUG_ON(lock_end - lock_start + 1 < num_bytes); 3899 lock_end + 1 < key.offset + num_bytes) {
3900 unlock_extent(&BTRFS_I(inode)->io_tree,
3901 lock_start, lock_end, GFP_NOFS);
3902 extent_locked = 0;
3903 }
3901 } 3904 }
3902 3905
3903 if (!inode) { 3906 if (!inode) {
@@ -3951,7 +3954,6 @@ next:
3951 if (ordered) 3954 if (ordered)
3952 btrfs_put_ordered_extent(ordered); 3955 btrfs_put_ordered_extent(ordered);
3953 3956
3954 mutex_lock(&BTRFS_I(inode)->extent_mutex);
3955 extent_locked = 1; 3957 extent_locked = 1;
3956 continue; 3958 continue;
3957 } 3959 }
@@ -4073,7 +4075,6 @@ next:
4073 } 4075 }
4074 4076
4075 if (extent_locked) { 4077 if (extent_locked) {
4076 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
4077 unlock_extent(&BTRFS_I(inode)->io_tree, lock_start, 4078 unlock_extent(&BTRFS_I(inode)->io_tree, lock_start,
4078 lock_end, GFP_NOFS); 4079 lock_end, GFP_NOFS);
4079 extent_locked = 0; 4080 extent_locked = 0;
@@ -4091,7 +4092,6 @@ out:
4091 if (inode) { 4092 if (inode) {
4092 mutex_unlock(&inode->i_mutex); 4093 mutex_unlock(&inode->i_mutex);
4093 if (extent_locked) { 4094 if (extent_locked) {
4094 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
4095 unlock_extent(&BTRFS_I(inode)->io_tree, lock_start, 4095 unlock_extent(&BTRFS_I(inode)->io_tree, lock_start,
4096 lock_end, GFP_NOFS); 4096 lock_end, GFP_NOFS);
4097 } 4097 }
@@ -4180,10 +4180,8 @@ static int noinline invalidate_extent_cache(struct btrfs_root *root,
4180 4180
4181 lock_extent(&BTRFS_I(inode)->io_tree, key.offset, 4181 lock_extent(&BTRFS_I(inode)->io_tree, key.offset,
4182 key.offset + num_bytes - 1, GFP_NOFS); 4182 key.offset + num_bytes - 1, GFP_NOFS);
4183 mutex_lock(&BTRFS_I(inode)->extent_mutex);
4184 btrfs_drop_extent_cache(inode, key.offset, 4183 btrfs_drop_extent_cache(inode, key.offset,
4185 key.offset + num_bytes - 1, 1); 4184 key.offset + num_bytes - 1, 1);
4186 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
4187 unlock_extent(&BTRFS_I(inode)->io_tree, key.offset, 4185 unlock_extent(&BTRFS_I(inode)->io_tree, key.offset,
4188 key.offset + num_bytes - 1, GFP_NOFS); 4186 key.offset + num_bytes - 1, GFP_NOFS);
4189 cond_resched(); 4187 cond_resched();