aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
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;