diff options
author | Chao Yu <yuchao0@huawei.com> | 2018-10-03 23:18:30 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2018-10-16 12:36:59 -0400 |
commit | 4dada3fd7025e9dbc56c93d9996cba6e47915c62 (patch) | |
tree | 55f52b75e7a306beefb9c3bdd63c7ad4ef4fddb2 | |
parent | ef2a007134b4eaa39264c885999f296577bc87d2 (diff) |
f2fs: use rb_*_cached friends
As rbtree supports caching leftmost node natively, update f2fs codes
to use rb_*_cached helpers to speed up leftmost node visiting.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fs/f2fs/extent_cache.c | 78 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 17 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 22 |
3 files changed, 69 insertions, 48 deletions
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 904ad7ba5a45..1cb0fcc67d2d 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c | |||
@@ -27,10 +27,10 @@ static struct rb_entry *__lookup_rb_tree_fast(struct rb_entry *cached_re, | |||
27 | return NULL; | 27 | return NULL; |
28 | } | 28 | } |
29 | 29 | ||
30 | static struct rb_entry *__lookup_rb_tree_slow(struct rb_root *root, | 30 | static struct rb_entry *__lookup_rb_tree_slow(struct rb_root_cached *root, |
31 | unsigned int ofs) | 31 | unsigned int ofs) |
32 | { | 32 | { |
33 | struct rb_node *node = root->rb_node; | 33 | struct rb_node *node = root->rb_root.rb_node; |
34 | struct rb_entry *re; | 34 | struct rb_entry *re; |
35 | 35 | ||
36 | while (node) { | 36 | while (node) { |
@@ -46,7 +46,7 @@ static struct rb_entry *__lookup_rb_tree_slow(struct rb_root *root, | |||
46 | return NULL; | 46 | return NULL; |
47 | } | 47 | } |
48 | 48 | ||
49 | struct rb_entry *f2fs_lookup_rb_tree(struct rb_root *root, | 49 | struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root, |
50 | struct rb_entry *cached_re, unsigned int ofs) | 50 | struct rb_entry *cached_re, unsigned int ofs) |
51 | { | 51 | { |
52 | struct rb_entry *re; | 52 | struct rb_entry *re; |
@@ -59,22 +59,25 @@ struct rb_entry *f2fs_lookup_rb_tree(struct rb_root *root, | |||
59 | } | 59 | } |
60 | 60 | ||
61 | struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi, | 61 | struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi, |
62 | struct rb_root *root, struct rb_node **parent, | 62 | struct rb_root_cached *root, |
63 | unsigned int ofs) | 63 | struct rb_node **parent, |
64 | unsigned int ofs, bool *leftmost) | ||
64 | { | 65 | { |
65 | struct rb_node **p = &root->rb_node; | 66 | struct rb_node **p = &root->rb_root.rb_node; |
66 | struct rb_entry *re; | 67 | struct rb_entry *re; |
67 | 68 | ||
68 | while (*p) { | 69 | while (*p) { |
69 | *parent = *p; | 70 | *parent = *p; |
70 | re = rb_entry(*parent, struct rb_entry, rb_node); | 71 | re = rb_entry(*parent, struct rb_entry, rb_node); |
71 | 72 | ||
72 | if (ofs < re->ofs) | 73 | if (ofs < re->ofs) { |
73 | p = &(*p)->rb_left; | 74 | p = &(*p)->rb_left; |
74 | else if (ofs >= re->ofs + re->len) | 75 | } else if (ofs >= re->ofs + re->len) { |
75 | p = &(*p)->rb_right; | 76 | p = &(*p)->rb_right; |
76 | else | 77 | *leftmost = false; |
78 | } else { | ||
77 | f2fs_bug_on(sbi, 1); | 79 | f2fs_bug_on(sbi, 1); |
80 | } | ||
78 | } | 81 | } |
79 | 82 | ||
80 | return p; | 83 | return p; |
@@ -89,16 +92,16 @@ struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi, | |||
89 | * in order to simpfy the insertion after. | 92 | * in order to simpfy the insertion after. |
90 | * tree must stay unchanged between lookup and insertion. | 93 | * tree must stay unchanged between lookup and insertion. |
91 | */ | 94 | */ |
92 | struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root *root, | 95 | struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root_cached *root, |
93 | struct rb_entry *cached_re, | 96 | struct rb_entry *cached_re, |
94 | unsigned int ofs, | 97 | unsigned int ofs, |
95 | struct rb_entry **prev_entry, | 98 | struct rb_entry **prev_entry, |
96 | struct rb_entry **next_entry, | 99 | struct rb_entry **next_entry, |
97 | struct rb_node ***insert_p, | 100 | struct rb_node ***insert_p, |
98 | struct rb_node **insert_parent, | 101 | struct rb_node **insert_parent, |
99 | bool force) | 102 | bool force, bool *leftmost) |
100 | { | 103 | { |
101 | struct rb_node **pnode = &root->rb_node; | 104 | struct rb_node **pnode = &root->rb_root.rb_node; |
102 | struct rb_node *parent = NULL, *tmp_node; | 105 | struct rb_node *parent = NULL, *tmp_node; |
103 | struct rb_entry *re = cached_re; | 106 | struct rb_entry *re = cached_re; |
104 | 107 | ||
@@ -107,7 +110,7 @@ struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root *root, | |||
107 | *prev_entry = NULL; | 110 | *prev_entry = NULL; |
108 | *next_entry = NULL; | 111 | *next_entry = NULL; |
109 | 112 | ||
110 | if (RB_EMPTY_ROOT(root)) | 113 | if (RB_EMPTY_ROOT(&root->rb_root)) |
111 | return NULL; | 114 | return NULL; |
112 | 115 | ||
113 | if (re) { | 116 | if (re) { |
@@ -115,16 +118,22 @@ struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root *root, | |||
115 | goto lookup_neighbors; | 118 | goto lookup_neighbors; |
116 | } | 119 | } |
117 | 120 | ||
121 | if (leftmost) | ||
122 | *leftmost = true; | ||
123 | |||
118 | while (*pnode) { | 124 | while (*pnode) { |
119 | parent = *pnode; | 125 | parent = *pnode; |
120 | re = rb_entry(*pnode, struct rb_entry, rb_node); | 126 | re = rb_entry(*pnode, struct rb_entry, rb_node); |
121 | 127 | ||
122 | if (ofs < re->ofs) | 128 | if (ofs < re->ofs) { |
123 | pnode = &(*pnode)->rb_left; | 129 | pnode = &(*pnode)->rb_left; |
124 | else if (ofs >= re->ofs + re->len) | 130 | } else if (ofs >= re->ofs + re->len) { |
125 | pnode = &(*pnode)->rb_right; | 131 | pnode = &(*pnode)->rb_right; |
126 | else | 132 | if (leftmost) |
133 | *leftmost = false; | ||
134 | } else { | ||
127 | goto lookup_neighbors; | 135 | goto lookup_neighbors; |
136 | } | ||
128 | } | 137 | } |
129 | 138 | ||
130 | *insert_p = pnode; | 139 | *insert_p = pnode; |
@@ -157,10 +166,10 @@ lookup_neighbors: | |||
157 | } | 166 | } |
158 | 167 | ||
159 | bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi, | 168 | bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi, |
160 | struct rb_root *root) | 169 | struct rb_root_cached *root) |
161 | { | 170 | { |
162 | #ifdef CONFIG_F2FS_CHECK_FS | 171 | #ifdef CONFIG_F2FS_CHECK_FS |
163 | struct rb_node *cur = rb_first(root), *next; | 172 | struct rb_node *cur = rb_first_cached(root), *next; |
164 | struct rb_entry *cur_re, *next_re; | 173 | struct rb_entry *cur_re, *next_re; |
165 | 174 | ||
166 | if (!cur) | 175 | if (!cur) |
@@ -193,7 +202,8 @@ static struct kmem_cache *extent_node_slab; | |||
193 | 202 | ||
194 | static struct extent_node *__attach_extent_node(struct f2fs_sb_info *sbi, | 203 | static struct extent_node *__attach_extent_node(struct f2fs_sb_info *sbi, |
195 | struct extent_tree *et, struct extent_info *ei, | 204 | struct extent_tree *et, struct extent_info *ei, |
196 | struct rb_node *parent, struct rb_node **p) | 205 | struct rb_node *parent, struct rb_node **p, |
206 | bool leftmost) | ||
197 | { | 207 | { |
198 | struct extent_node *en; | 208 | struct extent_node *en; |
199 | 209 | ||
@@ -206,7 +216,7 @@ static struct extent_node *__attach_extent_node(struct f2fs_sb_info *sbi, | |||
206 | en->et = et; | 216 | en->et = et; |
207 | 217 | ||
208 | rb_link_node(&en->rb_node, parent, p); | 218 | rb_link_node(&en->rb_node, parent, p); |
209 | rb_insert_color(&en->rb_node, &et->root); | 219 | rb_insert_color_cached(&en->rb_node, &et->root, leftmost); |
210 | atomic_inc(&et->node_cnt); | 220 | atomic_inc(&et->node_cnt); |
211 | atomic_inc(&sbi->total_ext_node); | 221 | atomic_inc(&sbi->total_ext_node); |
212 | return en; | 222 | return en; |
@@ -215,7 +225,7 @@ static struct extent_node *__attach_extent_node(struct f2fs_sb_info *sbi, | |||
215 | static void __detach_extent_node(struct f2fs_sb_info *sbi, | 225 | static void __detach_extent_node(struct f2fs_sb_info *sbi, |
216 | struct extent_tree *et, struct extent_node *en) | 226 | struct extent_tree *et, struct extent_node *en) |
217 | { | 227 | { |
218 | rb_erase(&en->rb_node, &et->root); | 228 | rb_erase_cached(&en->rb_node, &et->root); |
219 | atomic_dec(&et->node_cnt); | 229 | atomic_dec(&et->node_cnt); |
220 | atomic_dec(&sbi->total_ext_node); | 230 | atomic_dec(&sbi->total_ext_node); |
221 | 231 | ||
@@ -254,7 +264,7 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode) | |||
254 | f2fs_radix_tree_insert(&sbi->extent_tree_root, ino, et); | 264 | f2fs_radix_tree_insert(&sbi->extent_tree_root, ino, et); |
255 | memset(et, 0, sizeof(struct extent_tree)); | 265 | memset(et, 0, sizeof(struct extent_tree)); |
256 | et->ino = ino; | 266 | et->ino = ino; |
257 | et->root = RB_ROOT; | 267 | et->root = RB_ROOT_CACHED; |
258 | et->cached_en = NULL; | 268 | et->cached_en = NULL; |
259 | rwlock_init(&et->lock); | 269 | rwlock_init(&et->lock); |
260 | INIT_LIST_HEAD(&et->list); | 270 | INIT_LIST_HEAD(&et->list); |
@@ -275,10 +285,10 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode) | |||
275 | static struct extent_node *__init_extent_tree(struct f2fs_sb_info *sbi, | 285 | static struct extent_node *__init_extent_tree(struct f2fs_sb_info *sbi, |
276 | struct extent_tree *et, struct extent_info *ei) | 286 | struct extent_tree *et, struct extent_info *ei) |
277 | { | 287 | { |
278 | struct rb_node **p = &et->root.rb_node; | 288 | struct rb_node **p = &et->root.rb_root.rb_node; |
279 | struct extent_node *en; | 289 | struct extent_node *en; |
280 | 290 | ||
281 | en = __attach_extent_node(sbi, et, ei, NULL, p); | 291 | en = __attach_extent_node(sbi, et, ei, NULL, p, true); |
282 | if (!en) | 292 | if (!en) |
283 | return NULL; | 293 | return NULL; |
284 | 294 | ||
@@ -294,7 +304,7 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi, | |||
294 | struct extent_node *en; | 304 | struct extent_node *en; |
295 | unsigned int count = atomic_read(&et->node_cnt); | 305 | unsigned int count = atomic_read(&et->node_cnt); |
296 | 306 | ||
297 | node = rb_first(&et->root); | 307 | node = rb_first_cached(&et->root); |
298 | while (node) { | 308 | while (node) { |
299 | next = rb_next(node); | 309 | next = rb_next(node); |
300 | en = rb_entry(node, struct extent_node, rb_node); | 310 | en = rb_entry(node, struct extent_node, rb_node); |
@@ -452,7 +462,8 @@ static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi, | |||
452 | static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi, | 462 | static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi, |
453 | struct extent_tree *et, struct extent_info *ei, | 463 | struct extent_tree *et, struct extent_info *ei, |
454 | struct rb_node **insert_p, | 464 | struct rb_node **insert_p, |
455 | struct rb_node *insert_parent) | 465 | struct rb_node *insert_parent, |
466 | bool leftmost) | ||
456 | { | 467 | { |
457 | struct rb_node **p; | 468 | struct rb_node **p; |
458 | struct rb_node *parent = NULL; | 469 | struct rb_node *parent = NULL; |
@@ -464,9 +475,12 @@ static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi, | |||
464 | goto do_insert; | 475 | goto do_insert; |
465 | } | 476 | } |
466 | 477 | ||
467 | p = f2fs_lookup_rb_tree_for_insert(sbi, &et->root, &parent, ei->fofs); | 478 | leftmost = true; |
479 | |||
480 | p = f2fs_lookup_rb_tree_for_insert(sbi, &et->root, &parent, | ||
481 | ei->fofs, &leftmost); | ||
468 | do_insert: | 482 | do_insert: |
469 | en = __attach_extent_node(sbi, et, ei, parent, p); | 483 | en = __attach_extent_node(sbi, et, ei, parent, p, leftmost); |
470 | if (!en) | 484 | if (!en) |
471 | return NULL; | 485 | return NULL; |
472 | 486 | ||
@@ -492,6 +506,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode, | |||
492 | unsigned int end = fofs + len; | 506 | unsigned int end = fofs + len; |
493 | unsigned int pos = (unsigned int)fofs; | 507 | unsigned int pos = (unsigned int)fofs; |
494 | bool updated = false; | 508 | bool updated = false; |
509 | bool leftmost; | ||
495 | 510 | ||
496 | if (!et) | 511 | if (!et) |
497 | return; | 512 | return; |
@@ -519,7 +534,8 @@ static void f2fs_update_extent_tree_range(struct inode *inode, | |||
519 | (struct rb_entry *)et->cached_en, fofs, | 534 | (struct rb_entry *)et->cached_en, fofs, |
520 | (struct rb_entry **)&prev_en, | 535 | (struct rb_entry **)&prev_en, |
521 | (struct rb_entry **)&next_en, | 536 | (struct rb_entry **)&next_en, |
522 | &insert_p, &insert_parent, false); | 537 | &insert_p, &insert_parent, false, |
538 | &leftmost); | ||
523 | if (!en) | 539 | if (!en) |
524 | en = next_en; | 540 | en = next_en; |
525 | 541 | ||
@@ -546,7 +562,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode, | |||
546 | end - dei.fofs + dei.blk, | 562 | end - dei.fofs + dei.blk, |
547 | org_end - end); | 563 | org_end - end); |
548 | en1 = __insert_extent_tree(sbi, et, &ei, | 564 | en1 = __insert_extent_tree(sbi, et, &ei, |
549 | NULL, NULL); | 565 | NULL, NULL, true); |
550 | next_en = en1; | 566 | next_en = en1; |
551 | } else { | 567 | } else { |
552 | en->ei.fofs = end; | 568 | en->ei.fofs = end; |
@@ -587,7 +603,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode, | |||
587 | set_extent_info(&ei, fofs, blkaddr, len); | 603 | set_extent_info(&ei, fofs, blkaddr, len); |
588 | if (!__try_merge_extent_node(sbi, et, &ei, prev_en, next_en)) | 604 | if (!__try_merge_extent_node(sbi, et, &ei, prev_en, next_en)) |
589 | __insert_extent_tree(sbi, et, &ei, | 605 | __insert_extent_tree(sbi, et, &ei, |
590 | insert_p, insert_parent); | 606 | insert_p, insert_parent, leftmost); |
591 | 607 | ||
592 | /* give up extent_cache, if split and small updates happen */ | 608 | /* give up extent_cache, if split and small updates happen */ |
593 | if (dei.len >= 1 && | 609 | if (dei.len >= 1 && |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index bf81c60e12b8..829355dc469b 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -328,7 +328,7 @@ struct discard_cmd_control { | |||
328 | atomic_t issued_discard; /* # of issued discard */ | 328 | atomic_t issued_discard; /* # of issued discard */ |
329 | atomic_t issing_discard; /* # of issing discard */ | 329 | atomic_t issing_discard; /* # of issing discard */ |
330 | atomic_t discard_cmd_cnt; /* # of cached cmd count */ | 330 | atomic_t discard_cmd_cnt; /* # of cached cmd count */ |
331 | struct rb_root root; /* root of discard rb-tree */ | 331 | struct rb_root_cached root; /* root of discard rb-tree */ |
332 | bool rbtree_check; /* config for consistence check */ | 332 | bool rbtree_check; /* config for consistence check */ |
333 | }; | 333 | }; |
334 | 334 | ||
@@ -570,7 +570,7 @@ struct extent_node { | |||
570 | 570 | ||
571 | struct extent_tree { | 571 | struct extent_tree { |
572 | nid_t ino; /* inode number */ | 572 | nid_t ino; /* inode number */ |
573 | struct rb_root root; /* root of extent info rb-tree */ | 573 | struct rb_root_cached root; /* root of extent info rb-tree */ |
574 | struct extent_node *cached_en; /* recently accessed extent node */ | 574 | struct extent_node *cached_en; /* recently accessed extent node */ |
575 | struct extent_info largest; /* largested extent info */ | 575 | struct extent_info largest; /* largested extent info */ |
576 | struct list_head list; /* to be used by sbi->zombie_list */ | 576 | struct list_head list; /* to be used by sbi->zombie_list */ |
@@ -3368,18 +3368,19 @@ void f2fs_leave_shrinker(struct f2fs_sb_info *sbi); | |||
3368 | /* | 3368 | /* |
3369 | * extent_cache.c | 3369 | * extent_cache.c |
3370 | */ | 3370 | */ |
3371 | struct rb_entry *f2fs_lookup_rb_tree(struct rb_root *root, | 3371 | struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root, |
3372 | struct rb_entry *cached_re, unsigned int ofs); | 3372 | struct rb_entry *cached_re, unsigned int ofs); |
3373 | struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi, | 3373 | struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi, |
3374 | struct rb_root *root, struct rb_node **parent, | 3374 | struct rb_root_cached *root, |
3375 | unsigned int ofs); | 3375 | struct rb_node **parent, |
3376 | struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root *root, | 3376 | unsigned int ofs, bool *leftmost); |
3377 | struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root_cached *root, | ||
3377 | struct rb_entry *cached_re, unsigned int ofs, | 3378 | struct rb_entry *cached_re, unsigned int ofs, |
3378 | struct rb_entry **prev_entry, struct rb_entry **next_entry, | 3379 | struct rb_entry **prev_entry, struct rb_entry **next_entry, |
3379 | struct rb_node ***insert_p, struct rb_node **insert_parent, | 3380 | struct rb_node ***insert_p, struct rb_node **insert_parent, |
3380 | bool force); | 3381 | bool force, bool *leftmost); |
3381 | bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi, | 3382 | bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi, |
3382 | struct rb_root *root); | 3383 | struct rb_root_cached *root); |
3383 | unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink); | 3384 | unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink); |
3384 | bool f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext); | 3385 | bool f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext); |
3385 | void f2fs_drop_extent_tree(struct inode *inode); | 3386 | void f2fs_drop_extent_tree(struct inode *inode); |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 195dc8142bff..805c8310d7b0 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -920,7 +920,8 @@ static struct discard_cmd *__create_discard_cmd(struct f2fs_sb_info *sbi, | |||
920 | static struct discard_cmd *__attach_discard_cmd(struct f2fs_sb_info *sbi, | 920 | static struct discard_cmd *__attach_discard_cmd(struct f2fs_sb_info *sbi, |
921 | struct block_device *bdev, block_t lstart, | 921 | struct block_device *bdev, block_t lstart, |
922 | block_t start, block_t len, | 922 | block_t start, block_t len, |
923 | struct rb_node *parent, struct rb_node **p) | 923 | struct rb_node *parent, struct rb_node **p, |
924 | bool leftmost) | ||
924 | { | 925 | { |
925 | struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; | 926 | struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; |
926 | struct discard_cmd *dc; | 927 | struct discard_cmd *dc; |
@@ -928,7 +929,7 @@ static struct discard_cmd *__attach_discard_cmd(struct f2fs_sb_info *sbi, | |||
928 | dc = __create_discard_cmd(sbi, bdev, lstart, start, len); | 929 | dc = __create_discard_cmd(sbi, bdev, lstart, start, len); |
929 | 930 | ||
930 | rb_link_node(&dc->rb_node, parent, p); | 931 | rb_link_node(&dc->rb_node, parent, p); |
931 | rb_insert_color(&dc->rb_node, &dcc->root); | 932 | rb_insert_color_cached(&dc->rb_node, &dcc->root, leftmost); |
932 | 933 | ||
933 | return dc; | 934 | return dc; |
934 | } | 935 | } |
@@ -940,7 +941,7 @@ static void __detach_discard_cmd(struct discard_cmd_control *dcc, | |||
940 | atomic_sub(dc->issuing, &dcc->issing_discard); | 941 | atomic_sub(dc->issuing, &dcc->issing_discard); |
941 | 942 | ||
942 | list_del(&dc->list); | 943 | list_del(&dc->list); |
943 | rb_erase(&dc->rb_node, &dcc->root); | 944 | rb_erase_cached(&dc->rb_node, &dcc->root); |
944 | dcc->undiscard_blks -= dc->len; | 945 | dcc->undiscard_blks -= dc->len; |
945 | 946 | ||
946 | kmem_cache_free(discard_cmd_slab, dc); | 947 | kmem_cache_free(discard_cmd_slab, dc); |
@@ -1177,6 +1178,7 @@ static struct discard_cmd *__insert_discard_tree(struct f2fs_sb_info *sbi, | |||
1177 | struct rb_node **p; | 1178 | struct rb_node **p; |
1178 | struct rb_node *parent = NULL; | 1179 | struct rb_node *parent = NULL; |
1179 | struct discard_cmd *dc = NULL; | 1180 | struct discard_cmd *dc = NULL; |
1181 | bool leftmost = true; | ||
1180 | 1182 | ||
1181 | if (insert_p && insert_parent) { | 1183 | if (insert_p && insert_parent) { |
1182 | parent = insert_parent; | 1184 | parent = insert_parent; |
@@ -1184,9 +1186,11 @@ static struct discard_cmd *__insert_discard_tree(struct f2fs_sb_info *sbi, | |||
1184 | goto do_insert; | 1186 | goto do_insert; |
1185 | } | 1187 | } |
1186 | 1188 | ||
1187 | p = f2fs_lookup_rb_tree_for_insert(sbi, &dcc->root, &parent, lstart); | 1189 | p = f2fs_lookup_rb_tree_for_insert(sbi, &dcc->root, &parent, |
1190 | lstart, &leftmost); | ||
1188 | do_insert: | 1191 | do_insert: |
1189 | dc = __attach_discard_cmd(sbi, bdev, lstart, start, len, parent, p); | 1192 | dc = __attach_discard_cmd(sbi, bdev, lstart, start, len, parent, |
1193 | p, leftmost); | ||
1190 | if (!dc) | 1194 | if (!dc) |
1191 | return NULL; | 1195 | return NULL; |
1192 | 1196 | ||
@@ -1254,7 +1258,7 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi, | |||
1254 | NULL, lstart, | 1258 | NULL, lstart, |
1255 | (struct rb_entry **)&prev_dc, | 1259 | (struct rb_entry **)&prev_dc, |
1256 | (struct rb_entry **)&next_dc, | 1260 | (struct rb_entry **)&next_dc, |
1257 | &insert_p, &insert_parent, true); | 1261 | &insert_p, &insert_parent, true, NULL); |
1258 | if (dc) | 1262 | if (dc) |
1259 | prev_dc = dc; | 1263 | prev_dc = dc; |
1260 | 1264 | ||
@@ -1362,7 +1366,7 @@ static unsigned int __issue_discard_cmd_orderly(struct f2fs_sb_info *sbi, | |||
1362 | NULL, pos, | 1366 | NULL, pos, |
1363 | (struct rb_entry **)&prev_dc, | 1367 | (struct rb_entry **)&prev_dc, |
1364 | (struct rb_entry **)&next_dc, | 1368 | (struct rb_entry **)&next_dc, |
1365 | &insert_p, &insert_parent, true); | 1369 | &insert_p, &insert_parent, true, NULL); |
1366 | if (!dc) | 1370 | if (!dc) |
1367 | dc = next_dc; | 1371 | dc = next_dc; |
1368 | 1372 | ||
@@ -1994,7 +1998,7 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi) | |||
1994 | dcc->max_discards = MAIN_SEGS(sbi) << sbi->log_blocks_per_seg; | 1998 | dcc->max_discards = MAIN_SEGS(sbi) << sbi->log_blocks_per_seg; |
1995 | dcc->undiscard_blks = 0; | 1999 | dcc->undiscard_blks = 0; |
1996 | dcc->next_pos = 0; | 2000 | dcc->next_pos = 0; |
1997 | dcc->root = RB_ROOT; | 2001 | dcc->root = RB_ROOT_CACHED; |
1998 | dcc->rbtree_check = false; | 2002 | dcc->rbtree_check = false; |
1999 | 2003 | ||
2000 | init_waitqueue_head(&dcc->discard_wait_queue); | 2004 | init_waitqueue_head(&dcc->discard_wait_queue); |
@@ -2658,7 +2662,7 @@ next: | |||
2658 | NULL, start, | 2662 | NULL, start, |
2659 | (struct rb_entry **)&prev_dc, | 2663 | (struct rb_entry **)&prev_dc, |
2660 | (struct rb_entry **)&next_dc, | 2664 | (struct rb_entry **)&next_dc, |
2661 | &insert_p, &insert_parent, true); | 2665 | &insert_p, &insert_parent, true, NULL); |
2662 | if (!dc) | 2666 | if (!dc) |
2663 | dc = next_dc; | 2667 | dc = next_dc; |
2664 | 2668 | ||