diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-07-18 12:01:11 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:05 -0400 |
commit | 7f3c74fb831fa19bafe087e817c0a5ff3883f1ea (patch) | |
tree | 416e95db10e408240916d5061caf1e5d1182b330 /fs/btrfs/inode.c | |
parent | 211f90e68b679d27fe23c5505f86d6ce62c98bae (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.c | 15 |
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 */ |