Merge tag 'f2fs-for-5.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeu...
[linux-2.6-microblaze.git] / fs / f2fs / node.c
index 219506c..50b2874 100644 (file)
@@ -430,6 +430,10 @@ static void cache_nat_entry(struct f2fs_sb_info *sbi, nid_t nid,
        struct f2fs_nm_info *nm_i = NM_I(sbi);
        struct nat_entry *new, *e;
 
+       /* Let's mitigate lock contention of nat_tree_lock during checkpoint */
+       if (rwsem_is_locked(&sbi->cp_global_sem))
+               return;
+
        new = __alloc_nat_entry(sbi, nid, false);
        if (!new)
                return;
@@ -539,7 +543,7 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink)
 }
 
 int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
-                                               struct node_info *ni)
+                               struct node_info *ni, bool checkpoint_context)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
        struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
@@ -572,9 +576,10 @@ retry:
         * nat_tree_lock. Therefore, we should retry, if we failed to grab here
         * while not bothering checkpoint.
         */
-       if (!rwsem_is_locked(&sbi->cp_global_sem)) {
+       if (!rwsem_is_locked(&sbi->cp_global_sem) || checkpoint_context) {
                down_read(&curseg->journal_rwsem);
-       } else if (!down_read_trylock(&curseg->journal_rwsem)) {
+       } else if (rwsem_is_contended(&nm_i->nat_tree_lock) ||
+                               !down_read_trylock(&curseg->journal_rwsem)) {
                up_read(&nm_i->nat_tree_lock);
                goto retry;
        }
@@ -887,7 +892,7 @@ static int truncate_node(struct dnode_of_data *dn)
        int err;
        pgoff_t index;
 
-       err = f2fs_get_node_info(sbi, dn->nid, &ni);
+       err = f2fs_get_node_info(sbi, dn->nid, &ni, false);
        if (err)
                return err;
 
@@ -1286,7 +1291,7 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs)
                goto fail;
 
 #ifdef CONFIG_F2FS_CHECK_FS
-       err = f2fs_get_node_info(sbi, dn->nid, &new_ni);
+       err = f2fs_get_node_info(sbi, dn->nid, &new_ni, false);
        if (err) {
                dec_valid_node_count(sbi, dn->inode, !ofs);
                goto fail;
@@ -1348,7 +1353,7 @@ static int read_node_page(struct page *page, int op_flags)
                return LOCKED_PAGE;
        }
 
-       err = f2fs_get_node_info(sbi, page->index, &ni);
+       err = f2fs_get_node_info(sbi, page->index, &ni, false);
        if (err)
                return err;
 
@@ -1600,7 +1605,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
        nid = nid_of_node(page);
        f2fs_bug_on(sbi, page->index != nid);
 
-       if (f2fs_get_node_info(sbi, nid, &ni))
+       if (f2fs_get_node_info(sbi, nid, &ni, !do_balance))
                goto redirty_out;
 
        if (wbc->for_reclaim) {
@@ -2701,7 +2706,7 @@ int f2fs_recover_xattr_data(struct inode *inode, struct page *page)
                goto recover_xnid;
 
        /* 1: invalidate the previous xattr nid */
-       err = f2fs_get_node_info(sbi, prev_xnid, &ni);
+       err = f2fs_get_node_info(sbi, prev_xnid, &ni, false);
        if (err)
                return err;
 
@@ -2741,7 +2746,7 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
        struct page *ipage;
        int err;
 
-       err = f2fs_get_node_info(sbi, ino, &old_ni);
+       err = f2fs_get_node_info(sbi, ino, &old_ni, false);
        if (err)
                return err;