aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2017-01-31 10:50:22 -0500
committerDavid Sterba <dsterba@suse.com>2017-02-17 06:03:48 -0500
commit6f9994dbabe5756df1922d84a568cbff74ae1323 (patch)
tree3b5d8e583bb73d757fd5c994ed9461a6ac1c3d8f /fs/btrfs/inode.c
parent4136135b080f5680fb31eda9348d1f636e4dbfb9 (diff)
Btrfs: create a helper to create em for IO
We have similar codes to create and insert extent mapping around IO path, this merges them into a single helper. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c189
1 files changed, 74 insertions, 115 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 175c28a94a57..b37b062789a7 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -109,11 +109,11 @@ static noinline int cow_file_range(struct inode *inode,
109 u64 start, u64 end, u64 delalloc_end, 109 u64 start, u64 end, u64 delalloc_end,
110 int *page_started, unsigned long *nr_written, 110 int *page_started, unsigned long *nr_written,
111 int unlock, struct btrfs_dedupe_hash *hash); 111 int unlock, struct btrfs_dedupe_hash *hash);
112static struct extent_map *create_pinned_em(struct inode *inode, u64 start, 112static struct extent_map *create_io_em(struct inode *inode, u64 start, u64 len,
113 u64 len, u64 orig_start, 113 u64 orig_start, u64 block_start,
114 u64 block_start, u64 block_len, 114 u64 block_len, u64 orig_block_len,
115 u64 orig_block_len, u64 ram_bytes, 115 u64 ram_bytes, int compress_type,
116 int type); 116 int type);
117 117
118static int btrfs_dirty_inode(struct inode *inode); 118static int btrfs_dirty_inode(struct inode *inode);
119 119
@@ -697,7 +697,6 @@ static noinline void submit_compressed_extents(struct inode *inode,
697 struct btrfs_key ins; 697 struct btrfs_key ins;
698 struct extent_map *em; 698 struct extent_map *em;
699 struct btrfs_root *root = BTRFS_I(inode)->root; 699 struct btrfs_root *root = BTRFS_I(inode)->root;
700 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
701 struct extent_io_tree *io_tree; 700 struct extent_io_tree *io_tree;
702 int ret = 0; 701 int ret = 0;
703 702
@@ -785,46 +784,19 @@ retry:
785 * here we're doing allocation and writeback of the 784 * here we're doing allocation and writeback of the
786 * compressed pages 785 * compressed pages
787 */ 786 */
788 btrfs_drop_extent_cache(inode, async_extent->start, 787 em = create_io_em(inode, async_extent->start,
789 async_extent->start + 788 async_extent->ram_size, /* len */
790 async_extent->ram_size - 1, 0); 789 async_extent->start, /* orig_start */
791 790 ins.objectid, /* block_start */
792 em = alloc_extent_map(); 791 ins.offset, /* block_len */
793 if (!em) { 792 ins.offset, /* orig_block_len */
794 ret = -ENOMEM; 793 async_extent->ram_size, /* ram_bytes */
795 goto out_free_reserve; 794 async_extent->compress_type,
796 } 795 BTRFS_ORDERED_COMPRESSED);
797 em->start = async_extent->start; 796 if (IS_ERR(em))
798 em->len = async_extent->ram_size; 797 /* ret value is not necessary due to void function */
799 em->orig_start = em->start;
800 em->mod_start = em->start;
801 em->mod_len = em->len;
802
803 em->block_start = ins.objectid;
804 em->block_len = ins.offset;
805 em->orig_block_len = ins.offset;
806 em->ram_bytes = async_extent->ram_size;
807 em->bdev = fs_info->fs_devices->latest_bdev;
808 em->compress_type = async_extent->compress_type;
809 set_bit(EXTENT_FLAG_PINNED, &em->flags);
810 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
811 em->generation = -1;
812
813 while (1) {
814 write_lock(&em_tree->lock);
815 ret = add_extent_mapping(em_tree, em, 1);
816 write_unlock(&em_tree->lock);
817 if (ret != -EEXIST) {
818 free_extent_map(em);
819 break;
820 }
821 btrfs_drop_extent_cache(inode, async_extent->start,
822 async_extent->start +
823 async_extent->ram_size - 1, 0);
824 }
825
826 if (ret)
827 goto out_free_reserve; 798 goto out_free_reserve;
799 free_extent_map(em);
828 800
829 ret = btrfs_add_ordered_extent_compress(inode, 801 ret = btrfs_add_ordered_extent_compress(inode,
830 async_extent->start, 802 async_extent->start,
@@ -959,7 +931,6 @@ static noinline int cow_file_range(struct inode *inode,
959 u64 blocksize = fs_info->sectorsize; 931 u64 blocksize = fs_info->sectorsize;
960 struct btrfs_key ins; 932 struct btrfs_key ins;
961 struct extent_map *em; 933 struct extent_map *em;
962 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
963 int ret = 0; 934 int ret = 0;
964 935
965 if (btrfs_is_free_space_inode(inode)) { 936 if (btrfs_is_free_space_inode(inode)) {
@@ -1012,39 +983,18 @@ static noinline int cow_file_range(struct inode *inode,
1012 if (ret < 0) 983 if (ret < 0)
1013 goto out_unlock; 984 goto out_unlock;
1014 985
1015 em = alloc_extent_map();
1016 if (!em) {
1017 ret = -ENOMEM;
1018 goto out_reserve;
1019 }
1020 em->start = start;
1021 em->orig_start = em->start;
1022 ram_size = ins.offset; 986 ram_size = ins.offset;
1023 em->len = ins.offset; 987 em = create_io_em(inode, start, ins.offset, /* len */
1024 em->mod_start = em->start; 988 start, /* orig_start */
1025 em->mod_len = em->len; 989 ins.objectid, /* block_start */
1026 990 ins.offset, /* block_len */
1027 em->block_start = ins.objectid; 991 ins.offset, /* orig_block_len */
1028 em->block_len = ins.offset; 992 ram_size, /* ram_bytes */
1029 em->orig_block_len = ins.offset; 993 BTRFS_COMPRESS_NONE, /* compress_type */
1030 em->ram_bytes = ram_size; 994 0 /* type */);
1031 em->bdev = fs_info->fs_devices->latest_bdev; 995 if (IS_ERR(em))
1032 set_bit(EXTENT_FLAG_PINNED, &em->flags);
1033 em->generation = -1;
1034
1035 while (1) {
1036 write_lock(&em_tree->lock);
1037 ret = add_extent_mapping(em_tree, em, 1);
1038 write_unlock(&em_tree->lock);
1039 if (ret != -EEXIST) {
1040 free_extent_map(em);
1041 break;
1042 }
1043 btrfs_drop_extent_cache(inode, start,
1044 start + ram_size - 1, 0);
1045 }
1046 if (ret)
1047 goto out_reserve; 996 goto out_reserve;
997 free_extent_map(em);
1048 998
1049 cur_alloc_size = ins.offset; 999 cur_alloc_size = ins.offset;
1050 ret = btrfs_add_ordered_extent(inode, start, ins.objectid, 1000 ret = btrfs_add_ordered_extent(inode, start, ins.objectid,
@@ -1251,6 +1201,7 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1251 struct btrfs_path *path; 1201 struct btrfs_path *path;
1252 struct btrfs_file_extent_item *fi; 1202 struct btrfs_file_extent_item *fi;
1253 struct btrfs_key found_key; 1203 struct btrfs_key found_key;
1204 struct extent_map *em;
1254 u64 cow_start; 1205 u64 cow_start;
1255 u64 cur_offset; 1206 u64 cur_offset;
1256 u64 extent_end; 1207 u64 extent_end;
@@ -1431,35 +1382,28 @@ out_check:
1431 } 1382 }
1432 1383
1433 if (extent_type == BTRFS_FILE_EXTENT_PREALLOC) { 1384 if (extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
1434 struct extent_map *em; 1385 u64 orig_start = found_key.offset - extent_offset;
1435 struct extent_map_tree *em_tree; 1386
1436 em_tree = &BTRFS_I(inode)->extent_tree; 1387 em = create_io_em(inode, cur_offset, num_bytes,
1437 em = alloc_extent_map(); 1388 orig_start,
1438 BUG_ON(!em); /* -ENOMEM */ 1389 disk_bytenr, /* block_start */
1439 em->start = cur_offset; 1390 num_bytes, /* block_len */
1440 em->orig_start = found_key.offset - extent_offset; 1391 disk_num_bytes, /* orig_block_len */
1441 em->len = num_bytes; 1392 ram_bytes, BTRFS_COMPRESS_NONE,
1442 em->block_len = num_bytes; 1393 BTRFS_ORDERED_PREALLOC);
1443 em->block_start = disk_bytenr; 1394 if (IS_ERR(em)) {
1444 em->orig_block_len = disk_num_bytes; 1395 if (!nolock && nocow)
1445 em->ram_bytes = ram_bytes; 1396 btrfs_end_write_no_snapshoting(root);
1446 em->bdev = fs_info->fs_devices->latest_bdev; 1397 if (nocow)
1447 em->mod_start = em->start; 1398 btrfs_dec_nocow_writers(fs_info,
1448 em->mod_len = em->len; 1399 disk_bytenr);
1449 set_bit(EXTENT_FLAG_PINNED, &em->flags); 1400 ret = PTR_ERR(em);
1450 set_bit(EXTENT_FLAG_FILLING, &em->flags); 1401 goto error;
1451 em->generation = -1;
1452 while (1) {
1453 write_lock(&em_tree->lock);
1454 ret = add_extent_mapping(em_tree, em, 1);
1455 write_unlock(&em_tree->lock);
1456 if (ret != -EEXIST) {
1457 free_extent_map(em);
1458 break;
1459 }
1460 btrfs_drop_extent_cache(inode, em->start,
1461 em->start + em->len - 1, 0);
1462 } 1402 }
1403 free_extent_map(em);
1404 }
1405
1406 if (extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
1463 type = BTRFS_ORDERED_PREALLOC; 1407 type = BTRFS_ORDERED_PREALLOC;
1464 } else { 1408 } else {
1465 type = BTRFS_ORDERED_NOCOW; 1409 type = BTRFS_ORDERED_NOCOW;
@@ -7207,9 +7151,11 @@ static struct extent_map *btrfs_create_dio_extent(struct inode *inode,
7207 int ret; 7151 int ret;
7208 7152
7209 if (type != BTRFS_ORDERED_NOCOW) { 7153 if (type != BTRFS_ORDERED_NOCOW) {
7210 em = create_pinned_em(inode, start, len, orig_start, 7154 em = create_io_em(inode, start, len, orig_start,
7211 block_start, block_len, orig_block_len, 7155 block_start, block_len, orig_block_len,
7212 ram_bytes, type); 7156 ram_bytes,
7157 BTRFS_COMPRESS_NONE, /* compress_type */
7158 type);
7213 if (IS_ERR(em)) 7159 if (IS_ERR(em))
7214 goto out; 7160 goto out;
7215 } 7161 }
@@ -7545,17 +7491,23 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
7545 return ret; 7491 return ret;
7546} 7492}
7547 7493
7548static struct extent_map *create_pinned_em(struct inode *inode, u64 start, 7494/* The callers of this must take lock_extent() */
7549 u64 len, u64 orig_start, 7495static struct extent_map *create_io_em(struct inode *inode, u64 start, u64 len,
7550 u64 block_start, u64 block_len, 7496 u64 orig_start, u64 block_start,
7551 u64 orig_block_len, u64 ram_bytes, 7497 u64 block_len, u64 orig_block_len,
7552 int type) 7498 u64 ram_bytes, int compress_type,
7499 int type)
7553{ 7500{
7554 struct extent_map_tree *em_tree; 7501 struct extent_map_tree *em_tree;
7555 struct extent_map *em; 7502 struct extent_map *em;
7556 struct btrfs_root *root = BTRFS_I(inode)->root; 7503 struct btrfs_root *root = BTRFS_I(inode)->root;
7557 int ret; 7504 int ret;
7558 7505
7506 ASSERT(type == BTRFS_ORDERED_PREALLOC ||
7507 type == BTRFS_ORDERED_COMPRESSED ||
7508 type == BTRFS_ORDERED_NOCOW ||
7509 type == 0);
7510
7559 em_tree = &BTRFS_I(inode)->extent_tree; 7511 em_tree = &BTRFS_I(inode)->extent_tree;
7560 em = alloc_extent_map(); 7512 em = alloc_extent_map();
7561 if (!em) 7513 if (!em)
@@ -7563,8 +7515,6 @@ static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
7563 7515
7564 em->start = start; 7516 em->start = start;
7565 em->orig_start = orig_start; 7517 em->orig_start = orig_start;
7566 em->mod_start = start;
7567 em->mod_len = len;
7568 em->len = len; 7518 em->len = len;
7569 em->block_len = block_len; 7519 em->block_len = block_len;
7570 em->block_start = block_start; 7520 em->block_start = block_start;
@@ -7575,6 +7525,10 @@ static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
7575 set_bit(EXTENT_FLAG_PINNED, &em->flags); 7525 set_bit(EXTENT_FLAG_PINNED, &em->flags);
7576 if (type == BTRFS_ORDERED_PREALLOC) 7526 if (type == BTRFS_ORDERED_PREALLOC)
7577 set_bit(EXTENT_FLAG_FILLING, &em->flags); 7527 set_bit(EXTENT_FLAG_FILLING, &em->flags);
7528 else if (type == BTRFS_ORDERED_COMPRESSED) {
7529 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
7530 em->compress_type = compress_type;
7531 }
7578 7532
7579 do { 7533 do {
7580 btrfs_drop_extent_cache(inode, em->start, 7534 btrfs_drop_extent_cache(inode, em->start,
@@ -7582,6 +7536,10 @@ static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
7582 write_lock(&em_tree->lock); 7536 write_lock(&em_tree->lock);
7583 ret = add_extent_mapping(em_tree, em, 1); 7537 ret = add_extent_mapping(em_tree, em, 1);
7584 write_unlock(&em_tree->lock); 7538 write_unlock(&em_tree->lock);
7539 /*
7540 * The caller has taken lock_extent(), who could race with us
7541 * to add em?
7542 */
7585 } while (ret == -EEXIST); 7543 } while (ret == -EEXIST);
7586 7544
7587 if (ret) { 7545 if (ret) {
@@ -7589,6 +7547,7 @@ static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
7589 return ERR_PTR(ret); 7547 return ERR_PTR(ret);
7590 } 7548 }
7591 7549
7550 /* em got 2 refs now, callers needs to do free_extent_map once. */
7592 return em; 7551 return em;
7593} 7552}
7594 7553