aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-10-30 14:25:28 -0400
committerChris Mason <chris.mason@oracle.com>2008-10-30 14:25:28 -0400
commitd899e05215178fed903ad0e7fc1cb4d8e0cc0a88 (patch)
tree2969e3558f5c50ec0f9ac4201099c0d5d1d6e2c2 /fs/btrfs/extent-tree.c
parent80ff385665b7fca29fefe358a60ab0d09f9b8e87 (diff)
Btrfs: Add fallocate support v2
This patch updates btrfs-progs for fallocate support. fallocate is a little different in Btrfs because we need to tell the COW system that a given preallocated extent doesn't need to be cow'd as long as there are no snapshots of it. This leverages the -o nodatacow checks. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c65
1 files changed, 36 insertions, 29 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 1eb69a91b727..8af39521eb71 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2147,6 +2147,9 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
2147 total_needed += empty_size; 2147 total_needed += empty_size;
2148 2148
2149 block_group = btrfs_lookup_block_group(root->fs_info, search_start); 2149 block_group = btrfs_lookup_block_group(root->fs_info, search_start);
2150 if (!block_group)
2151 block_group = btrfs_lookup_first_block_group(root->fs_info,
2152 search_start);
2150 space_info = __find_space_info(root->fs_info, data); 2153 space_info = __find_space_info(root->fs_info, data);
2151 2154
2152 down_read(&space_info->groups_sem); 2155 down_read(&space_info->groups_sem);
@@ -3426,9 +3429,7 @@ walk_down:
3426next: 3429next:
3427 level--; 3430 level--;
3428 btrfs_release_path(extent_root, path); 3431 btrfs_release_path(extent_root, path);
3429 if (need_resched()) { 3432 cond_resched();
3430 cond_resched();
3431 }
3432 } 3433 }
3433 /* reached lowest level */ 3434 /* reached lowest level */
3434 ret = 1; 3435 ret = 1;
@@ -3539,9 +3540,7 @@ found:
3539 } 3540 }
3540 3541
3541 btrfs_release_path(extent_root, path); 3542 btrfs_release_path(extent_root, path);
3542 if (need_resched()) { 3543 cond_resched();
3543 cond_resched();
3544 }
3545 } 3544 }
3546 /* reached max tree level, but no tree root found. */ 3545 /* reached max tree level, but no tree root found. */
3547 BUG(); 3546 BUG();
@@ -3654,8 +3653,9 @@ static int noinline get_new_locations(struct inode *reloc_inode,
3654 exts[nr].encryption = btrfs_file_extent_encryption(leaf, fi); 3653 exts[nr].encryption = btrfs_file_extent_encryption(leaf, fi);
3655 exts[nr].other_encoding = btrfs_file_extent_other_encoding(leaf, 3654 exts[nr].other_encoding = btrfs_file_extent_other_encoding(leaf,
3656 fi); 3655 fi);
3657 WARN_ON(exts[nr].offset > 0); 3656 BUG_ON(exts[nr].offset > 0);
3658 WARN_ON(exts[nr].num_bytes != exts[nr].disk_num_bytes); 3657 BUG_ON(exts[nr].compression || exts[nr].encryption);
3658 BUG_ON(exts[nr].num_bytes != exts[nr].disk_num_bytes);
3659 3659
3660 cur_pos += exts[nr].num_bytes; 3660 cur_pos += exts[nr].num_bytes;
3661 nr++; 3661 nr++;
@@ -3709,6 +3709,7 @@ static int noinline replace_one_extent(struct btrfs_trans_handle *trans,
3709 u32 nritems; 3709 u32 nritems;
3710 int nr_scaned = 0; 3710 int nr_scaned = 0;
3711 int extent_locked = 0; 3711 int extent_locked = 0;
3712 int extent_type;
3712 int ret; 3713 int ret;
3713 3714
3714 memcpy(&key, leaf_key, sizeof(key)); 3715 memcpy(&key, leaf_key, sizeof(key));
@@ -3781,8 +3782,9 @@ next:
3781 } 3782 }
3782 fi = btrfs_item_ptr(leaf, path->slots[0], 3783 fi = btrfs_item_ptr(leaf, path->slots[0],
3783 struct btrfs_file_extent_item); 3784 struct btrfs_file_extent_item);
3784 if ((btrfs_file_extent_type(leaf, fi) != 3785 extent_type = btrfs_file_extent_type(leaf, fi);
3785 BTRFS_FILE_EXTENT_REG) || 3786 if ((extent_type != BTRFS_FILE_EXTENT_REG &&
3787 extent_type != BTRFS_FILE_EXTENT_PREALLOC) ||
3786 (btrfs_file_extent_disk_bytenr(leaf, fi) != 3788 (btrfs_file_extent_disk_bytenr(leaf, fi) !=
3787 extent_key->objectid)) { 3789 extent_key->objectid)) {
3788 path->slots[0]++; 3790 path->slots[0]++;
@@ -3865,16 +3867,10 @@ next:
3865 3867
3866 if (nr_extents == 1) { 3868 if (nr_extents == 1) {
3867 /* update extent pointer in place */ 3869 /* update extent pointer in place */
3868 btrfs_set_file_extent_generation(leaf, fi,
3869 trans->transid);
3870 btrfs_set_file_extent_disk_bytenr(leaf, fi, 3870 btrfs_set_file_extent_disk_bytenr(leaf, fi,
3871 new_extents[0].disk_bytenr); 3871 new_extents[0].disk_bytenr);
3872 btrfs_set_file_extent_disk_num_bytes(leaf, fi, 3872 btrfs_set_file_extent_disk_num_bytes(leaf, fi,
3873 new_extents[0].disk_num_bytes); 3873 new_extents[0].disk_num_bytes);
3874 btrfs_set_file_extent_ram_bytes(leaf, fi,
3875 new_extents[0].ram_bytes);
3876 ext_offset += new_extents[0].offset;
3877 btrfs_set_file_extent_offset(leaf, fi, ext_offset);
3878 btrfs_mark_buffer_dirty(leaf); 3874 btrfs_mark_buffer_dirty(leaf);
3879 3875
3880 btrfs_drop_extent_cache(inode, key.offset, 3876 btrfs_drop_extent_cache(inode, key.offset,
@@ -3901,6 +3897,8 @@ next:
3901 btrfs_release_path(root, path); 3897 btrfs_release_path(root, path);
3902 key.offset += num_bytes; 3898 key.offset += num_bytes;
3903 } else { 3899 } else {
3900 BUG_ON(1);
3901#if 0
3904 u64 alloc_hint; 3902 u64 alloc_hint;
3905 u64 extent_len; 3903 u64 extent_len;
3906 int i; 3904 int i;
@@ -3977,6 +3975,7 @@ next:
3977 break; 3975 break;
3978 } 3976 }
3979 BUG_ON(i >= nr_extents); 3977 BUG_ON(i >= nr_extents);
3978#endif
3980 } 3979 }
3981 3980
3982 if (extent_locked) { 3981 if (extent_locked) {
@@ -4156,15 +4155,10 @@ static int noinline replace_extents_in_leaf(struct btrfs_trans_handle *trans,
4156 ref->extents[ext_index].bytenr = new_extent->disk_bytenr; 4155 ref->extents[ext_index].bytenr = new_extent->disk_bytenr;
4157 ref->extents[ext_index].num_bytes = new_extent->disk_num_bytes; 4156 ref->extents[ext_index].num_bytes = new_extent->disk_num_bytes;
4158 4157
4159 btrfs_set_file_extent_generation(leaf, fi, trans->transid);
4160 btrfs_set_file_extent_ram_bytes(leaf, fi,
4161 new_extent->ram_bytes);
4162 btrfs_set_file_extent_disk_bytenr(leaf, fi, 4158 btrfs_set_file_extent_disk_bytenr(leaf, fi,
4163 new_extent->disk_bytenr); 4159 new_extent->disk_bytenr);
4164 btrfs_set_file_extent_disk_num_bytes(leaf, fi, 4160 btrfs_set_file_extent_disk_num_bytes(leaf, fi,
4165 new_extent->disk_num_bytes); 4161 new_extent->disk_num_bytes);
4166 new_extent->offset += btrfs_file_extent_offset(leaf, fi);
4167 btrfs_set_file_extent_offset(leaf, fi, new_extent->offset);
4168 btrfs_mark_buffer_dirty(leaf); 4162 btrfs_mark_buffer_dirty(leaf);
4169 4163
4170 ret = btrfs_inc_extent_ref(trans, root, 4164 ret = btrfs_inc_extent_ref(trans, root,
@@ -4625,12 +4619,15 @@ static int noinline relocate_one_extent(struct btrfs_root *extent_root,
4625 */ 4619 */
4626 if (!new_extents) { 4620 if (!new_extents) {
4627 u64 group_start = group->key.objectid; 4621 u64 group_start = group->key.objectid;
4622 new_extents = kmalloc(sizeof(*new_extents),
4623 GFP_NOFS);
4624 nr_extents = 1;
4628 ret = get_new_locations(reloc_inode, 4625 ret = get_new_locations(reloc_inode,
4629 extent_key, 4626 extent_key,
4630 group_start, 0, 4627 group_start, 1,
4631 &new_extents, 4628 &new_extents,
4632 &nr_extents); 4629 &nr_extents);
4633 if (ret < 0) 4630 if (ret)
4634 goto out; 4631 goto out;
4635 } 4632 }
4636 btrfs_record_root_in_trans(found_root); 4633 btrfs_record_root_in_trans(found_root);
@@ -4762,7 +4759,8 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans,
4762 btrfs_set_inode_generation(leaf, item, 1); 4759 btrfs_set_inode_generation(leaf, item, 1);
4763 btrfs_set_inode_size(leaf, item, size); 4760 btrfs_set_inode_size(leaf, item, size);
4764 btrfs_set_inode_mode(leaf, item, S_IFREG | 0600); 4761 btrfs_set_inode_mode(leaf, item, S_IFREG | 0600);
4765 btrfs_set_inode_flags(leaf, item, BTRFS_INODE_NODATASUM); 4762 btrfs_set_inode_flags(leaf, item, BTRFS_INODE_NODATASUM |
4763 BTRFS_INODE_NOCOMPRESS);
4766 btrfs_mark_buffer_dirty(leaf); 4764 btrfs_mark_buffer_dirty(leaf);
4767 btrfs_release_path(root, path); 4765 btrfs_release_path(root, path);
4768out: 4766out:
@@ -4835,6 +4833,7 @@ int btrfs_relocate_block_group(struct btrfs_root *root, u64 group_start)
4835 struct inode *reloc_inode; 4833 struct inode *reloc_inode;
4836 struct btrfs_block_group_cache *block_group; 4834 struct btrfs_block_group_cache *block_group;
4837 struct btrfs_key key; 4835 struct btrfs_key key;
4836 u64 skipped;
4838 u64 cur_byte; 4837 u64 cur_byte;
4839 u64 total_found; 4838 u64 total_found;
4840 u32 nritems; 4839 u32 nritems;
@@ -4864,6 +4863,7 @@ int btrfs_relocate_block_group(struct btrfs_root *root, u64 group_start)
4864 btrfs_start_delalloc_inodes(info->tree_root); 4863 btrfs_start_delalloc_inodes(info->tree_root);
4865 btrfs_wait_ordered_extents(info->tree_root, 0); 4864 btrfs_wait_ordered_extents(info->tree_root, 0);
4866again: 4865again:
4866 skipped = 0;
4867 total_found = 0; 4867 total_found = 0;
4868 progress = 0; 4868 progress = 0;
4869 key.objectid = block_group->key.objectid; 4869 key.objectid = block_group->key.objectid;
@@ -4926,6 +4926,8 @@ next:
4926 ret = relocate_one_extent(root, path, &key, block_group, 4926 ret = relocate_one_extent(root, path, &key, block_group,
4927 reloc_inode, pass); 4927 reloc_inode, pass);
4928 BUG_ON(ret < 0); 4928 BUG_ON(ret < 0);
4929 if (ret > 0)
4930 skipped++;
4929 4931
4930 key.objectid = cur_byte; 4932 key.objectid = cur_byte;
4931 key.type = 0; 4933 key.type = 0;
@@ -4944,6 +4946,11 @@ next:
4944 printk("btrfs found %llu extents in pass %d\n", 4946 printk("btrfs found %llu extents in pass %d\n",
4945 (unsigned long long)total_found, pass); 4947 (unsigned long long)total_found, pass);
4946 pass++; 4948 pass++;
4949 if (total_found == skipped && pass > 2) {
4950 iput(reloc_inode);
4951 reloc_inode = create_reloc_inode(info, block_group);
4952 pass = 0;
4953 }
4947 goto again; 4954 goto again;
4948 } 4955 }
4949 4956
@@ -5011,17 +5018,17 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
5011 while ((n = rb_last(&info->block_group_cache_tree)) != NULL) { 5018 while ((n = rb_last(&info->block_group_cache_tree)) != NULL) {
5012 block_group = rb_entry(n, struct btrfs_block_group_cache, 5019 block_group = rb_entry(n, struct btrfs_block_group_cache,
5013 cache_node); 5020 cache_node);
5014
5015 spin_unlock(&info->block_group_cache_lock);
5016 btrfs_remove_free_space_cache(block_group);
5017 spin_lock(&info->block_group_cache_lock);
5018
5019 rb_erase(&block_group->cache_node, 5021 rb_erase(&block_group->cache_node,
5020 &info->block_group_cache_tree); 5022 &info->block_group_cache_tree);
5023 spin_unlock(&info->block_group_cache_lock);
5024
5025 btrfs_remove_free_space_cache(block_group);
5021 down_write(&block_group->space_info->groups_sem); 5026 down_write(&block_group->space_info->groups_sem);
5022 list_del(&block_group->list); 5027 list_del(&block_group->list);
5023 up_write(&block_group->space_info->groups_sem); 5028 up_write(&block_group->space_info->groups_sem);
5024 kfree(block_group); 5029 kfree(block_group);
5030
5031 spin_lock(&info->block_group_cache_lock);
5025 } 5032 }
5026 spin_unlock(&info->block_group_cache_lock); 5033 spin_unlock(&info->block_group_cache_lock);
5027 return 0; 5034 return 0;