#define MAX_DIR_RA_PAGES       4       /* maximum ra pages of dir */
 
+/* dirty segments threshold for triggering CP */
+#define DEFAULT_DIRTY_THRESHOLD                4
+
 /* for in-memory extent cache entry */
 #define F2FS_MIN_EXTENT_LEN    64      /* minimum extent length */
 
 
        return NM_I(sbi)->nat_cnt[TOTAL_NAT] >= DEF_NAT_CACHE_THRESHOLD;
 }
 
-static inline bool excess_dirty_nodes(struct f2fs_sb_info *sbi)
-{
-       return get_pages(sbi, F2FS_DIRTY_NODES) >= sbi->blocks_per_seg * 8;
-}
-
 enum mem_type {
        FREE_NIDS,      /* indicates the free nid list */
        NAT_ENTRIES,    /* indicates the cached nat entry */
 
        }
 }
 
+static inline bool excess_dirty_threshold(struct f2fs_sb_info *sbi)
+{
+       int factor = rwsem_is_locked(&sbi->cp_rwsem) ? 3 : 2;
+       unsigned int dents = get_pages(sbi, F2FS_DIRTY_DENTS);
+       unsigned int qdata = get_pages(sbi, F2FS_DIRTY_QDATA);
+       unsigned int nodes = get_pages(sbi, F2FS_DIRTY_NODES);
+       unsigned int meta = get_pages(sbi, F2FS_DIRTY_META);
+       unsigned int imeta = get_pages(sbi, F2FS_DIRTY_IMETA);
+       unsigned int threshold = sbi->blocks_per_seg * factor *
+                                       DEFAULT_DIRTY_THRESHOLD;
+       unsigned int global_threshold = threshold * 3 / 2;
+
+       if (dents >= threshold || qdata >= threshold ||
+               nodes >= threshold || meta >= threshold ||
+               imeta >= threshold)
+               return true;
+       return dents + qdata + nodes + meta + imeta >  global_threshold;
+}
+
 void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi, bool from_bg)
 {
        if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
        else
                f2fs_build_free_nids(sbi, false, false);
 
-       if (excess_dirty_nats(sbi) || excess_dirty_nodes(sbi) ||
-               excess_prefree_segs(sbi))
+       if (excess_dirty_nats(sbi) || excess_dirty_threshold(sbi) ||
+               excess_prefree_segs(sbi) || !f2fs_space_for_roll_forward(sbi))
                goto do_sync;
 
        /* there is background inflight IO or foreground operation recently */