diff options
Diffstat (limited to 'fs/f2fs/extent_cache.c')
| -rw-r--r-- | fs/f2fs/extent_cache.c | 49 |
1 files changed, 21 insertions, 28 deletions
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index b37184f720e8..4dee2be9a648 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c | |||
| @@ -68,13 +68,13 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode) | |||
| 68 | et->root = RB_ROOT; | 68 | et->root = RB_ROOT; |
| 69 | et->cached_en = NULL; | 69 | et->cached_en = NULL; |
| 70 | rwlock_init(&et->lock); | 70 | rwlock_init(&et->lock); |
| 71 | atomic_set(&et->refcount, 0); | 71 | INIT_LIST_HEAD(&et->list); |
| 72 | et->count = 0; | 72 | et->count = 0; |
| 73 | atomic_inc(&sbi->total_ext_tree); | 73 | atomic_inc(&sbi->total_ext_tree); |
| 74 | } else { | 74 | } else { |
| 75 | atomic_dec(&sbi->total_zombie_tree); | 75 | atomic_dec(&sbi->total_zombie_tree); |
| 76 | list_del_init(&et->list); | ||
| 76 | } | 77 | } |
| 77 | atomic_inc(&et->refcount); | ||
| 78 | up_write(&sbi->extent_tree_lock); | 78 | up_write(&sbi->extent_tree_lock); |
| 79 | 79 | ||
| 80 | /* never died until evict_inode */ | 80 | /* never died until evict_inode */ |
| @@ -551,9 +551,9 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, | |||
| 551 | unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) | 551 | unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) |
| 552 | { | 552 | { |
| 553 | struct extent_tree *treevec[EXT_TREE_VEC_SIZE]; | 553 | struct extent_tree *treevec[EXT_TREE_VEC_SIZE]; |
| 554 | struct extent_tree *et, *next; | ||
| 554 | struct extent_node *en, *tmp; | 555 | struct extent_node *en, *tmp; |
| 555 | unsigned long ino = F2FS_ROOT_INO(sbi); | 556 | unsigned long ino = F2FS_ROOT_INO(sbi); |
| 556 | struct radix_tree_root *root = &sbi->extent_tree_root; | ||
| 557 | unsigned int found; | 557 | unsigned int found; |
| 558 | unsigned int node_cnt = 0, tree_cnt = 0; | 558 | unsigned int node_cnt = 0, tree_cnt = 0; |
| 559 | int remained; | 559 | int remained; |
| @@ -569,29 +569,20 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) | |||
| 569 | goto out; | 569 | goto out; |
| 570 | 570 | ||
| 571 | /* 1. remove unreferenced extent tree */ | 571 | /* 1. remove unreferenced extent tree */ |
| 572 | while ((found = radix_tree_gang_lookup(root, | 572 | list_for_each_entry_safe(et, next, &sbi->zombie_list, list) { |
| 573 | (void **)treevec, ino, EXT_TREE_VEC_SIZE))) { | 573 | write_lock(&et->lock); |
| 574 | unsigned i; | 574 | node_cnt += __free_extent_tree(sbi, et, true); |
| 575 | 575 | write_unlock(&et->lock); | |
| 576 | ino = treevec[found - 1]->ino + 1; | ||
| 577 | for (i = 0; i < found; i++) { | ||
| 578 | struct extent_tree *et = treevec[i]; | ||
| 579 | |||
| 580 | if (!atomic_read(&et->refcount)) { | ||
| 581 | write_lock(&et->lock); | ||
| 582 | node_cnt += __free_extent_tree(sbi, et, true); | ||
| 583 | write_unlock(&et->lock); | ||
| 584 | 576 | ||
| 585 | radix_tree_delete(root, et->ino); | 577 | list_del_init(&et->list); |
| 586 | kmem_cache_free(extent_tree_slab, et); | 578 | radix_tree_delete(&sbi->extent_tree_root, et->ino); |
| 587 | atomic_dec(&sbi->total_ext_tree); | 579 | kmem_cache_free(extent_tree_slab, et); |
| 588 | atomic_dec(&sbi->total_zombie_tree); | 580 | atomic_dec(&sbi->total_ext_tree); |
| 589 | tree_cnt++; | 581 | atomic_dec(&sbi->total_zombie_tree); |
| 582 | tree_cnt++; | ||
| 590 | 583 | ||
| 591 | if (node_cnt + tree_cnt >= nr_shrink) | 584 | if (node_cnt + tree_cnt >= nr_shrink) |
| 592 | goto unlock_out; | 585 | goto unlock_out; |
| 593 | } | ||
| 594 | } | ||
| 595 | } | 586 | } |
| 596 | up_write(&sbi->extent_tree_lock); | 587 | up_write(&sbi->extent_tree_lock); |
| 597 | 588 | ||
| @@ -619,7 +610,7 @@ free_node: | |||
| 619 | */ | 610 | */ |
| 620 | ino = F2FS_ROOT_INO(sbi); | 611 | ino = F2FS_ROOT_INO(sbi); |
| 621 | 612 | ||
| 622 | while ((found = radix_tree_gang_lookup(root, | 613 | while ((found = radix_tree_gang_lookup(&sbi->extent_tree_root, |
| 623 | (void **)treevec, ino, EXT_TREE_VEC_SIZE))) { | 614 | (void **)treevec, ino, EXT_TREE_VEC_SIZE))) { |
| 624 | unsigned i; | 615 | unsigned i; |
| 625 | 616 | ||
| @@ -670,8 +661,10 @@ void f2fs_destroy_extent_tree(struct inode *inode) | |||
| 670 | return; | 661 | return; |
| 671 | 662 | ||
| 672 | if (inode->i_nlink && !is_bad_inode(inode) && et->count) { | 663 | if (inode->i_nlink && !is_bad_inode(inode) && et->count) { |
| 673 | atomic_dec(&et->refcount); | 664 | down_write(&sbi->extent_tree_lock); |
| 665 | list_add_tail(&et->list, &sbi->zombie_list); | ||
| 674 | atomic_inc(&sbi->total_zombie_tree); | 666 | atomic_inc(&sbi->total_zombie_tree); |
| 667 | up_write(&sbi->extent_tree_lock); | ||
| 675 | return; | 668 | return; |
| 676 | } | 669 | } |
| 677 | 670 | ||
| @@ -680,8 +673,7 @@ void f2fs_destroy_extent_tree(struct inode *inode) | |||
| 680 | 673 | ||
| 681 | /* delete extent tree entry in radix tree */ | 674 | /* delete extent tree entry in radix tree */ |
| 682 | down_write(&sbi->extent_tree_lock); | 675 | down_write(&sbi->extent_tree_lock); |
| 683 | atomic_dec(&et->refcount); | 676 | f2fs_bug_on(sbi, et->count); |
| 684 | f2fs_bug_on(sbi, atomic_read(&et->refcount) || et->count); | ||
| 685 | radix_tree_delete(&sbi->extent_tree_root, inode->i_ino); | 677 | radix_tree_delete(&sbi->extent_tree_root, inode->i_ino); |
| 686 | kmem_cache_free(extent_tree_slab, et); | 678 | kmem_cache_free(extent_tree_slab, et); |
| 687 | atomic_dec(&sbi->total_ext_tree); | 679 | atomic_dec(&sbi->total_ext_tree); |
| @@ -737,6 +729,7 @@ void init_extent_cache_info(struct f2fs_sb_info *sbi) | |||
| 737 | INIT_LIST_HEAD(&sbi->extent_list); | 729 | INIT_LIST_HEAD(&sbi->extent_list); |
| 738 | spin_lock_init(&sbi->extent_lock); | 730 | spin_lock_init(&sbi->extent_lock); |
| 739 | atomic_set(&sbi->total_ext_tree, 0); | 731 | atomic_set(&sbi->total_ext_tree, 0); |
| 732 | INIT_LIST_HEAD(&sbi->zombie_list); | ||
| 740 | atomic_set(&sbi->total_zombie_tree, 0); | 733 | atomic_set(&sbi->total_zombie_tree, 0); |
| 741 | atomic_set(&sbi->total_ext_node, 0); | 734 | atomic_set(&sbi->total_ext_node, 0); |
| 742 | } | 735 | } |
