diff options
author | Liu Bo <bo.liu@linux.alibaba.com> | 2018-08-22 15:51:51 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2018-10-15 11:23:33 -0400 |
commit | 03a1d4c891634dd5b98da865fb783e8b22d4d027 (patch) | |
tree | 13f08f751243f45acad6274532bc959e2ab37c55 /fs/btrfs/delayed-inode.c | |
parent | e3d039656384288bbe952413d8d404b3035fe7d7 (diff) |
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: Holger Hoffstätte <holger@applied-asynchrony.com>
Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/delayed-inode.c')
-rw-r--r-- | fs/btrfs/delayed-inode.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 47ce74cf134a..15dcbd6ef531 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -42,8 +42,8 @@ static inline void btrfs_init_delayed_node( | |||
42 | delayed_node->root = root; | 42 | delayed_node->root = root; |
43 | delayed_node->inode_id = inode_id; | 43 | delayed_node->inode_id = inode_id; |
44 | refcount_set(&delayed_node->refs, 0); | 44 | refcount_set(&delayed_node->refs, 0); |
45 | delayed_node->ins_root = RB_ROOT; | 45 | delayed_node->ins_root = RB_ROOT_CACHED; |
46 | delayed_node->del_root = RB_ROOT; | 46 | delayed_node->del_root = RB_ROOT_CACHED; |
47 | mutex_init(&delayed_node->mutex); | 47 | mutex_init(&delayed_node->mutex); |
48 | INIT_LIST_HEAD(&delayed_node->n_list); | 48 | INIT_LIST_HEAD(&delayed_node->n_list); |
49 | INIT_LIST_HEAD(&delayed_node->p_list); | 49 | INIT_LIST_HEAD(&delayed_node->p_list); |
@@ -390,7 +390,7 @@ static struct btrfs_delayed_item *__btrfs_lookup_delayed_insertion_item( | |||
390 | struct btrfs_delayed_node *delayed_node, | 390 | struct btrfs_delayed_node *delayed_node, |
391 | struct btrfs_key *key) | 391 | struct btrfs_key *key) |
392 | { | 392 | { |
393 | return __btrfs_lookup_delayed_item(&delayed_node->ins_root, key, | 393 | return __btrfs_lookup_delayed_item(&delayed_node->ins_root.rb_root, key, |
394 | NULL, NULL); | 394 | NULL, NULL); |
395 | } | 395 | } |
396 | 396 | ||
@@ -400,9 +400,10 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node, | |||
400 | { | 400 | { |
401 | struct rb_node **p, *node; | 401 | struct rb_node **p, *node; |
402 | struct rb_node *parent_node = NULL; | 402 | struct rb_node *parent_node = NULL; |
403 | struct rb_root *root; | 403 | struct rb_root_cached *root; |
404 | struct btrfs_delayed_item *item; | 404 | struct btrfs_delayed_item *item; |
405 | int cmp; | 405 | int cmp; |
406 | bool leftmost = true; | ||
406 | 407 | ||
407 | if (action == BTRFS_DELAYED_INSERTION_ITEM) | 408 | if (action == BTRFS_DELAYED_INSERTION_ITEM) |
408 | root = &delayed_node->ins_root; | 409 | root = &delayed_node->ins_root; |
@@ -410,7 +411,7 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node, | |||
410 | root = &delayed_node->del_root; | 411 | root = &delayed_node->del_root; |
411 | else | 412 | else |
412 | BUG(); | 413 | BUG(); |
413 | p = &root->rb_node; | 414 | p = &root->rb_root.rb_node; |
414 | node = &ins->rb_node; | 415 | node = &ins->rb_node; |
415 | 416 | ||
416 | while (*p) { | 417 | while (*p) { |
@@ -419,16 +420,18 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node, | |||
419 | rb_node); | 420 | rb_node); |
420 | 421 | ||
421 | cmp = btrfs_comp_cpu_keys(&item->key, &ins->key); | 422 | cmp = btrfs_comp_cpu_keys(&item->key, &ins->key); |
422 | if (cmp < 0) | 423 | if (cmp < 0) { |
423 | p = &(*p)->rb_right; | 424 | p = &(*p)->rb_right; |
424 | else if (cmp > 0) | 425 | leftmost = false; |
426 | } else if (cmp > 0) { | ||
425 | p = &(*p)->rb_left; | 427 | p = &(*p)->rb_left; |
426 | else | 428 | } else { |
427 | return -EEXIST; | 429 | return -EEXIST; |
430 | } | ||
428 | } | 431 | } |
429 | 432 | ||
430 | rb_link_node(node, parent_node, p); | 433 | rb_link_node(node, parent_node, p); |
431 | rb_insert_color(node, root); | 434 | rb_insert_color_cached(node, root, leftmost); |
432 | ins->delayed_node = delayed_node; | 435 | ins->delayed_node = delayed_node; |
433 | ins->ins_or_del = action; | 436 | ins->ins_or_del = action; |
434 | 437 | ||
@@ -468,7 +471,7 @@ static void finish_one_item(struct btrfs_delayed_root *delayed_root) | |||
468 | 471 | ||
469 | static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) | 472 | static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) |
470 | { | 473 | { |
471 | struct rb_root *root; | 474 | struct rb_root_cached *root; |
472 | struct btrfs_delayed_root *delayed_root; | 475 | struct btrfs_delayed_root *delayed_root; |
473 | 476 | ||
474 | delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root; | 477 | 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 | else | 485 | else |
483 | root = &delayed_item->delayed_node->del_root; | 486 | root = &delayed_item->delayed_node->del_root; |
484 | 487 | ||
485 | rb_erase(&delayed_item->rb_node, root); | 488 | rb_erase_cached(&delayed_item->rb_node, root); |
486 | delayed_item->delayed_node->count--; | 489 | delayed_item->delayed_node->count--; |
487 | 490 | ||
488 | finish_one_item(delayed_root); | 491 | finish_one_item(delayed_root); |
@@ -503,7 +506,7 @@ static struct btrfs_delayed_item *__btrfs_first_delayed_insertion_item( | |||
503 | struct rb_node *p; | 506 | struct rb_node *p; |
504 | struct btrfs_delayed_item *item = NULL; | 507 | struct btrfs_delayed_item *item = NULL; |
505 | 508 | ||
506 | p = rb_first(&delayed_node->ins_root); | 509 | p = rb_first_cached(&delayed_node->ins_root); |
507 | if (p) | 510 | if (p) |
508 | item = rb_entry(p, struct btrfs_delayed_item, rb_node); | 511 | item = rb_entry(p, struct btrfs_delayed_item, rb_node); |
509 | 512 | ||
@@ -516,7 +519,7 @@ static struct btrfs_delayed_item *__btrfs_first_delayed_deletion_item( | |||
516 | struct rb_node *p; | 519 | struct rb_node *p; |
517 | struct btrfs_delayed_item *item = NULL; | 520 | struct btrfs_delayed_item *item = NULL; |
518 | 521 | ||
519 | p = rb_first(&delayed_node->del_root); | 522 | p = rb_first_cached(&delayed_node->del_root); |
520 | if (p) | 523 | if (p) |
521 | item = rb_entry(p, struct btrfs_delayed_item, rb_node); | 524 | item = rb_entry(p, struct btrfs_delayed_item, rb_node); |
522 | 525 | ||