aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2012-10-11 16:54:30 -0400
committerChris Mason <chris.mason@fusionio.com>2012-12-16 20:46:24 -0500
commit70c8a91ce21b83ccd2d9e7c968775430ead4353d (patch)
treedc1e83734b08836fc278ae2d763c5d75cc3d4de0 /fs/btrfs/inode.c
parentd6393786cd40f67709324bc4f08d7e4b911153fe (diff)
Btrfs: log changed inodes based on the extent map tree
We don't really need to copy extents from the source tree since we have all of the information already available to us in the extent_map tree. So instead just write the extents straight to the log tree and don't bother to copy the extent items from the source tree. Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c85
1 files changed, 32 insertions, 53 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 73e6833dcc21..355a297e7988 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -95,6 +95,10 @@ static noinline int cow_file_range(struct inode *inode,
95 struct page *locked_page, 95 struct page *locked_page,
96 u64 start, u64 end, int *page_started, 96 u64 start, u64 end, int *page_started,
97 unsigned long *nr_written, int unlock); 97 unsigned long *nr_written, int unlock);
98static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
99 u64 len, u64 orig_start,
100 u64 block_start, u64 block_len,
101 u64 orig_block_len, int type);
98 102
99static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, 103static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
100 struct inode *inode, struct inode *dir, 104 struct inode *inode, struct inode *dir,
@@ -704,10 +708,14 @@ retry:
704 em->compress_type = async_extent->compress_type; 708 em->compress_type = async_extent->compress_type;
705 set_bit(EXTENT_FLAG_PINNED, &em->flags); 709 set_bit(EXTENT_FLAG_PINNED, &em->flags);
706 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); 710 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
711 em->generation = -1;
707 712
708 while (1) { 713 while (1) {
709 write_lock(&em_tree->lock); 714 write_lock(&em_tree->lock);
710 ret = add_extent_mapping(em_tree, em); 715 ret = add_extent_mapping(em_tree, em);
716 if (!ret)
717 list_move(&em->list,
718 &em_tree->modified_extents);
711 write_unlock(&em_tree->lock); 719 write_unlock(&em_tree->lock);
712 if (ret != -EEXIST) { 720 if (ret != -EEXIST) {
713 free_extent_map(em); 721 free_extent_map(em);
@@ -890,10 +898,14 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
890 em->orig_block_len = ins.offset; 898 em->orig_block_len = ins.offset;
891 em->bdev = root->fs_info->fs_devices->latest_bdev; 899 em->bdev = root->fs_info->fs_devices->latest_bdev;
892 set_bit(EXTENT_FLAG_PINNED, &em->flags); 900 set_bit(EXTENT_FLAG_PINNED, &em->flags);
901 em->generation = -1;
893 902
894 while (1) { 903 while (1) {
895 write_lock(&em_tree->lock); 904 write_lock(&em_tree->lock);
896 ret = add_extent_mapping(em_tree, em); 905 ret = add_extent_mapping(em_tree, em);
906 if (!ret)
907 list_move(&em->list,
908 &em_tree->modified_extents);
897 write_unlock(&em_tree->lock); 909 write_unlock(&em_tree->lock);
898 if (ret != -EEXIST) { 910 if (ret != -EEXIST) {
899 free_extent_map(em); 911 free_extent_map(em);
@@ -1320,7 +1332,7 @@ out_check:
1320 em = alloc_extent_map(); 1332 em = alloc_extent_map();
1321 BUG_ON(!em); /* -ENOMEM */ 1333 BUG_ON(!em); /* -ENOMEM */
1322 em->start = cur_offset; 1334 em->start = cur_offset;
1323 em->orig_start = em->start; 1335 em->orig_start = found_key.offset - extent_offset;
1324 em->len = num_bytes; 1336 em->len = num_bytes;
1325 em->block_len = num_bytes; 1337 em->block_len = num_bytes;
1326 em->block_start = disk_bytenr; 1338 em->block_start = disk_bytenr;
@@ -1328,9 +1340,13 @@ out_check:
1328 em->bdev = root->fs_info->fs_devices->latest_bdev; 1340 em->bdev = root->fs_info->fs_devices->latest_bdev;
1329 set_bit(EXTENT_FLAG_PINNED, &em->flags); 1341 set_bit(EXTENT_FLAG_PINNED, &em->flags);
1330 set_bit(EXTENT_FLAG_FILLING, &em->flags); 1342 set_bit(EXTENT_FLAG_FILLING, &em->flags);
1343 em->generation = -1;
1331 while (1) { 1344 while (1) {
1332 write_lock(&em_tree->lock); 1345 write_lock(&em_tree->lock);
1333 ret = add_extent_mapping(em_tree, em); 1346 ret = add_extent_mapping(em_tree, em);
1347 if (!ret)
1348 list_move(&em->list,
1349 &em_tree->modified_extents);
1334 write_unlock(&em_tree->lock); 1350 write_unlock(&em_tree->lock);
1335 if (ret != -EEXIST) { 1351 if (ret != -EEXIST) {
1336 free_extent_map(em); 1352 free_extent_map(em);
@@ -5371,6 +5387,7 @@ again:
5371 if (start + len <= found_key.offset) 5387 if (start + len <= found_key.offset)
5372 goto not_found; 5388 goto not_found;
5373 em->start = start; 5389 em->start = start;
5390 em->orig_start = start;
5374 em->len = found_key.offset - start; 5391 em->len = found_key.offset - start;
5375 goto not_found_em; 5392 goto not_found_em;
5376 } 5393 }
@@ -5423,7 +5440,7 @@ again:
5423 em->len = (copy_size + root->sectorsize - 1) & 5440 em->len = (copy_size + root->sectorsize - 1) &
5424 ~((u64)root->sectorsize - 1); 5441 ~((u64)root->sectorsize - 1);
5425 em->orig_block_len = em->len; 5442 em->orig_block_len = em->len;
5426 em->orig_start = EXTENT_MAP_INLINE; 5443 em->orig_start = em->start;
5427 if (compress_type) { 5444 if (compress_type) {
5428 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); 5445 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
5429 em->compress_type = compress_type; 5446 em->compress_type = compress_type;
@@ -5476,6 +5493,7 @@ again:
5476 } 5493 }
5477not_found: 5494not_found:
5478 em->start = start; 5495 em->start = start;
5496 em->orig_start = start;
5479 em->len = len; 5497 em->len = len;
5480not_found_em: 5498not_found_em:
5481 em->block_start = EXTENT_MAP_HOLE; 5499 em->block_start = EXTENT_MAP_HOLE;
@@ -5677,30 +5695,14 @@ out:
5677} 5695}
5678 5696
5679static struct extent_map *btrfs_new_extent_direct(struct inode *inode, 5697static struct extent_map *btrfs_new_extent_direct(struct inode *inode,
5680 struct extent_map *em,
5681 u64 start, u64 len) 5698 u64 start, u64 len)
5682{ 5699{
5683 struct btrfs_root *root = BTRFS_I(inode)->root; 5700 struct btrfs_root *root = BTRFS_I(inode)->root;
5684 struct btrfs_trans_handle *trans; 5701 struct btrfs_trans_handle *trans;
5685 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; 5702 struct extent_map *em;
5686 struct btrfs_key ins; 5703 struct btrfs_key ins;
5687 u64 alloc_hint; 5704 u64 alloc_hint;
5688 int ret; 5705 int ret;
5689 bool insert = false;
5690
5691 /*
5692 * Ok if the extent map we looked up is a hole and is for the exact
5693 * range we want, there is no reason to allocate a new one, however if
5694 * it is not right then we need to free this one and drop the cache for
5695 * our range.
5696 */
5697 if (em->block_start != EXTENT_MAP_HOLE || em->start != start ||
5698 em->len != len) {
5699 free_extent_map(em);
5700 em = NULL;
5701 insert = true;
5702 btrfs_drop_extent_cache(inode, start, start + len - 1, 0);
5703 }
5704 5706
5705 trans = btrfs_join_transaction(root); 5707 trans = btrfs_join_transaction(root);
5706 if (IS_ERR(trans)) 5708 if (IS_ERR(trans))
@@ -5716,38 +5718,10 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode,
5716 goto out; 5718 goto out;
5717 } 5719 }
5718 5720
5719 if (!em) { 5721 em = create_pinned_em(inode, start, ins.offset, start, ins.objectid,
5720 em = alloc_extent_map(); 5722 ins.offset, ins.offset, 0);
5721 if (!em) { 5723 if (IS_ERR(em))
5722 em = ERR_PTR(-ENOMEM); 5724 goto out;
5723 goto out;
5724 }
5725 }
5726
5727 em->start = start;
5728 em->orig_start = em->start;
5729 em->len = ins.offset;
5730
5731 em->block_start = ins.objectid;
5732 em->block_len = ins.offset;
5733 em->orig_block_len = ins.offset;
5734 em->bdev = root->fs_info->fs_devices->latest_bdev;
5735
5736 /*
5737 * We need to do this because if we're using the original em we searched
5738 * for, we could have EXTENT_FLAG_VACANCY set, and we don't want that.
5739 */
5740 em->flags = 0;
5741 set_bit(EXTENT_FLAG_PINNED, &em->flags);
5742
5743 while (insert) {
5744 write_lock(&em_tree->lock);
5745 ret = add_extent_mapping(em_tree, em);
5746 write_unlock(&em_tree->lock);
5747 if (ret != -EEXIST)
5748 break;
5749 btrfs_drop_extent_cache(inode, start, start + em->len - 1, 0);
5750 }
5751 5725
5752 ret = btrfs_add_ordered_extent_dio(inode, start, ins.objectid, 5726 ret = btrfs_add_ordered_extent_dio(inode, start, ins.objectid,
5753 ins.offset, ins.offset, 0); 5727 ins.offset, ins.offset, 0);
@@ -5943,6 +5917,7 @@ static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
5943 em->block_start = block_start; 5917 em->block_start = block_start;
5944 em->bdev = root->fs_info->fs_devices->latest_bdev; 5918 em->bdev = root->fs_info->fs_devices->latest_bdev;
5945 em->orig_block_len = orig_block_len; 5919 em->orig_block_len = orig_block_len;
5920 em->generation = -1;
5946 set_bit(EXTENT_FLAG_PINNED, &em->flags); 5921 set_bit(EXTENT_FLAG_PINNED, &em->flags);
5947 if (type == BTRFS_ORDERED_PREALLOC) 5922 if (type == BTRFS_ORDERED_PREALLOC)
5948 set_bit(EXTENT_FLAG_FILLING, &em->flags); 5923 set_bit(EXTENT_FLAG_FILLING, &em->flags);
@@ -5952,6 +5927,9 @@ static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
5952 em->start + em->len - 1, 0); 5927 em->start + em->len - 1, 0);
5953 write_lock(&em_tree->lock); 5928 write_lock(&em_tree->lock);
5954 ret = add_extent_mapping(em_tree, em); 5929 ret = add_extent_mapping(em_tree, em);
5930 if (!ret)
5931 list_move(&em->list,
5932 &em_tree->modified_extents);
5955 write_unlock(&em_tree->lock); 5933 write_unlock(&em_tree->lock);
5956 } while (ret == -EEXIST); 5934 } while (ret == -EEXIST);
5957 5935
@@ -6078,7 +6056,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
6078 goto must_cow; 6056 goto must_cow;
6079 6057
6080 if (can_nocow_odirect(trans, inode, start, len) == 1) { 6058 if (can_nocow_odirect(trans, inode, start, len) == 1) {
6081 u64 orig_start = em->start; 6059 u64 orig_start = em->orig_start;
6082 u64 orig_block_len = em->orig_block_len; 6060 u64 orig_block_len = em->orig_block_len;
6083 6061
6084 if (type == BTRFS_ORDERED_PREALLOC) { 6062 if (type == BTRFS_ORDERED_PREALLOC) {
@@ -6110,7 +6088,8 @@ must_cow:
6110 * it above 6088 * it above
6111 */ 6089 */
6112 len = bh_result->b_size; 6090 len = bh_result->b_size;
6113 em = btrfs_new_extent_direct(inode, em, start, len); 6091 free_extent_map(em);
6092 em = btrfs_new_extent_direct(inode, start, len);
6114 if (IS_ERR(em)) { 6093 if (IS_ERR(em)) {
6115 ret = PTR_ERR(em); 6094 ret = PTR_ERR(em);
6116 goto unlock_err; 6095 goto unlock_err;