]> www.infradead.org Git - users/willy/xarray.git/commitdiff
f2fs: Convert nat_root to XArray
authorMatthew Wilcox <willy@infradead.org>
Thu, 18 Oct 2018 19:06:36 +0000 (15:06 -0400)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 8 Aug 2019 14:29:40 +0000 (10:29 -0400)
Leave the locking unchanged, although I suspect nat_tree_lock
could probably now be removed or at least narrowed in scope.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
fs/f2fs/f2fs.h
fs/f2fs/node.c
fs/f2fs/node.h

index 40415afae9cba37aa410bf487e3d0bc4888bea43..26f6f31f0f08333853a3291cc7015c4088dcc2c1 100644 (file)
@@ -789,7 +789,7 @@ struct f2fs_nm_info {
        unsigned int dirty_nats_ratio;  /* control dirty nats ratio threshold */
 
        /* NAT cache management */
-       struct radix_tree_root nat_root;/* root of the nat entry cache */
+       struct xarray nat_cache;
        struct xarray nat_set_cache;
        struct rw_semaphore nat_tree_lock;      /* protect nat_tree_lock */
        struct list_head nat_entries;   /* cached nat entry list (clean) */
@@ -2225,13 +2225,6 @@ static inline bool is_idle(struct f2fs_sb_info *sbi, int type)
        return f2fs_time_over(sbi, type);
 }
 
-static inline void f2fs_radix_tree_insert(struct radix_tree_root *root,
-                               unsigned long index, void *item)
-{
-       while (radix_tree_insert(root, index, item))
-               cond_resched();
-}
-
 #define RAW_IS_INODE(p)        ((p)->footer.nid == (p)->footer.ino)
 
 static inline bool IS_INODE(struct page *page)
index d83c6e990637f6034ac5f7453c9b2533d645031d..bd2384e2a56cd7bcf75699439d719f46c5df01c9 100644 (file)
@@ -158,11 +158,9 @@ static void __free_nat_entry(struct nat_entry *e)
 
 /* must be locked by nat_tree_lock */
 static struct nat_entry *__init_nat_entry(struct f2fs_nm_info *nm_i,
-       struct nat_entry *ne, struct f2fs_nat_entry *raw_ne, bool no_fail)
+       struct nat_entry *ne, struct f2fs_nat_entry *raw_ne, gfp_t gfp)
 {
-       if (no_fail)
-               f2fs_radix_tree_insert(&nm_i->nat_root, nat_get_nid(ne), ne);
-       else if (radix_tree_insert(&nm_i->nat_root, nat_get_nid(ne), ne))
+       if (xa_store(&nm_i->nat_cache, nat_get_nid(ne), ne, gfp) != NULL)
                return NULL;
 
        if (raw_ne)
@@ -180,7 +178,7 @@ static struct nat_entry *__lookup_nat_cache(struct f2fs_nm_info *nm_i, nid_t n)
 {
        struct nat_entry *ne;
 
-       ne = radix_tree_lookup(&nm_i->nat_root, n);
+       ne = xa_load(&nm_i->nat_cache, n);
 
        /* for recent accessed nat entry, move it to tail of lru list */
        if (ne && !get_nat_flag(ne, IS_DIRTY)) {
@@ -193,15 +191,9 @@ static struct nat_entry *__lookup_nat_cache(struct f2fs_nm_info *nm_i, nid_t n)
        return ne;
 }
 
-static unsigned int __gang_lookup_nat_cache(struct f2fs_nm_info *nm_i,
-               nid_t start, unsigned int nr, struct nat_entry **ep)
-{
-       return radix_tree_gang_lookup(&nm_i->nat_root, (void **)ep, start, nr);
-}
-
 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));
+       xa_erase(&nm_i->nat_cache, nat_get_nid(e));
        nm_i->nat_cnt--;
        __free_nat_entry(e);
 }
@@ -399,7 +391,7 @@ static void cache_nat_entry(struct f2fs_sb_info *sbi, nid_t nid,
        down_write(&nm_i->nat_tree_lock);
        e = __lookup_nat_cache(nm_i, nid);
        if (!e)
-               e = __init_nat_entry(nm_i, new, ne, false);
+               e = __init_nat_entry(nm_i, new, ne, GFP_NOIO);
        else
                f2fs_bug_on(sbi, nat_get_ino(e) != le32_to_cpu(ne->ino) ||
                                nat_get_blkaddr(e) !=
@@ -420,7 +412,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
        down_write(&nm_i->nat_tree_lock);
        e = __lookup_nat_cache(nm_i, ni->nid);
        if (!e) {
-               e = __init_nat_entry(nm_i, new, NULL, true);
+               e = __init_nat_entry(nm_i, new, NULL, GFP_NOIO | __GFP_NOFAIL);
                copy_node_info(&e->ni, ni);
                f2fs_bug_on(sbi, ni->blk_addr == NEW_ADDR);
        } else if (new_blkaddr == NEW_ADDR) {
@@ -2573,7 +2565,8 @@ static void remove_nats_in_journal(struct f2fs_sb_info *sbi)
                ne = __lookup_nat_cache(nm_i, nid);
                if (!ne) {
                        ne = __alloc_nat_entry(nid, true);
-                       __init_nat_entry(nm_i, ne, &raw_ne, true);
+                       __init_nat_entry(nm_i, ne, &raw_ne,
+                                               GFP_NOIO | __GFP_NOFAIL);
                }
 
                /*
@@ -2875,7 +2868,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
        nm_i->dirty_nats_ratio = DEF_DIRTY_NAT_RATIO_THRESHOLD;
 
        xa_init(&nm_i->free_nid_cache);
-       INIT_RADIX_TREE(&nm_i->nat_root, GFP_NOIO);
+       xa_init(&nm_i->nat_cache);
        xa_init(&nm_i->nat_set_cache);
        INIT_LIST_HEAD(&nm_i->nat_entries);
        spin_lock_init(&nm_i->nat_list_lock);
@@ -2967,11 +2960,9 @@ int f2fs_build_node_manager(struct f2fs_sb_info *sbi)
 void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
-       struct nat_entry *natvec[NATVEC_SIZE];
+       struct nat_entry *nat;
        struct nat_entry_set *set;
        unsigned long index;
-       nid_t nid = 0;
-       unsigned int found;
 
        if (!nm_i)
                return;
@@ -2981,19 +2972,14 @@ void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi)
 
        /* destroy nat cache */
        down_write(&nm_i->nat_tree_lock);
-       while ((found = __gang_lookup_nat_cache(nm_i,
-                                       nid, NATVEC_SIZE, natvec))) {
-               unsigned idx;
-
-               nid = nat_get_nid(natvec[found - 1]) + 1;
-               for (idx = 0; idx < found; idx++) {
-                       spin_lock(&nm_i->nat_list_lock);
-                       list_del(&natvec[idx]->list);
-                       spin_unlock(&nm_i->nat_list_lock);
+       xa_for_each(&nm_i->nat_cache, index, nat) {
+               spin_lock(&nm_i->nat_list_lock);
+               list_del(&nat->list);
+               spin_unlock(&nm_i->nat_list_lock);
 
-                       __del_from_nat_cache(nm_i, natvec[idx]);
-               }
+               __del_from_nat_cache(nm_i, nat);
        }
+       f2fs_bug_on(sbi, !xa_empty(&nm_i->nat_set_cache));
        f2fs_bug_on(sbi, nm_i->nat_cnt);
 
        /* destroy nat set cache */
index 649469a2feada08d37e218ef9fb7f4476c9e1cc7..49e7087bd02ed9e014b946585ca8641440cf1aff 100644 (file)
@@ -28,9 +28,6 @@
 /* control total # of nats */
 #define DEF_NAT_CACHE_THRESHOLD                        100000
 
-/* vector size for gang look-up from nat cache that consists of radix tree */
-#define NATVEC_SIZE    64
-
 /* return value for read_node_page */
 #define LOCKED_PAGE    1