Commit 03a1d4c8 authored by Liu Bo's avatar Liu Bo Committed by David Sterba

Btrfs: delayed-inode: use rb_first_cached for ins_root and del_root

rb_first_cached() trades an extra pointer "leftmost" for doing the same job as
rb_first() but in O(1).

Functions manipulating delayed_item need to get the first entry, this converts
it to use rb_first_cached().

For more details about the optimization see patch "Btrfs: delayed-refs:
use rb_first_cached for href_root".
Tested-by: default avatarHolger Hoffstätte <holger@applied-asynchrony.com>
Signed-off-by: default avatarLiu Bo <bo.liu@linux.alibaba.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent e3d03965
...@@ -42,8 +42,8 @@ static inline void btrfs_init_delayed_node( ...@@ -42,8 +42,8 @@ static inline void btrfs_init_delayed_node(
delayed_node->root = root; delayed_node->root = root;
delayed_node->inode_id = inode_id; delayed_node->inode_id = inode_id;
refcount_set(&delayed_node->refs, 0); refcount_set(&delayed_node->refs, 0);
delayed_node->ins_root = RB_ROOT; delayed_node->ins_root = RB_ROOT_CACHED;
delayed_node->del_root = RB_ROOT; delayed_node->del_root = RB_ROOT_CACHED;
mutex_init(&delayed_node->mutex); mutex_init(&delayed_node->mutex);
INIT_LIST_HEAD(&delayed_node->n_list); INIT_LIST_HEAD(&delayed_node->n_list);
INIT_LIST_HEAD(&delayed_node->p_list); INIT_LIST_HEAD(&delayed_node->p_list);
...@@ -390,7 +390,7 @@ static struct btrfs_delayed_item *__btrfs_lookup_delayed_insertion_item( ...@@ -390,7 +390,7 @@ static struct btrfs_delayed_item *__btrfs_lookup_delayed_insertion_item(
struct btrfs_delayed_node *delayed_node, struct btrfs_delayed_node *delayed_node,
struct btrfs_key *key) struct btrfs_key *key)
{ {
return __btrfs_lookup_delayed_item(&delayed_node->ins_root, key, return __btrfs_lookup_delayed_item(&delayed_node->ins_root.rb_root, key,
NULL, NULL); NULL, NULL);
} }
...@@ -400,9 +400,10 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node, ...@@ -400,9 +400,10 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node,
{ {
struct rb_node **p, *node; struct rb_node **p, *node;
struct rb_node *parent_node = NULL; struct rb_node *parent_node = NULL;
struct rb_root *root; struct rb_root_cached *root;
struct btrfs_delayed_item *item; struct btrfs_delayed_item *item;
int cmp; int cmp;
bool leftmost = true;
if (action == BTRFS_DELAYED_INSERTION_ITEM) if (action == BTRFS_DELAYED_INSERTION_ITEM)
root = &delayed_node->ins_root; root = &delayed_node->ins_root;
...@@ -410,7 +411,7 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node, ...@@ -410,7 +411,7 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node,
root = &delayed_node->del_root; root = &delayed_node->del_root;
else else
BUG(); BUG();
p = &root->rb_node; p = &root->rb_root.rb_node;
node = &ins->rb_node; node = &ins->rb_node;
while (*p) { while (*p) {
...@@ -419,16 +420,18 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node, ...@@ -419,16 +420,18 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node,
rb_node); rb_node);
cmp = btrfs_comp_cpu_keys(&item->key, &ins->key); cmp = btrfs_comp_cpu_keys(&item->key, &ins->key);
if (cmp < 0) if (cmp < 0) {
p = &(*p)->rb_right; p = &(*p)->rb_right;
else if (cmp > 0) leftmost = false;
} else if (cmp > 0) {
p = &(*p)->rb_left; p = &(*p)->rb_left;
else } else {
return -EEXIST; return -EEXIST;
}
} }
rb_link_node(node, parent_node, p); rb_link_node(node, parent_node, p);
rb_insert_color(node, root); rb_insert_color_cached(node, root, leftmost);
ins->delayed_node = delayed_node; ins->delayed_node = delayed_node;
ins->ins_or_del = action; ins->ins_or_del = action;
...@@ -468,7 +471,7 @@ static void finish_one_item(struct btrfs_delayed_root *delayed_root) ...@@ -468,7 +471,7 @@ static void finish_one_item(struct btrfs_delayed_root *delayed_root)
static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
{ {
struct rb_root *root; struct rb_root_cached *root;
struct btrfs_delayed_root *delayed_root; struct btrfs_delayed_root *delayed_root;
delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root; delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root;
...@@ -482,7 +485,7 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) ...@@ -482,7 +485,7 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
else else
root = &delayed_item->delayed_node->del_root; root = &delayed_item->delayed_node->del_root;
rb_erase(&delayed_item->rb_node, root); rb_erase_cached(&delayed_item->rb_node, root);
delayed_item->delayed_node->count--; delayed_item->delayed_node->count--;
finish_one_item(delayed_root); finish_one_item(delayed_root);
...@@ -503,7 +506,7 @@ static struct btrfs_delayed_item *__btrfs_first_delayed_insertion_item( ...@@ -503,7 +506,7 @@ static struct btrfs_delayed_item *__btrfs_first_delayed_insertion_item(
struct rb_node *p; struct rb_node *p;
struct btrfs_delayed_item *item = NULL; struct btrfs_delayed_item *item = NULL;
p = rb_first(&delayed_node->ins_root); p = rb_first_cached(&delayed_node->ins_root);
if (p) if (p)
item = rb_entry(p, struct btrfs_delayed_item, rb_node); item = rb_entry(p, struct btrfs_delayed_item, rb_node);
...@@ -516,7 +519,7 @@ static struct btrfs_delayed_item *__btrfs_first_delayed_deletion_item( ...@@ -516,7 +519,7 @@ static struct btrfs_delayed_item *__btrfs_first_delayed_deletion_item(
struct rb_node *p; struct rb_node *p;
struct btrfs_delayed_item *item = NULL; struct btrfs_delayed_item *item = NULL;
p = rb_first(&delayed_node->del_root); p = rb_first_cached(&delayed_node->del_root);
if (p) if (p)
item = rb_entry(p, struct btrfs_delayed_item, rb_node); item = rb_entry(p, struct btrfs_delayed_item, rb_node);
......
...@@ -50,8 +50,8 @@ struct btrfs_delayed_node { ...@@ -50,8 +50,8 @@ struct btrfs_delayed_node {
* is waiting to be dealt with by the async worker. * is waiting to be dealt with by the async worker.
*/ */
struct list_head p_list; struct list_head p_list;
struct rb_root ins_root; struct rb_root_cached ins_root;
struct rb_root del_root; struct rb_root_cached del_root;
struct mutex mutex; struct mutex mutex;
struct btrfs_inode_item inode_item; struct btrfs_inode_item inode_item;
refcount_t refs; refcount_t refs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment