diff options
Diffstat (limited to 'fs/btrfs/relocation.c')
| -rw-r--r-- | fs/btrfs/relocation.c | 81 | 
1 files changed, 28 insertions, 53 deletions
| diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 914d403b4415..33a0ee7ac590 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -25,6 +25,7 @@  #include "backref.h"  #include "misc.h"  #include "subpage.h" +#include "zoned.h"  /*   * Relocation overview @@ -1145,9 +1146,9 @@ int replace_file_extents(struct btrfs_trans_handle *trans,  		key.offset -= btrfs_file_extent_offset(leaf, fi);  		btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new_bytenr,  				       num_bytes, parent); -		ref.real_root = root->root_key.objectid;  		btrfs_init_data_ref(&ref, btrfs_header_owner(leaf), -				    key.objectid, key.offset); +				    key.objectid, key.offset, +				    root->root_key.objectid, false);  		ret = btrfs_inc_extent_ref(trans, &ref);  		if (ret) {  			btrfs_abort_transaction(trans, ret); @@ -1156,9 +1157,9 @@ int replace_file_extents(struct btrfs_trans_handle *trans,  		btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, bytenr,  				       num_bytes, parent); -		ref.real_root = root->root_key.objectid;  		btrfs_init_data_ref(&ref, btrfs_header_owner(leaf), -				    key.objectid, key.offset); +				    key.objectid, key.offset, +				    root->root_key.objectid, false);  		ret = btrfs_free_extent(trans, &ref);  		if (ret) {  			btrfs_abort_transaction(trans, ret); @@ -1367,8 +1368,8 @@ again:  		btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, old_bytenr,  				       blocksize, path->nodes[level]->start); -		ref.skip_qgroup = true; -		btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid); +		btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid, +				    0, true);  		ret = btrfs_inc_extent_ref(trans, &ref);  		if (ret) {  			btrfs_abort_transaction(trans, ret); @@ -1376,8 +1377,8 @@ again:  		}  		btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new_bytenr,  				       blocksize, 0); -		ref.skip_qgroup = true; -		btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid); +		btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid, 0, +				    true);  		ret = btrfs_inc_extent_ref(trans, &ref);  		if (ret) {  			btrfs_abort_transaction(trans, ret); @@ -1386,8 +1387,8 @@ again:  		btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, new_bytenr,  				       blocksize, path->nodes[level]->start); -		btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid); -		ref.skip_qgroup = true; +		btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid, +				    0, true);  		ret = btrfs_free_extent(trans, &ref);  		if (ret) {  			btrfs_abort_transaction(trans, ret); @@ -1396,8 +1397,8 @@ again:  		btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, old_bytenr,  				       blocksize, 0); -		btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid); -		ref.skip_qgroup = true; +		btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid, +				    0, true);  		ret = btrfs_free_extent(trans, &ref);  		if (ret) {  			btrfs_abort_transaction(trans, ret); @@ -2473,9 +2474,9 @@ static int do_relocation(struct btrfs_trans_handle *trans,  			btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF,  					       node->eb->start, blocksize,  					       upper->eb->start); -			ref.real_root = root->root_key.objectid;  			btrfs_init_tree_ref(&ref, node->level, -					    btrfs_header_owner(upper->eb)); +					    btrfs_header_owner(upper->eb), +					    root->root_key.objectid, false);  			ret = btrfs_inc_extent_ref(trans, &ref);  			if (!ret)  				ret = btrfs_drop_subtree(trans, root, eb, @@ -2691,8 +2692,12 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,  			list_add_tail(&node->list, &rc->backref_cache.changed);  		} else {  			path->lowest_level = node->level; +			if (root == root->fs_info->chunk_root) +				btrfs_reserve_chunk_metadata(trans, false);  			ret = btrfs_search_slot(trans, root, key, path, 0, 1);  			btrfs_release_path(path); +			if (root == root->fs_info->chunk_root) +				btrfs_trans_release_chunk_metadata(trans);  			if (ret > 0)  				ret = 0;  		} @@ -2852,31 +2857,6 @@ static noinline_for_stack int prealloc_file_extent_cluster(  	if (ret)  		return ret; -	/* -	 * On a zoned filesystem, we cannot preallocate the file region. -	 * Instead, we dirty and fiemap_write the region. -	 */ -	if (btrfs_is_zoned(inode->root->fs_info)) { -		struct btrfs_root *root = inode->root; -		struct btrfs_trans_handle *trans; - -		end = cluster->end - offset + 1; -		trans = btrfs_start_transaction(root, 1); -		if (IS_ERR(trans)) -			return PTR_ERR(trans); - -		inode->vfs_inode.i_ctime = current_time(&inode->vfs_inode); -		i_size_write(&inode->vfs_inode, end); -		ret = btrfs_update_inode(trans, root, inode); -		if (ret) { -			btrfs_abort_transaction(trans, ret); -			btrfs_end_transaction(trans); -			return ret; -		} - -		return btrfs_end_transaction(trans); -	} -  	btrfs_inode_lock(&inode->vfs_inode, 0);  	for (nr = 0; nr < cluster->nr; nr++) {  		start = cluster->boundary[nr] - offset; @@ -2903,9 +2883,8 @@ static noinline_for_stack int prealloc_file_extent_cluster(  	return ret;  } -static noinline_for_stack -int setup_extent_mapping(struct inode *inode, u64 start, u64 end, -			 u64 block_start) +static noinline_for_stack int setup_relocation_extent_mapping(struct inode *inode, +				u64 start, u64 end, u64 block_start)  {  	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;  	struct extent_map *em; @@ -3084,7 +3063,6 @@ release_page:  static int relocate_file_extent_cluster(struct inode *inode,  					struct file_extent_cluster *cluster)  { -	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);  	u64 offset = BTRFS_I(inode)->index_cnt;  	unsigned long index;  	unsigned long last_index; @@ -3105,7 +3083,7 @@ static int relocate_file_extent_cluster(struct inode *inode,  	file_ra_state_init(ra, inode->i_mapping); -	ret = setup_extent_mapping(inode, cluster->start - offset, +	ret = setup_relocation_extent_mapping(inode, cluster->start - offset,  				   cluster->end - offset, cluster->start);  	if (ret)  		goto out; @@ -3114,8 +3092,6 @@ static int relocate_file_extent_cluster(struct inode *inode,  	for (index = (cluster->start - offset) >> PAGE_SHIFT;  	     index <= last_index && !ret; index++)  		ret = relocate_one_page(inode, ra, cluster, &cluster_nr, index); -	if (btrfs_is_zoned(fs_info) && !ret) -		ret = btrfs_wait_ordered_range(inode, 0, (u64)-1);  	if (ret == 0)  		WARN_ON(cluster_nr != cluster->nr);  out: @@ -3770,12 +3746,8 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans,  	struct btrfs_path *path;  	struct btrfs_inode_item *item;  	struct extent_buffer *leaf; -	u64 flags = BTRFS_INODE_NOCOMPRESS | BTRFS_INODE_PREALLOC;  	int ret; -	if (btrfs_is_zoned(trans->fs_info)) -		flags &= ~BTRFS_INODE_PREALLOC; -  	path = btrfs_alloc_path();  	if (!path)  		return -ENOMEM; @@ -3790,7 +3762,8 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans,  	btrfs_set_inode_generation(leaf, item, 1);  	btrfs_set_inode_size(leaf, item, 0);  	btrfs_set_inode_mode(leaf, item, S_IFREG | 0600); -	btrfs_set_inode_flags(leaf, item, flags); +	btrfs_set_inode_flags(leaf, item, BTRFS_INODE_NOCOMPRESS | +					  BTRFS_INODE_PREALLOC);  	btrfs_mark_buffer_dirty(leaf);  out:  	btrfs_free_path(path); @@ -4063,6 +4036,9 @@ int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start)  				 rc->block_group->start,  				 rc->block_group->length); +	ret = btrfs_zone_finish(rc->block_group); +	WARN_ON(ret && ret != -EAGAIN); +  	while (1) {  		int finishes_stage; @@ -4386,8 +4362,7 @@ int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,  	if (!rc)  		return 0; -	BUG_ON(rc->stage == UPDATE_DATA_PTRS && -	       root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID); +	BUG_ON(rc->stage == UPDATE_DATA_PTRS && btrfs_is_data_reloc_root(root));  	level = btrfs_header_level(buf);  	if (btrfs_header_generation(buf) <= |