aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-10-30 14:19:50 -0400
committerChris Mason <chris.mason@oracle.com>2008-10-30 14:19:50 -0400
commit6643558db29006825dbb10012b3f8890aca4bcd5 (patch)
tree0c0f4f7a0011749cda998431828cb9161747b51a /fs/btrfs/inode.c
parent9036c10208e1fc496cef7692ba66a78699b360dc (diff)
Btrfs: Fix bookend extent race v2
When dropping middle part of an extent, btrfs_drop_extents truncates the extent at first, then inserts a bookend extent. Since truncation and insertion can't be done atomically, there is a small period that the bookend extent isn't in the tree. This causes problem for functions that search the tree for file extent item. The way to fix this is lock the range of the bookend extent before truncation. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c10
1 files changed, 0 insertions, 10 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8254d6fa6910..e8511d14b119 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -246,7 +246,6 @@ static int cow_file_range_inline(struct btrfs_trans_handle *trans,
246 return 1; 246 return 1;
247 } 247 }
248 248
249 mutex_lock(&BTRFS_I(inode)->extent_mutex);
250 ret = btrfs_drop_extents(trans, root, inode, start, 249 ret = btrfs_drop_extents(trans, root, inode, start,
251 aligned_end, aligned_end, &hint_byte); 250 aligned_end, aligned_end, &hint_byte);
252 BUG_ON(ret); 251 BUG_ON(ret);
@@ -258,7 +257,6 @@ static int cow_file_range_inline(struct btrfs_trans_handle *trans,
258 compressed_pages); 257 compressed_pages);
259 BUG_ON(ret); 258 BUG_ON(ret);
260 btrfs_drop_extent_cache(inode, start, aligned_end, 0); 259 btrfs_drop_extent_cache(inode, start, aligned_end, 0);
261 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
262 return 0; 260 return 0;
263} 261}
264 262
@@ -437,9 +435,7 @@ again:
437 BUG_ON(disk_num_bytes > 435 BUG_ON(disk_num_bytes >
438 btrfs_super_total_bytes(&root->fs_info->super_copy)); 436 btrfs_super_total_bytes(&root->fs_info->super_copy));
439 437
440 mutex_lock(&BTRFS_I(inode)->extent_mutex);
441 btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0); 438 btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0);
442 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
443 439
444 while(disk_num_bytes > 0) { 440 while(disk_num_bytes > 0) {
445 unsigned long min_bytes; 441 unsigned long min_bytes;
@@ -477,8 +473,6 @@ again:
477 em->block_start = ins.objectid; 473 em->block_start = ins.objectid;
478 em->block_len = ins.offset; 474 em->block_len = ins.offset;
479 em->bdev = root->fs_info->fs_devices->latest_bdev; 475 em->bdev = root->fs_info->fs_devices->latest_bdev;
480
481 mutex_lock(&BTRFS_I(inode)->extent_mutex);
482 set_bit(EXTENT_FLAG_PINNED, &em->flags); 476 set_bit(EXTENT_FLAG_PINNED, &em->flags);
483 477
484 if (will_compress) 478 if (will_compress)
@@ -495,7 +489,6 @@ again:
495 btrfs_drop_extent_cache(inode, start, 489 btrfs_drop_extent_cache(inode, start,
496 start + ram_size - 1, 0); 490 start + ram_size - 1, 0);
497 } 491 }
498 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
499 492
500 cur_alloc_size = ins.offset; 493 cur_alloc_size = ins.offset;
501 ret = btrfs_add_ordered_extent(inode, start, ins.objectid, 494 ret = btrfs_add_ordered_extent(inode, start, ins.objectid,
@@ -1016,8 +1009,6 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
1016 1009
1017 INIT_LIST_HEAD(&list); 1010 INIT_LIST_HEAD(&list);
1018 1011
1019 mutex_lock(&BTRFS_I(inode)->extent_mutex);
1020
1021 ret = btrfs_drop_extents(trans, root, inode, 1012 ret = btrfs_drop_extents(trans, root, inode,
1022 ordered_extent->file_offset, 1013 ordered_extent->file_offset,
1023 ordered_extent->file_offset + 1014 ordered_extent->file_offset +
@@ -1059,7 +1050,6 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
1059 btrfs_drop_extent_cache(inode, ordered_extent->file_offset, 1050 btrfs_drop_extent_cache(inode, ordered_extent->file_offset,
1060 ordered_extent->file_offset + 1051 ordered_extent->file_offset +
1061 ordered_extent->len - 1, 0); 1052 ordered_extent->len - 1, 0);
1062 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
1063 1053
1064 ins.objectid = ordered_extent->start; 1054 ins.objectid = ordered_extent->start;
1065 ins.offset = ordered_extent->disk_len; 1055 ins.offset = ordered_extent->disk_len;