aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-07-18 12:01:11 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commit7f3c74fb831fa19bafe087e817c0a5ff3883f1ea (patch)
tree416e95db10e408240916d5061caf1e5d1182b330 /fs/btrfs/inode.c
parent211f90e68b679d27fe23c5505f86d6ce62c98bae (diff)
Btrfs: Keep extent mappings in ram until pending ordered extents are done
It was possible for stale mappings from disk to be used instead of the new pending ordered extent. This adds a flag to the extent map struct to keep it pinned until the pending ordered extent is actually on disk. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8803abc89bb8..08dbe738b512 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -144,6 +144,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
144 em->len = ins.offset; 144 em->len = ins.offset;
145 em->block_start = ins.objectid; 145 em->block_start = ins.objectid;
146 em->bdev = root->fs_info->fs_devices->latest_bdev; 146 em->bdev = root->fs_info->fs_devices->latest_bdev;
147 set_bit(EXTENT_FLAG_PINNED, &em->flags);
147 while(1) { 148 while(1) {
148 spin_lock(&em_tree->lock); 149 spin_lock(&em_tree->lock);
149 ret = add_extent_mapping(em_tree, em); 150 ret = add_extent_mapping(em_tree, em);
@@ -483,6 +484,8 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
483 struct btrfs_trans_handle *trans; 484 struct btrfs_trans_handle *trans;
484 struct btrfs_ordered_extent *ordered_extent; 485 struct btrfs_ordered_extent *ordered_extent;
485 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 486 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
487 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
488 struct extent_map *em;
486 u64 alloc_hint = 0; 489 u64 alloc_hint = 0;
487 struct list_head list; 490 struct list_head list;
488 struct btrfs_key ins; 491 struct btrfs_key ins;
@@ -524,6 +527,17 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
524 ordered_extent->len, 527 ordered_extent->len,
525 ordered_extent->len, 0); 528 ordered_extent->len, 0);
526 BUG_ON(ret); 529 BUG_ON(ret);
530
531
532 spin_lock(&em_tree->lock);
533 em = lookup_extent_mapping(em_tree, ordered_extent->file_offset,
534 ordered_extent->len);
535 if (em) {
536 clear_bit(EXTENT_FLAG_PINNED, &em->flags);
537 free_extent_map(em);
538 }
539 spin_unlock(&em_tree->lock);
540
527 btrfs_drop_extent_cache(inode, ordered_extent->file_offset, 541 btrfs_drop_extent_cache(inode, ordered_extent->file_offset,
528 ordered_extent->file_offset + 542 ordered_extent->file_offset +
529 ordered_extent->len - 1); 543 ordered_extent->len - 1);
@@ -538,6 +552,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
538 552
539 btrfs_ordered_update_i_size(inode, ordered_extent); 553 btrfs_ordered_update_i_size(inode, ordered_extent);
540 btrfs_remove_ordered_extent(inode, ordered_extent); 554 btrfs_remove_ordered_extent(inode, ordered_extent);
555
541 /* once for us */ 556 /* once for us */
542 btrfs_put_ordered_extent(ordered_extent); 557 btrfs_put_ordered_extent(ordered_extent);
543 /* once for the tree */ 558 /* once for the tree */