aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/extent_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/f2fs/extent_cache.c')
-rw-r--r--fs/f2fs/extent_cache.c176
1 files changed, 75 insertions, 101 deletions
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
index ccd5c636d3fe..c859bb044728 100644
--- a/fs/f2fs/extent_cache.c
+++ b/fs/f2fs/extent_cache.c
@@ -33,6 +33,7 @@ static struct extent_node *__attach_extent_node(struct f2fs_sb_info *sbi,
33 33
34 en->ei = *ei; 34 en->ei = *ei;
35 INIT_LIST_HEAD(&en->list); 35 INIT_LIST_HEAD(&en->list);
36 en->et = et;
36 37
37 rb_link_node(&en->rb_node, parent, p); 38 rb_link_node(&en->rb_node, parent, p);
38 rb_insert_color(&en->rb_node, &et->root); 39 rb_insert_color(&en->rb_node, &et->root);
@@ -50,6 +51,24 @@ static void __detach_extent_node(struct f2fs_sb_info *sbi,
50 51
51 if (et->cached_en == en) 52 if (et->cached_en == en)
52 et->cached_en = NULL; 53 et->cached_en = NULL;
54 kmem_cache_free(extent_node_slab, en);
55}
56
57/*
58 * Flow to release an extent_node:
59 * 1. list_del_init
60 * 2. __detach_extent_node
61 * 3. kmem_cache_free.
62 */
63static void __release_extent_node(struct f2fs_sb_info *sbi,
64 struct extent_tree *et, struct extent_node *en)
65{
66 spin_lock(&sbi->extent_lock);
67 f2fs_bug_on(sbi, list_empty(&en->list));
68 list_del_init(&en->list);
69 spin_unlock(&sbi->extent_lock);
70
71 __detach_extent_node(sbi, et, en);
53} 72}
54 73
55static struct extent_tree *__grab_extent_tree(struct inode *inode) 74static struct extent_tree *__grab_extent_tree(struct inode *inode)
@@ -129,7 +148,7 @@ static struct extent_node *__init_extent_tree(struct f2fs_sb_info *sbi,
129} 148}
130 149
131static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi, 150static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi,
132 struct extent_tree *et, bool free_all) 151 struct extent_tree *et)
133{ 152{
134 struct rb_node *node, *next; 153 struct rb_node *node, *next;
135 struct extent_node *en; 154 struct extent_node *en;
@@ -139,18 +158,7 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi,
139 while (node) { 158 while (node) {
140 next = rb_next(node); 159 next = rb_next(node);
141 en = rb_entry(node, struct extent_node, rb_node); 160 en = rb_entry(node, struct extent_node, rb_node);
142 161 __release_extent_node(sbi, et, en);
143 if (free_all) {
144 spin_lock(&sbi->extent_lock);
145 if (!list_empty(&en->list))
146 list_del_init(&en->list);
147 spin_unlock(&sbi->extent_lock);
148 }
149
150 if (free_all || list_empty(&en->list)) {
151 __detach_extent_node(sbi, et, en);
152 kmem_cache_free(extent_node_slab, en);
153 }
154 node = next; 162 node = next;
155 } 163 }
156 164
@@ -232,9 +240,10 @@ static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs,
232 if (en) { 240 if (en) {
233 *ei = en->ei; 241 *ei = en->ei;
234 spin_lock(&sbi->extent_lock); 242 spin_lock(&sbi->extent_lock);
235 if (!list_empty(&en->list)) 243 if (!list_empty(&en->list)) {
236 list_move_tail(&en->list, &sbi->extent_list); 244 list_move_tail(&en->list, &sbi->extent_list);
237 et->cached_en = en; 245 et->cached_en = en;
246 }
238 spin_unlock(&sbi->extent_lock); 247 spin_unlock(&sbi->extent_lock);
239 ret = true; 248 ret = true;
240 } 249 }
@@ -329,7 +338,6 @@ lookup_neighbors:
329 338
330static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi, 339static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,
331 struct extent_tree *et, struct extent_info *ei, 340 struct extent_tree *et, struct extent_info *ei,
332 struct extent_node **den,
333 struct extent_node *prev_ex, 341 struct extent_node *prev_ex,
334 struct extent_node *next_ex) 342 struct extent_node *next_ex)
335{ 343{
@@ -342,20 +350,25 @@ static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,
342 } 350 }
343 351
344 if (next_ex && __is_front_mergeable(ei, &next_ex->ei)) { 352 if (next_ex && __is_front_mergeable(ei, &next_ex->ei)) {
345 if (en) { 353 if (en)
346 __detach_extent_node(sbi, et, prev_ex); 354 __release_extent_node(sbi, et, prev_ex);
347 *den = prev_ex;
348 }
349 next_ex->ei.fofs = ei->fofs; 355 next_ex->ei.fofs = ei->fofs;
350 next_ex->ei.blk = ei->blk; 356 next_ex->ei.blk = ei->blk;
351 next_ex->ei.len += ei->len; 357 next_ex->ei.len += ei->len;
352 en = next_ex; 358 en = next_ex;
353 } 359 }
354 360
355 if (en) { 361 if (!en)
356 __try_update_largest_extent(et, en); 362 return NULL;
363
364 __try_update_largest_extent(et, en);
365
366 spin_lock(&sbi->extent_lock);
367 if (!list_empty(&en->list)) {
368 list_move_tail(&en->list, &sbi->extent_list);
357 et->cached_en = en; 369 et->cached_en = en;
358 } 370 }
371 spin_unlock(&sbi->extent_lock);
359 return en; 372 return en;
360} 373}
361 374
@@ -391,7 +404,12 @@ do_insert:
391 return NULL; 404 return NULL;
392 405
393 __try_update_largest_extent(et, en); 406 __try_update_largest_extent(et, en);
407
408 /* update in global extent list */
409 spin_lock(&sbi->extent_lock);
410 list_add_tail(&en->list, &sbi->extent_list);
394 et->cached_en = en; 411 et->cached_en = en;
412 spin_unlock(&sbi->extent_lock);
395 return en; 413 return en;
396} 414}
397 415
@@ -479,7 +497,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
479 if (parts) 497 if (parts)
480 __try_update_largest_extent(et, en); 498 __try_update_largest_extent(et, en);
481 else 499 else
482 __detach_extent_node(sbi, et, en); 500 __release_extent_node(sbi, et, en);
483 501
484 /* 502 /*
485 * if original extent is split into zero or two parts, extent 503 * if original extent is split into zero or two parts, extent
@@ -490,31 +508,15 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
490 insert_p = NULL; 508 insert_p = NULL;
491 insert_parent = NULL; 509 insert_parent = NULL;
492 } 510 }
493
494 /* update in global extent list */
495 spin_lock(&sbi->extent_lock);
496 if (!parts && !list_empty(&en->list))
497 list_del(&en->list);
498 if (en1)
499 list_add_tail(&en1->list, &sbi->extent_list);
500 spin_unlock(&sbi->extent_lock);
501
502 /* release extent node */
503 if (!parts)
504 kmem_cache_free(extent_node_slab, en);
505
506 en = next_en; 511 en = next_en;
507 } 512 }
508 513
509 /* 3. update extent in extent cache */ 514 /* 3. update extent in extent cache */
510 if (blkaddr) { 515 if (blkaddr) {
511 struct extent_node *den = NULL;
512 516
513 set_extent_info(&ei, fofs, blkaddr, len); 517 set_extent_info(&ei, fofs, blkaddr, len);
514 en1 = __try_merge_extent_node(sbi, et, &ei, &den, 518 if (!__try_merge_extent_node(sbi, et, &ei, prev_en, next_en))
515 prev_en, next_en); 519 __insert_extent_tree(sbi, et, &ei,
516 if (!en1)
517 en1 = __insert_extent_tree(sbi, et, &ei,
518 insert_p, insert_parent); 520 insert_p, insert_parent);
519 521
520 /* give up extent_cache, if split and small updates happen */ 522 /* give up extent_cache, if split and small updates happen */
@@ -524,24 +526,10 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
524 et->largest.len = 0; 526 et->largest.len = 0;
525 set_inode_flag(F2FS_I(inode), FI_NO_EXTENT); 527 set_inode_flag(F2FS_I(inode), FI_NO_EXTENT);
526 } 528 }
527
528 spin_lock(&sbi->extent_lock);
529 if (en1) {
530 if (list_empty(&en1->list))
531 list_add_tail(&en1->list, &sbi->extent_list);
532 else
533 list_move_tail(&en1->list, &sbi->extent_list);
534 }
535 if (den && !list_empty(&den->list))
536 list_del(&den->list);
537 spin_unlock(&sbi->extent_lock);
538
539 if (den)
540 kmem_cache_free(extent_node_slab, den);
541 } 529 }
542 530
543 if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT)) 531 if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT))
544 __free_extent_tree(sbi, et, true); 532 __free_extent_tree(sbi, et);
545 533
546 write_unlock(&et->lock); 534 write_unlock(&et->lock);
547 535
@@ -550,14 +538,10 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
550 538
551unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) 539unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink)
552{ 540{
553 struct extent_tree *treevec[EXT_TREE_VEC_SIZE];
554 struct extent_tree *et, *next; 541 struct extent_tree *et, *next;
555 struct extent_node *en, *tmp; 542 struct extent_node *en;
556 unsigned long ino = F2FS_ROOT_INO(sbi);
557 unsigned int found;
558 unsigned int node_cnt = 0, tree_cnt = 0; 543 unsigned int node_cnt = 0, tree_cnt = 0;
559 int remained; 544 int remained;
560 bool do_free = false;
561 545
562 if (!test_opt(sbi, EXTENT_CACHE)) 546 if (!test_opt(sbi, EXTENT_CACHE))
563 return 0; 547 return 0;
@@ -572,10 +556,10 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink)
572 list_for_each_entry_safe(et, next, &sbi->zombie_list, list) { 556 list_for_each_entry_safe(et, next, &sbi->zombie_list, list) {
573 if (atomic_read(&et->node_cnt)) { 557 if (atomic_read(&et->node_cnt)) {
574 write_lock(&et->lock); 558 write_lock(&et->lock);
575 node_cnt += __free_extent_tree(sbi, et, true); 559 node_cnt += __free_extent_tree(sbi, et);
576 write_unlock(&et->lock); 560 write_unlock(&et->lock);
577 } 561 }
578 562 f2fs_bug_on(sbi, atomic_read(&et->node_cnt));
579 list_del_init(&et->list); 563 list_del_init(&et->list);
580 radix_tree_delete(&sbi->extent_tree_root, et->ino); 564 radix_tree_delete(&sbi->extent_tree_root, et->ino);
581 kmem_cache_free(extent_tree_slab, et); 565 kmem_cache_free(extent_tree_slab, et);
@@ -585,6 +569,7 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink)
585 569
586 if (node_cnt + tree_cnt >= nr_shrink) 570 if (node_cnt + tree_cnt >= nr_shrink)
587 goto unlock_out; 571 goto unlock_out;
572 cond_resched();
588 } 573 }
589 up_write(&sbi->extent_tree_lock); 574 up_write(&sbi->extent_tree_lock);
590 575
@@ -596,42 +581,29 @@ free_node:
596 remained = nr_shrink - (node_cnt + tree_cnt); 581 remained = nr_shrink - (node_cnt + tree_cnt);
597 582
598 spin_lock(&sbi->extent_lock); 583 spin_lock(&sbi->extent_lock);
599 list_for_each_entry_safe(en, tmp, &sbi->extent_list, list) { 584 for (; remained > 0; remained--) {
600 if (!remained--) 585 if (list_empty(&sbi->extent_list))
601 break; 586 break;
602 list_del_init(&en->list); 587 en = list_first_entry(&sbi->extent_list,
603 do_free = true; 588 struct extent_node, list);
604 } 589 et = en->et;
605 spin_unlock(&sbi->extent_lock); 590 if (!write_trylock(&et->lock)) {
606 591 /* refresh this extent node's position in extent list */
607 if (do_free == false) 592 list_move_tail(&en->list, &sbi->extent_list);
608 goto unlock_out; 593 continue;
609 594 }
610 /*
611 * reset ino for searching victims from beginning of global extent tree.
612 */
613 ino = F2FS_ROOT_INO(sbi);
614
615 while ((found = radix_tree_gang_lookup(&sbi->extent_tree_root,
616 (void **)treevec, ino, EXT_TREE_VEC_SIZE))) {
617 unsigned i;
618
619 ino = treevec[found - 1]->ino + 1;
620 for (i = 0; i < found; i++) {
621 struct extent_tree *et = treevec[i];
622 595
623 if (!atomic_read(&et->node_cnt)) 596 list_del_init(&en->list);
624 continue; 597 spin_unlock(&sbi->extent_lock);
625 598
626 if (write_trylock(&et->lock)) { 599 __detach_extent_node(sbi, et, en);
627 node_cnt += __free_extent_tree(sbi, et, false);
628 write_unlock(&et->lock);
629 }
630 600
631 if (node_cnt + tree_cnt >= nr_shrink) 601 write_unlock(&et->lock);
632 goto unlock_out; 602 node_cnt++;
633 } 603 spin_lock(&sbi->extent_lock);
634 } 604 }
605 spin_unlock(&sbi->extent_lock);
606
635unlock_out: 607unlock_out:
636 up_write(&sbi->extent_tree_lock); 608 up_write(&sbi->extent_tree_lock);
637out: 609out:
@@ -650,7 +622,7 @@ unsigned int f2fs_destroy_extent_node(struct inode *inode)
650 return 0; 622 return 0;
651 623
652 write_lock(&et->lock); 624 write_lock(&et->lock);
653 node_cnt = __free_extent_tree(sbi, et, true); 625 node_cnt = __free_extent_tree(sbi, et);
654 write_unlock(&et->lock); 626 write_unlock(&et->lock);
655 627
656 return node_cnt; 628 return node_cnt;
@@ -701,19 +673,21 @@ bool f2fs_lookup_extent_cache(struct inode *inode, pgoff_t pgofs,
701 673
702void f2fs_update_extent_cache(struct dnode_of_data *dn) 674void f2fs_update_extent_cache(struct dnode_of_data *dn)
703{ 675{
704 struct f2fs_inode_info *fi = F2FS_I(dn->inode);
705 pgoff_t fofs; 676 pgoff_t fofs;
677 block_t blkaddr;
706 678
707 if (!f2fs_may_extent_tree(dn->inode)) 679 if (!f2fs_may_extent_tree(dn->inode))
708 return; 680 return;
709 681
710 f2fs_bug_on(F2FS_I_SB(dn->inode), dn->data_blkaddr == NEW_ADDR); 682 if (dn->data_blkaddr == NEW_ADDR)
711 683 blkaddr = NULL_ADDR;
684 else
685 blkaddr = dn->data_blkaddr;
712 686
713 fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) + 687 fofs = start_bidx_of_node(ofs_of_node(dn->node_page), dn->inode) +
714 dn->ofs_in_node; 688 dn->ofs_in_node;
715 689
716 if (f2fs_update_extent_tree_range(dn->inode, fofs, dn->data_blkaddr, 1)) 690 if (f2fs_update_extent_tree_range(dn->inode, fofs, blkaddr, 1))
717 sync_inode_page(dn); 691 sync_inode_page(dn);
718} 692}
719 693