btrfs: Document __btrfs_inc_extent_ref
diff mbox

Message ID 1526649170-29815-1-git-send-email-nborisov@suse.com
State New
Headers show

Commit Message

Nikolay Borisov May 18, 2018, 1:12 p.m. UTC
Here is a doc-only patch which tires to deobfuscate the terra-incognita
that arguments for delayed refs are.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
Hello, 

This patch needs revieweing since I'm not entirely sure I managed to capture 
the semantics of the "parent" and "owner" arguments. Specifically, parent is 
passed "ref->parent" only if we have a shared block, however looking at the 
code where parent is passed to the add delayed tree/data refs, it seems that 
parent is set to the eb->Start only if the tree where this extent comes from is 
the data_reloc_tree, i.e the code in replace_path/replace_file_extents/do_relocation
__btrfs_cow_block.

For the "owner" argument in case of data extents it'set to the ino, for metadata
extents it's a bit trickier, what I think it always contains for such extents 
is the level of the parent block in the tree. 


If this function is documented correctly then it wil be fairly trivial to 
document btrfs_add_delayed(tree|data)_ref ones as well. 

 fs/btrfs/extent-tree.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

Comments

Nikolay Borisov June 13, 2018, 3:49 p.m. UTC | #1
On 18.05.2018 16:12, Nikolay Borisov wrote:
> Here is a doc-only patch which tires to deobfuscate the terra-incognita
> that arguments for delayed refs are.
> 
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>
> ---
> Hello, 
> 
> This patch needs revieweing since I'm not entirely sure I managed to capture 
> the semantics of the "parent" and "owner" arguments. Specifically, parent is 
> passed "ref->parent" only if we have a shared block, however looking at the 
> code where parent is passed to the add delayed tree/data refs, it seems that 
> parent is set to the eb->Start only if the tree where this extent comes from is 
> the data_reloc_tree, i.e the code in replace_path/replace_file_extents/do_relocation
> __btrfs_cow_block.
> 
> For the "owner" argument in case of data extents it'set to the ino, for metadata
> extents it's a bit trickier, what I think it always contains for such extents 
> is the level of the parent block in the tree. 
> 
> 
> If this function is documented correctly then it wil be fairly trivial to 
> document btrfs_add_delayed(tree|data)_ref ones as well. 


Ping

> 
>  fs/btrfs/extent-tree.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
> index 2ce32f05812f..5a2f4a86dc71 100644
> --- a/fs/btrfs/extent-tree.c
> +++ b/fs/btrfs/extent-tree.c
> @@ -2207,6 +2207,35 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
>  	return ret;
>  }
>  
> +/*
> + * __btrfs_inc_extent_ref - insert backreference for a given extent
> + *
> + * @trans:	    Handle of transaction
> + *
> + * @node:	    The delayed ref node used to get the bytenr/length for
> + *		    extent
> + *
> + * @parent:	    If this is a shared extent (BTRFS_SHARED_DATA_REF_KEY/
> + *		    BTRFS_SHARED_BLOCK_REF_KEY) then parent *may* hold the
> + *		    logical bytenr of the parent block.
> + *
> + * @root_objectid: The id of the root where this modification has originated,
> + *		    this can be either one of the well-known metadata trees or
> + *		    the subvolume id which references this extent.
> + *
> + * @owner:	    For data extents it is the inode number of the owning file.
> + *		    For metadata extents this parameter holds the level in the
> + *		    tree of the parent block.
> + *
> + * @offset:	    For metadata extents this is always 0. For data extents it
> + *		    is the fileoffset this extent belongs to.
> + *
> + * @refs_to_add    Number of references to add
> + *
> + * @extent_op      Pointer to a structure, holding information necessary when
> + *                 updating a tree block's flags
> + *
> + */
>  static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
>  				  struct btrfs_delayed_ref_node *node,
>  				  u64 parent, u64 root_objectid,
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Mahoney June 14, 2018, 9:31 p.m. UTC | #2
On 5/18/18 9:12 AM, Nikolay Borisov wrote:
> Here is a doc-only patch which tires to deobfuscate the terra-incognita
> that arguments for delayed refs are.
> 
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>
> ---
> Hello, 
> 
> This patch needs revieweing since I'm not entirely sure I managed to capture 
> the semantics of the "parent" and "owner" arguments. Specifically, parent is 
> passed "ref->parent" only if we have a shared block, however looking at the 
> code where parent is passed to the add delayed tree/data refs, it seems that 
> parent is set to the eb->Start only if the tree where this extent comes from is 
> the data_reloc_tree, i.e the code in replace_path/replace_file_extents/do_relocation
> __btrfs_cow_block.

This makes sense.  When we create a new extent or add a reference to an
existing one, we have a root to use as a reference.  Those references
are created as indirect references.  When a reference is dropped and the
remaining references are either shared or implied from higher levels in
the tree, we need to create a shared reference.

The exception is relocation which is creating new extents in a literal
sense, but is really just moving them.  We only have the references
already in place to work with, so we'll need to insert updated shared
references to point to the new parent.

> For the "owner" argument in case of data extents it'set to the ino, for metadata
> extents it's a bit trickier, what I think it always contains for such extents 
> is the level of the parent block in the tree. 

It contains the level of the buffer in the tree.

__btrfs_cow_block():

        level = btrfs_header_level(buf);

        if (level == 0)
                btrfs_item_key(buf, &disk_key, 0);
        else
                btrfs_node_key(buf, &disk_key, 0);

Leaf node extents show up in the tree dump as (objectid METADATA_ITEM 0).

If you're referring to the following comment, it was introduced in the
commit that added skinny metadata (3173a18f70554).
        /*
         * Owner is our parent level, so we can just add one to get the
level
         * for the block we are interested in.
         */

I think that Josef was maybe documenting why just using the level was
safe instead of using the full key + level as the old tree block refs
did.  It could probably be made more clear if that's the case.

> If this function is documented correctly then it wil be fairly trivial to 
> document btrfs_add_delayed(tree|data)_ref ones as well. 
> 
>  fs/btrfs/extent-tree.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
> index 2ce32f05812f..5a2f4a86dc71 100644
> --- a/fs/btrfs/extent-tree.c
> +++ b/fs/btrfs/extent-tree.c
> @@ -2207,6 +2207,35 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
>  	return ret;
>  }
>  
> +/*
> + * __btrfs_inc_extent_ref - insert backreference for a given extent
> + *
> + * @trans:	    Handle of transaction
> + *
> + * @node:	    The delayed ref node used to get the bytenr/length for
> + *		    extent
> + *
> + * @parent:	    If this is a shared extent (BTRFS_SHARED_DATA_REF_KEY/
> + *		    BTRFS_SHARED_BLOCK_REF_KEY) then parent *may* hold the> + *		    logical bytenr of the parent block.

If this is a shared extent then parent holds the logical bytenr of the
parent block.  Since new extents are always created with indirect
references, this will only be the case when relocating a shared extent.
In that case, root_objectid will be BTRFS_TREE_RELOC_OBJECTID.
Otherwise, parent must be 0.

> + * @root_objectid: The id of the root where this modification has originated,
> + *		    this can be either one of the well-known metadata trees or
> + *		    the subvolume id which references this extent.
> + *
> + * @owner:	    For data extents it is the inode number of the owning file.
> + *		    For metadata extents this parameter holds the level in the
> + *		    tree of the parent block.
>

As mentioned above, it holds the level of the tree that contains the
block.  The parent can be looked up indirectly by taking this level and
adding 1 until we hit the level of the root node.

> + * @offset:	    For metadata extents this is always 0. For data extents it
> + *		    is the fileoffset this extent belongs to.

For metadata extents, offset is ignored.  It just happens to be passed
as 0 in existing code.

-Jeff

Patch
diff mbox

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 2ce32f05812f..5a2f4a86dc71 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2207,6 +2207,35 @@  int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
 	return ret;
 }
 
+/*
+ * __btrfs_inc_extent_ref - insert backreference for a given extent
+ *
+ * @trans:	    Handle of transaction
+ *
+ * @node:	    The delayed ref node used to get the bytenr/length for
+ *		    extent
+ *
+ * @parent:	    If this is a shared extent (BTRFS_SHARED_DATA_REF_KEY/
+ *		    BTRFS_SHARED_BLOCK_REF_KEY) then parent *may* hold the
+ *		    logical bytenr of the parent block.
+ *
+ * @root_objectid: The id of the root where this modification has originated,
+ *		    this can be either one of the well-known metadata trees or
+ *		    the subvolume id which references this extent.
+ *
+ * @owner:	    For data extents it is the inode number of the owning file.
+ *		    For metadata extents this parameter holds the level in the
+ *		    tree of the parent block.
+ *
+ * @offset:	    For metadata extents this is always 0. For data extents it
+ *		    is the fileoffset this extent belongs to.
+ *
+ * @refs_to_add    Number of references to add
+ *
+ * @extent_op      Pointer to a structure, holding information necessary when
+ *                 updating a tree block's flags
+ *
+ */
 static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
 				  struct btrfs_delayed_ref_node *node,
 				  u64 parent, u64 root_objectid,