diff options
author | David Woodhouse <dwmw2@infradead.org> | 2005-07-05 17:03:10 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-07-06 08:07:54 -0400 |
commit | 9dee7503ce3fc38911b9873216619190cf688128 (patch) | |
tree | 4a980e7afd14722a81472600ed13e147ff69f923 /fs/jffs2/readinode.c | |
parent | 10c96f2ec37f5369a785cf8c5a065a15e323c743 (diff) |
[JFFS2] Optimise jffs2_add_tn_to_list
Use an rbtree instead of a simple linked list. We were wasting
an amazing amount of time in jffs2_add_tn_to_list().
Thanks to Artem Bityuckiy and Jarkko Jlavinen for noticing.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2/readinode.c')
-rw-r--r-- | fs/jffs2/readinode.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index ef552477c813..081656c1d49e 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: readinode.c,v 1.119 2005/03/01 10:34:03 dedekind Exp $ | 10 | * $Id: readinode.c,v 1.120 2005/07/05 21:03:07 dwmw2 Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
@@ -500,7 +500,9 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, | |||
500 | struct jffs2_inode_info *f, | 500 | struct jffs2_inode_info *f, |
501 | struct jffs2_raw_inode *latest_node) | 501 | struct jffs2_raw_inode *latest_node) |
502 | { | 502 | { |
503 | struct jffs2_tmp_dnode_info *tn_list, *tn; | 503 | struct jffs2_tmp_dnode_info *tn = NULL; |
504 | struct rb_root tn_list; | ||
505 | struct rb_node *rb, *repl_rb; | ||
504 | struct jffs2_full_dirent *fd_list; | 506 | struct jffs2_full_dirent *fd_list; |
505 | struct jffs2_full_dnode *fn = NULL; | 507 | struct jffs2_full_dnode *fn = NULL; |
506 | uint32_t crc; | 508 | uint32_t crc; |
@@ -522,9 +524,10 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, | |||
522 | } | 524 | } |
523 | f->dents = fd_list; | 525 | f->dents = fd_list; |
524 | 526 | ||
525 | while (tn_list) { | 527 | rb = rb_first(&tn_list); |
526 | tn = tn_list; | ||
527 | 528 | ||
529 | while (rb) { | ||
530 | tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb); | ||
528 | fn = tn->fn; | 531 | fn = tn->fn; |
529 | 532 | ||
530 | if (f->metadata) { | 533 | if (f->metadata) { |
@@ -556,7 +559,30 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, | |||
556 | mdata_ver = tn->version; | 559 | mdata_ver = tn->version; |
557 | } | 560 | } |
558 | next_tn: | 561 | next_tn: |
559 | tn_list = tn->next; | 562 | BUG_ON(rb->rb_left); |
563 | repl_rb = NULL; | ||
564 | if (rb->rb_parent && rb->rb_parent->rb_left == rb) { | ||
565 | /* We were then left-hand child of our parent. We need | ||
566 | to move our own right-hand child into our place. */ | ||
567 | repl_rb = rb->rb_right; | ||
568 | if (repl_rb) | ||
569 | repl_rb->rb_parent = rb->rb_parent; | ||
570 | } else | ||
571 | repl_rb = NULL; | ||
572 | |||
573 | rb = rb_next(rb); | ||
574 | |||
575 | /* Remove the spent tn from the tree; don't bother rebalancing | ||
576 | but put our right-hand child in our own place. */ | ||
577 | if (tn->rb.rb_parent) { | ||
578 | if (tn->rb.rb_parent->rb_left == &tn->rb) | ||
579 | tn->rb.rb_parent->rb_left = repl_rb; | ||
580 | else if (tn->rb.rb_parent->rb_right == &tn->rb) | ||
581 | tn->rb.rb_parent->rb_right = repl_rb; | ||
582 | else BUG(); | ||
583 | } else if (tn->rb.rb_right) | ||
584 | tn->rb.rb_right->rb_parent = NULL; | ||
585 | |||
560 | jffs2_free_tmp_dnode_info(tn); | 586 | jffs2_free_tmp_dnode_info(tn); |
561 | } | 587 | } |
562 | D1(jffs2_sanitycheck_fragtree(f)); | 588 | D1(jffs2_sanitycheck_fragtree(f)); |