diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2008-10-30 14:19:50 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-10-30 14:19:50 -0400 |
commit | 6643558db29006825dbb10012b3f8890aca4bcd5 (patch) | |
tree | 0c0f4f7a0011749cda998431828cb9161747b51a /fs/btrfs/inode.c | |
parent | 9036c10208e1fc496cef7692ba66a78699b360dc (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.c | 10 |
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; |