]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - fs/f2fs/node.c
f2fs: avoid race condition for shrinker count
[mirror_ubuntu-hirsute-kernel.git] / fs / f2fs / node.c
index 42394de6c7eb1d76a7f13b565b9c3d73d3ad6674..e65d73293a3f635e8ca37c33944cd602f88d5829 100644 (file)
@@ -62,8 +62,8 @@ bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type)
                                sizeof(struct free_nid)) >> PAGE_SHIFT;
                res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 2);
        } else if (type == NAT_ENTRIES) {
-               mem_size = (nm_i->nat_cnt * sizeof(struct nat_entry)) >>
-                                                       PAGE_SHIFT;
+               mem_size = (nm_i->nat_cnt[TOTAL_NAT] *
+                               sizeof(struct nat_entry)) >> PAGE_SHIFT;
                res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 2);
                if (excess_cached_nats(sbi))
                        res = false;
@@ -177,7 +177,8 @@ static struct nat_entry *__init_nat_entry(struct f2fs_nm_info *nm_i,
        list_add_tail(&ne->list, &nm_i->nat_entries);
        spin_unlock(&nm_i->nat_list_lock);
 
-       nm_i->nat_cnt++;
+       nm_i->nat_cnt[TOTAL_NAT]++;
+       nm_i->nat_cnt[RECLAIMABLE_NAT]++;
        return ne;
 }
 
@@ -207,7 +208,8 @@ static unsigned int __gang_lookup_nat_cache(struct f2fs_nm_info *nm_i,
 static void __del_from_nat_cache(struct f2fs_nm_info *nm_i, struct nat_entry *e)
 {
        radix_tree_delete(&nm_i->nat_root, nat_get_nid(e));
-       nm_i->nat_cnt--;
+       nm_i->nat_cnt[TOTAL_NAT]--;
+       nm_i->nat_cnt[RECLAIMABLE_NAT]--;
        __free_nat_entry(e);
 }
 
@@ -253,7 +255,8 @@ static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i,
        if (get_nat_flag(ne, IS_DIRTY))
                goto refresh_list;
 
-       nm_i->dirty_nat_cnt++;
+       nm_i->nat_cnt[DIRTY_NAT]++;
+       nm_i->nat_cnt[RECLAIMABLE_NAT]--;
        set_nat_flag(ne, IS_DIRTY, true);
 refresh_list:
        spin_lock(&nm_i->nat_list_lock);
@@ -273,7 +276,8 @@ static void __clear_nat_cache_dirty(struct f2fs_nm_info *nm_i,
 
        set_nat_flag(ne, IS_DIRTY, false);
        set->entry_cnt--;
-       nm_i->dirty_nat_cnt--;
+       nm_i->nat_cnt[DIRTY_NAT]--;
+       nm_i->nat_cnt[RECLAIMABLE_NAT]++;
 }
 
 static unsigned int __gang_lookup_nat_set(struct f2fs_nm_info *nm_i,
@@ -2944,14 +2948,17 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
        LIST_HEAD(sets);
        int err = 0;
 
-       /* during unmount, let's flush nat_bits before checking dirty_nat_cnt */
+       /*
+        * during unmount, let's flush nat_bits before checking
+        * nat_cnt[DIRTY_NAT].
+        */
        if (enabled_nat_bits(sbi, cpc)) {
                down_write(&nm_i->nat_tree_lock);
                remove_nats_in_journal(sbi);
                up_write(&nm_i->nat_tree_lock);
        }
 
-       if (!nm_i->dirty_nat_cnt)
+       if (!nm_i->nat_cnt[DIRTY_NAT])
                return 0;
 
        down_write(&nm_i->nat_tree_lock);
@@ -2962,7 +2969,8 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
         * into nat entry set.
         */
        if (enabled_nat_bits(sbi, cpc) ||
-               !__has_cursum_space(journal, nm_i->dirty_nat_cnt, NAT_JOURNAL))
+               !__has_cursum_space(journal,
+                       nm_i->nat_cnt[DIRTY_NAT], NAT_JOURNAL))
                remove_nats_in_journal(sbi);
 
        while ((found = __gang_lookup_nat_set(nm_i,
@@ -3086,7 +3094,6 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
                                                F2FS_RESERVED_NODE_NUM;
        nm_i->nid_cnt[FREE_NID] = 0;
        nm_i->nid_cnt[PREALLOC_NID] = 0;
-       nm_i->nat_cnt = 0;
        nm_i->ram_thresh = DEF_RAM_THRESHOLD;
        nm_i->ra_nid_pages = DEF_RA_NID_PAGES;
        nm_i->dirty_nats_ratio = DEF_DIRTY_NAT_RATIO_THRESHOLD;
@@ -3220,7 +3227,7 @@ void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi)
                        __del_from_nat_cache(nm_i, natvec[idx]);
                }
        }
-       f2fs_bug_on(sbi, nm_i->nat_cnt);
+       f2fs_bug_on(sbi, nm_i->nat_cnt[TOTAL_NAT]);
 
        /* destroy nat set cache */
        nid = 0;