Re: [PATCH] btrfs: qgroup: Skip delayed data ref for reloc trees

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 20.11.18 г. 10:46 ч., Qu Wenruo wrote:
> Currently we only check @ref_root in btrfs_add_delayed_data_ref() to
> determine whether a data delayed ref is for reloc tree.
> 
> Such check is insufficient as for relocation we could pass @ref_root
> as the source file tree, causing qgroup to trace unchanged data extents
> even we're only relocating metadata chunks.
> 
> We could insert qgroup extent record for the following call trace even
> we're only relocating metadata block group:
> 
> do_relocation()
> |- btrfs_cow_block(root=reloc_root)
>    |- update_ref_for_cow(root=reloc_root)
>       |- __btrfs_mod_ref(root=reloc_root)
>          |- ref_root = btrfs_header_owner()
>          |- btrfs_add_delayed_data_ref(ref_root=source_root)
> 
> And another case when dropping reloc tree:
> 
> clean_dirty_root()
> |- btrfs_drop_snapshot(root=relocc_root)
>    |- walk_up_tree(root=reloc_root)
>       |- walk_up_proc(root=reloc_root)
>          |- btrfs_dec_ref(root=reloc_root)
>             |- __btrfs_mod_ref(root=reloc_root)
>                |- ref_root = btrfs_header_owner()
>                |- btrfs_add_delayed_data_ref(ref_root=source_root)
> 
> This patch will introduce @root parameter for
> btrfs_add_delayed_data_ref(), so that we could determine if this data
> extent belongs to reloc tree or not.
> 
> This could skip data extents which aren't really modified during
> relocation.
> 
> For the same real world 4G data 16 snapshots 4K nodesize metadata
> balance test:
>                      | v4.20-rc1 + delaye*  | w/ patch       | diff
> -----------------------------------------------------------------------
> relocated extents    | 22773                | 22656          | -0.1%
> qgroup dirty extents | 122879               | 74316          | -39.5%
> time (real)          | 23.073s              | 14.971         | -35.1%
> 
> *: v4.20-rc1 + delayed subtree scan patchset
> 
> Signed-off-by: Qu Wenruo <wqu@xxxxxxxx>
> ---
>  fs/btrfs/delayed-ref.c | 3 ++-
>  fs/btrfs/delayed-ref.h | 1 +
>  fs/btrfs/extent-tree.c | 6 +++---
>  3 files changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
> index 9301b3ad9217..269bd6ecb8f3 100644
> --- a/fs/btrfs/delayed-ref.c
> +++ b/fs/btrfs/delayed-ref.c
> @@ -798,6 +798,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
>   * add a delayed data ref. it's similar to btrfs_add_delayed_tree_ref.
>   */
>  int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans,
> +			       struct btrfs_root *root,

I'm beginning to wonder, should we document
btrfs_add_delayed_data_ref/btrfs_add_tree_ref arguments separate for
each function, or should only the differences be documented - in this
case the newly added root parameter. The rest of the arguments are being
documented at init_delayed_ref_common.

>  			       u64 bytenr, u64 num_bytes,
>  			       u64 parent, u64 ref_root,
>  			       u64 owner, u64 offset, u64 reserved, int action,
> @@ -835,7 +836,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans,
>  	}
>  
>  	if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) &&
> -	    is_fstree(ref_root)) {
> +	    is_fstree(ref_root) && is_fstree(root->root_key.objectid)) {
>  		record = kmalloc(sizeof(*record), GFP_NOFS);
>  		if (!record) {
>  			kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
> diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
> index 8e20c5cb5404..6c60737e55d6 100644
> --- a/fs/btrfs/delayed-ref.h
> +++ b/fs/btrfs/delayed-ref.h
> @@ -240,6 +240,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
>  			       struct btrfs_delayed_extent_op *extent_op,
>  			       int *old_ref_mod, int *new_ref_mod);
>  int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans,
> +			       struct btrfs_root *root,
>  			       u64 bytenr, u64 num_bytes,
>  			       u64 parent, u64 ref_root,
>  			       u64 owner, u64 offset, u64 reserved, int action,
> diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
> index a1febf155747..0554d2cc2ea1 100644
> --- a/fs/btrfs/extent-tree.c
> +++ b/fs/btrfs/extent-tree.c
> @@ -2046,7 +2046,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
>  						 BTRFS_ADD_DELAYED_REF, NULL,
>  						 &old_ref_mod, &new_ref_mod);
>  	} else {
> -		ret = btrfs_add_delayed_data_ref(trans, bytenr,
> +		ret = btrfs_add_delayed_data_ref(trans, root, bytenr,
>  						 num_bytes, parent,
>  						 root_objectid, owner, offset,
>  						 0, BTRFS_ADD_DELAYED_REF,
> @@ -7104,7 +7104,7 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
>  						 BTRFS_DROP_DELAYED_REF, NULL,
>  						 &old_ref_mod, &new_ref_mod);
>  	} else {
> -		ret = btrfs_add_delayed_data_ref(trans, bytenr,
> +		ret = btrfs_add_delayed_data_ref(trans, root, bytenr,
>  						 num_bytes, parent,
>  						 root_objectid, owner, offset,
>  						 0, BTRFS_DROP_DELAYED_REF,
> @@ -8080,7 +8080,7 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
>  			   root->root_key.objectid, owner, offset,
>  			   BTRFS_ADD_DELAYED_EXTENT);
>  
> -	ret = btrfs_add_delayed_data_ref(trans, ins->objectid,
> +	ret = btrfs_add_delayed_data_ref(trans, root, ins->objectid,
>  					 ins->offset, 0,
>  					 root->root_key.objectid, owner,
>  					 offset, ram_bytes,
> 



[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux