diff options
author | Jeff Mahoney <jeffm@suse.com> | 2017-07-13 01:20:08 +0300 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2017-08-16 17:12:01 +0300 |
commit | 00142756e1f8015d2f8ce96532d156689db7e448 (patch) | |
tree | 7f21d4788cb9939c63dd2f11f4c3ffdb6700039b /fs/btrfs/backref.c | |
parent | 6c336b212bef66e507897c78551b3bb4e613a857 (diff) | |
download | linux-00142756e1f8015d2f8ce96532d156689db7e448.tar.xz |
btrfs: backref, add tracepoints for prelim_ref insertion and merging
This patch adds a tracepoint event for prelim_ref insertion and
merging. For each, the ref being inserted or merged and the count
of tree nodes is issued.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r-- | fs/btrfs/backref.c | 118 |
1 files changed, 60 insertions, 58 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 297f33850425..4cda81964dd4 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -18,6 +18,7 @@ #include <linux/mm.h> #include <linux/rbtree.h> +#include <trace/events/btrfs.h> #include "ctree.h" #include "disk-io.h" #include "backref.h" @@ -120,20 +121,6 @@ static int find_extent_in_eb(const struct extent_buffer *eb, return 0; } -/* - * this structure records all encountered refs on the way up to the root - */ -struct prelim_ref { - struct rb_node rbnode; - u64 root_id; - struct btrfs_key key_for_search; - int level; - int count; - struct extent_inode_elem *inode_list; - u64 parent; - u64 wanted_disk_byte; -}; - struct preftree { struct rb_root root; unsigned int count; @@ -212,7 +199,8 @@ static int prelim_ref_compare(struct prelim_ref *ref1, * * Callers should assumed that newref has been freed after calling. */ -static void prelim_ref_insert(struct preftree *preftree, +static void prelim_ref_insert(const struct btrfs_fs_info *fs_info, + struct preftree *preftree, struct prelim_ref *newref) { struct rb_root *root; @@ -243,6 +231,8 @@ static void prelim_ref_insert(struct preftree *preftree, ref->inode_list = newref->inode_list; else eie->next = newref->inode_list; + trace_btrfs_prelim_ref_merge(fs_info, ref, newref, + preftree->count); ref->count += newref->count; free_pref(newref); return; @@ -250,6 +240,7 @@ static void prelim_ref_insert(struct preftree *preftree, } preftree->count++; + trace_btrfs_prelim_ref_insert(fs_info, newref, NULL, preftree->count); rb_link_node(&newref->rbnode, parent, p); rb_insert_color(&newref->rbnode, root); } @@ -308,7 +299,8 @@ static void prelim_release(struct preftree *preftree) * additional information that's available but not required to find the parent * block might help in merging entries to gain some speed. */ -static int add_prelim_ref(struct preftree *preftree, u64 root_id, +static int add_prelim_ref(const struct btrfs_fs_info *fs_info, + struct preftree *preftree, u64 root_id, const struct btrfs_key *key, int level, u64 parent, u64 wanted_disk_byte, int count, gfp_t gfp_mask) { @@ -355,21 +347,23 @@ static int add_prelim_ref(struct preftree *preftree, u64 root_id, ref->count = count; ref->parent = parent; ref->wanted_disk_byte = wanted_disk_byte; - prelim_ref_insert(preftree, ref); + prelim_ref_insert(fs_info, preftree, ref); return 0; } /* direct refs use root == 0, key == NULL */ -static int add_direct_ref(struct preftrees *preftrees, int level, u64 parent, +static int add_direct_ref(const struct btrfs_fs_info *fs_info, + struct preftrees *preftrees, int level, u64 parent, u64 wanted_disk_byte, int count, gfp_t gfp_mask) { - return add_prelim_ref(&preftrees->direct, 0, NULL, level, parent, - wanted_disk_byte, count, gfp_mask); + return add_prelim_ref(fs_info, &preftrees->direct, 0, NULL, level, + parent, wanted_disk_byte, count, gfp_mask); } /* indirect refs use parent == 0 */ -static int add_indirect_ref(struct preftrees *preftrees, u64 root_id, +static int add_indirect_ref(const struct btrfs_fs_info *fs_info, + struct preftrees *preftrees, u64 root_id, const struct btrfs_key *key, int level, u64 wanted_disk_byte, int count, gfp_t gfp_mask) { @@ -377,7 +371,7 @@ static int add_indirect_ref(struct preftrees *preftrees, u64 root_id, if (!key) tree = &preftrees->indirect_missing_keys; - return add_prelim_ref(tree, root_id, key, level, 0, + return add_prelim_ref(fs_info, tree, root_id, key, level, 0, wanted_disk_byte, count, gfp_mask); } @@ -631,7 +625,7 @@ static int resolve_indirect_refs(struct btrfs_fs_info *fs_info, * and return directly. */ if (err == -ENOENT) { - prelim_ref_insert(&preftrees->direct, ref); + prelim_ref_insert(fs_info, &preftrees->direct, ref); continue; } else if (err) { free_pref(ref); @@ -659,11 +653,11 @@ static int resolve_indirect_refs(struct btrfs_fs_info *fs_info, memcpy(new_ref, ref, sizeof(*ref)); new_ref->parent = node->val; new_ref->inode_list = unode_aux_to_inode_list(node); - prelim_ref_insert(&preftrees->direct, new_ref); + prelim_ref_insert(fs_info, &preftrees->direct, new_ref); } /* Now it's a direct ref, put it in the the direct tree */ - prelim_ref_insert(&preftrees->direct, ref); + prelim_ref_insert(fs_info, &preftrees->direct, ref); ulist_reinit(parents); } @@ -707,7 +701,7 @@ static int add_missing_keys(struct btrfs_fs_info *fs_info, btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0); btrfs_tree_read_unlock(eb); free_extent_buffer(eb); - prelim_ref_insert(&preftrees->indirect, ref); + prelim_ref_insert(fs_info, &preftrees->indirect, ref); } return 0; } @@ -716,7 +710,8 @@ static int add_missing_keys(struct btrfs_fs_info *fs_info, * add all currently queued delayed refs from this head whose seq nr is * smaller or equal that seq to the list */ -static int add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, +static int add_delayed_refs(const struct btrfs_fs_info *fs_info, + struct btrfs_delayed_ref_head *head, u64 seq, struct preftrees *preftrees, u64 *total_refs, u64 inum) { @@ -759,8 +754,9 @@ static int add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, struct btrfs_delayed_tree_ref *ref; ref = btrfs_delayed_node_to_tree_ref(node); - ret = add_indirect_ref(preftrees, ref->root, &tmp_op_key, - ref->level + 1, node->bytenr, + ret = add_indirect_ref(fs_info, preftrees, ref->root, + &tmp_op_key, ref->level + 1, + node->bytenr, node->ref_mod * sgn, GFP_ATOMIC); break; @@ -771,9 +767,9 @@ static int add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, ref = btrfs_delayed_node_to_tree_ref(node); - ret = add_direct_ref(preftrees, ref->level + 1, - ref->parent, node->bytenr, - node->ref_mod * sgn, + ret = add_direct_ref(fs_info, preftrees, + ref->level + 1, ref->parent, + node->bytenr, node->ref_mod * sgn, GFP_ATOMIC); break; } @@ -795,8 +791,8 @@ static int add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, break; } - ret = add_indirect_ref(preftrees, ref->root, &key, 0, - node->bytenr, + ret = add_indirect_ref(fs_info, preftrees, ref->root, + &key, 0, node->bytenr, node->ref_mod * sgn, GFP_ATOMIC); break; @@ -807,8 +803,8 @@ static int add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, ref = btrfs_delayed_node_to_data_ref(node); - ret = add_direct_ref(preftrees, 0, ref->parent, - node->bytenr, + ret = add_direct_ref(fs_info, preftrees, 0, + ref->parent, node->bytenr, node->ref_mod * sgn, GFP_ATOMIC); break; @@ -826,7 +822,8 @@ static int add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, /* * add all inline backrefs for bytenr to the list */ -static int add_inline_refs(struct btrfs_path *path, u64 bytenr, +static int add_inline_refs(const struct btrfs_fs_info *fs_info, + struct btrfs_path *path, u64 bytenr, int *info_level, struct preftrees *preftrees, u64 *total_refs, u64 inum) { @@ -883,7 +880,8 @@ static int add_inline_refs(struct btrfs_path *path, u64 bytenr, switch (type) { case BTRFS_SHARED_BLOCK_REF_KEY: - ret = add_direct_ref(preftrees, *info_level + 1, offset, + ret = add_direct_ref(fs_info, preftrees, + *info_level + 1, offset, bytenr, 1, GFP_NOFS); break; case BTRFS_SHARED_DATA_REF_KEY: { @@ -893,14 +891,14 @@ static int add_inline_refs(struct btrfs_path *path, u64 bytenr, sdref = (struct btrfs_shared_data_ref *)(iref + 1); count = btrfs_shared_data_ref_count(leaf, sdref); - ret = add_direct_ref(preftrees, 0, offset, + ret = add_direct_ref(fs_info, preftrees, 0, offset, bytenr, count, GFP_NOFS); break; } case BTRFS_TREE_BLOCK_REF_KEY: - ret = add_indirect_ref(preftrees, offset, NULL, - *info_level + 1, bytenr, 1, - GFP_NOFS); + ret = add_indirect_ref(fs_info, preftrees, offset, + NULL, *info_level + 1, + bytenr, 1, GFP_NOFS); break; case BTRFS_EXTENT_DATA_REF_KEY: { struct btrfs_extent_data_ref *dref; @@ -921,8 +919,9 @@ static int add_inline_refs(struct btrfs_path *path, u64 bytenr, root = btrfs_extent_data_ref_root(leaf, dref); - ret = add_indirect_ref(preftrees, root, &key, 0, bytenr, - count, GFP_NOFS); + ret = add_indirect_ref(fs_info, preftrees, root, + &key, 0, bytenr, count, + GFP_NOFS); break; } default: @@ -973,9 +972,9 @@ static int add_keyed_refs(struct btrfs_fs_info *fs_info, switch (key.type) { case BTRFS_SHARED_BLOCK_REF_KEY: /* SHARED DIRECT METADATA backref */ - ret = add_direct_ref(preftrees, info_level + 1, - key.offset, bytenr, 1, - GFP_NOFS); + ret = add_direct_ref(fs_info, preftrees, + info_level + 1, key.offset, + bytenr, 1, GFP_NOFS); break; case BTRFS_SHARED_DATA_REF_KEY: { /* SHARED DIRECT FULL backref */ @@ -985,15 +984,16 @@ static int add_keyed_refs(struct btrfs_fs_info *fs_info, sdref = btrfs_item_ptr(leaf, slot, struct btrfs_shared_data_ref); count = btrfs_shared_data_ref_count(leaf, sdref); - ret = add_direct_ref(preftrees, 0, key.offset, bytenr, - count, GFP_NOFS); + ret = add_direct_ref(fs_info, preftrees, 0, + key.offset, bytenr, count, + GFP_NOFS); break; } case BTRFS_TREE_BLOCK_REF_KEY: /* NORMAL INDIRECT METADATA backref */ - ret = add_indirect_ref(preftrees, key.offset, NULL, - info_level + 1, bytenr, 1, - GFP_NOFS); + ret = add_indirect_ref(fs_info, preftrees, key.offset, + NULL, info_level + 1, bytenr, + 1, GFP_NOFS); break; case BTRFS_EXTENT_DATA_REF_KEY: { /* NORMAL INDIRECT DATA backref */ @@ -1015,8 +1015,9 @@ static int add_keyed_refs(struct btrfs_fs_info *fs_info, } root = btrfs_extent_data_ref_root(leaf, dref); - ret = add_indirect_ref(preftrees, root, &key, 0, bytenr, - count, GFP_NOFS); + ret = add_indirect_ref(fs_info, preftrees, root, + &key, 0, bytenr, count, + GFP_NOFS); break; } default: @@ -1129,8 +1130,8 @@ again: goto again; } spin_unlock(&delayed_refs->lock); - ret = add_delayed_refs(head, time_seq, &preftrees, - &total_refs, inum); + ret = add_delayed_refs(fs_info, head, time_seq, + &preftrees, &total_refs, inum); mutex_unlock(&head->mutex); if (ret) goto out; @@ -1150,8 +1151,9 @@ again: if (key.objectid == bytenr && (key.type == BTRFS_EXTENT_ITEM_KEY || key.type == BTRFS_METADATA_ITEM_KEY)) { - ret = add_inline_refs(path, bytenr, &info_level, - &preftrees, &total_refs, inum); + ret = add_inline_refs(fs_info, path, bytenr, + &info_level, &preftrees, + &total_refs, inum); if (ret) goto out; ret = add_keyed_refs(fs_info, path, bytenr, info_level, |