Merge tag 'f2fs-for-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeu...
[linux-2.6-microblaze.git] / fs / f2fs / f2fs.h
index 115204f..f4e094e 100644 (file)
@@ -44,6 +44,8 @@
 enum {
        FAULT_KMALLOC,
        FAULT_PAGE_ALLOC,
+       FAULT_PAGE_GET,
+       FAULT_ALLOC_BIO,
        FAULT_ALLOC_NID,
        FAULT_ORPHAN,
        FAULT_BLOCK,
@@ -91,6 +93,7 @@ extern char *fault_name[FAULT_MAX];
 #define F2FS_MOUNT_GRPQUOTA            0x00100000
 #define F2FS_MOUNT_PRJQUOTA            0x00200000
 #define F2FS_MOUNT_QUOTA               0x00400000
+#define F2FS_MOUNT_INLINE_XATTR_SIZE   0x00800000
 
 #define clear_opt(sbi, option) ((sbi)->mount_opt.opt &= ~F2FS_MOUNT_##option)
 #define set_opt(sbi, option)   ((sbi)->mount_opt.opt |= F2FS_MOUNT_##option)
@@ -116,6 +119,8 @@ struct f2fs_mount_info {
 #define F2FS_FEATURE_EXTRA_ATTR                0x0008
 #define F2FS_FEATURE_PRJQUOTA          0x0010
 #define F2FS_FEATURE_INODE_CHKSUM      0x0020
+#define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR     0x0040
+#define F2FS_FEATURE_QUOTA_INO         0x0080
 
 #define F2FS_HAS_FEATURE(sb, mask)                                     \
        ((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -145,7 +150,7 @@ enum {
 #define BATCHED_TRIM_BLOCKS(sbi)       \
                (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg)
 #define MAX_DISCARD_BLOCKS(sbi)                BLKS_PER_SEC(sbi)
-#define DISCARD_ISSUE_RATE             8
+#define DEF_MAX_DISCARD_REQUEST                8       /* issue 8 discards per round */
 #define DEF_MIN_DISCARD_ISSUE_TIME     50      /* 50 ms, if exists */
 #define DEF_MAX_DISCARD_ISSUE_TIME     60000   /* 60 s, if no candidates */
 #define DEF_CP_INTERVAL                        60      /* 60 secs */
@@ -156,7 +161,6 @@ struct cp_control {
        __u64 trim_start;
        __u64 trim_end;
        __u64 trim_minlen;
-       __u64 trimmed;
 };
 
 /*
@@ -175,12 +179,14 @@ enum {
        ORPHAN_INO,             /* for orphan ino list */
        APPEND_INO,             /* for append ino list */
        UPDATE_INO,             /* for update ino list */
+       FLUSH_INO,              /* for multiple device flushing */
        MAX_INO_ENTRY,          /* max. list */
 };
 
 struct ino_entry {
-       struct list_head list;  /* list head */
-       nid_t ino;              /* inode number */
+       struct list_head list;          /* list head */
+       nid_t ino;                      /* inode number */
+       unsigned int dirty_device;      /* dirty device bitmap */
 };
 
 /* for the list of inodes to be GCed */
@@ -204,10 +210,6 @@ struct discard_entry {
 #define plist_idx(blk_num)     ((blk_num) >= MAX_PLIST_NUM ?           \
                                        (MAX_PLIST_NUM - 1) : (blk_num - 1))
 
-#define P_ACTIVE       0x01
-#define P_TRIM         0x02
-#define plist_issue(tag)       (((tag) & P_ACTIVE) || ((tag) & P_TRIM))
-
 enum {
        D_PREP,
        D_SUBMIT,
@@ -239,12 +241,32 @@ struct discard_cmd {
        int error;                      /* bio error */
 };
 
+enum {
+       DPOLICY_BG,
+       DPOLICY_FORCE,
+       DPOLICY_FSTRIM,
+       DPOLICY_UMOUNT,
+       MAX_DPOLICY,
+};
+
+struct discard_policy {
+       int type;                       /* type of discard */
+       unsigned int min_interval;      /* used for candidates exist */
+       unsigned int max_interval;      /* used for candidates not exist */
+       unsigned int max_requests;      /* # of discards issued per round */
+       unsigned int io_aware_gran;     /* minimum granularity discard not be aware of I/O */
+       bool io_aware;                  /* issue discard in idle time */
+       bool sync;                      /* submit discard with REQ_SYNC flag */
+       unsigned int granularity;       /* discard granularity */
+};
+
 struct discard_cmd_control {
        struct task_struct *f2fs_issue_discard; /* discard thread */
        struct list_head entry_list;            /* 4KB discard entry list */
        struct list_head pend_list[MAX_PLIST_NUM];/* store pending entries */
        unsigned char pend_list_tag[MAX_PLIST_NUM];/* tag for pending entries */
        struct list_head wait_list;             /* store on-flushing entries */
+       struct list_head fstrim_list;           /* in-flight discard from fstrim */
        wait_queue_head_t discard_wait_queue;   /* waiting queue for wake-up */
        unsigned int discard_wake;              /* to wake up discard thread */
        struct mutex cmd_lock;
@@ -377,11 +399,14 @@ struct f2fs_flush_device {
 
 /* for inline stuff */
 #define DEF_INLINE_RESERVED_SIZE       1
+#define DEF_MIN_INLINE_SIZE            1
 static inline int get_extra_isize(struct inode *inode);
-#define MAX_INLINE_DATA(inode) (sizeof(__le32) * \
-                               (CUR_ADDRS_PER_INODE(inode) - \
-                               DEF_INLINE_RESERVED_SIZE - \
-                               F2FS_INLINE_XATTR_ADDRS))
+static inline int get_inline_xattr_addrs(struct inode *inode);
+#define F2FS_INLINE_XATTR_ADDRS(inode) get_inline_xattr_addrs(inode)
+#define MAX_INLINE_DATA(inode) (sizeof(__le32) *                       \
+                               (CUR_ADDRS_PER_INODE(inode) -           \
+                               F2FS_INLINE_XATTR_ADDRS(inode) -        \
+                               DEF_INLINE_RESERVED_SIZE))
 
 /* for inline dir */
 #define NR_INLINE_DENTRY(inode)        (MAX_INLINE_DATA(inode) * BITS_PER_BYTE / \
@@ -581,6 +606,7 @@ struct f2fs_inode_info {
 #endif
        struct list_head dirty_list;    /* dirty list for dirs and files */
        struct list_head gdirty_list;   /* linked in global dirty list */
+       struct list_head inmem_ilist;   /* list for inmem inodes */
        struct list_head inmem_pages;   /* inmemory pages managed by f2fs */
        struct task_struct *inmem_task; /* store inmemory task */
        struct mutex inmem_lock;        /* lock for inmemory pages */
@@ -591,6 +617,7 @@ struct f2fs_inode_info {
 
        int i_extra_isize;              /* size of extra space located in i_addr */
        kprojid_t i_projid;             /* id for project quota */
+       int i_inline_xattr_size;        /* inline xattr size */
 };
 
 static inline void get_extent_info(struct extent_info *ext,
@@ -664,10 +691,13 @@ static inline void __try_update_largest_extent(struct inode *inode,
        }
 }
 
-enum nid_list {
-       FREE_NID_LIST,
-       ALLOC_NID_LIST,
-       MAX_NID_LIST,
+/*
+ * For free nid management
+ */
+enum nid_state {
+       FREE_NID,               /* newly added to free nid list */
+       PREALLOC_NID,           /* it is preallocated */
+       MAX_NID_STATE,
 };
 
 struct f2fs_nm_info {
@@ -690,8 +720,8 @@ struct f2fs_nm_info {
 
        /* free node ids management */
        struct radix_tree_root free_nid_root;/* root of the free_nid cache */
-       struct list_head nid_list[MAX_NID_LIST];/* lists for free nids */
-       unsigned int nid_cnt[MAX_NID_LIST];     /* the number of free node id */
+       struct list_head free_nid_list;         /* list for free nids excluding preallocated nids */
+       unsigned int nid_cnt[MAX_NID_STATE];    /* the number of free node id */
        spinlock_t nid_list_lock;       /* protect nid lists ops */
        struct mutex build_lock;        /* lock for build free nids */
        unsigned char (*free_nid_bitmap)[NAT_ENTRY_BITMAP_SIZE];
@@ -769,6 +799,7 @@ enum {
 struct flush_cmd {
        struct completion wait;
        struct llist_node llnode;
+       nid_t ino;
        int ret;
 };
 
@@ -787,6 +818,8 @@ struct f2fs_sm_info {
        struct dirty_seglist_info *dirty_info;  /* dirty segment information */
        struct curseg_info *curseg_array;       /* active segment information */
 
+       struct rw_semaphore curseg_lock;        /* for preventing curseg change */
+
        block_t seg0_blkaddr;           /* block address of 0'th segment */
        block_t main_blkaddr;           /* start block address of main area */
        block_t ssa_blkaddr;            /* start block address of SSA area */
@@ -808,6 +841,7 @@ struct f2fs_sm_info {
        unsigned int min_ipu_util;      /* in-place-update threshold */
        unsigned int min_fsync_blocks;  /* threshold for fsync */
        unsigned int min_hot_blocks;    /* threshold for hot block allocation */
+       unsigned int min_ssr_sections;  /* threshold to trigger SSR allocation */
 
        /* for flush command control */
        struct flush_cmd_control *fcc_info;
@@ -829,6 +863,7 @@ struct f2fs_sm_info {
 enum count_type {
        F2FS_DIRTY_DENTS,
        F2FS_DIRTY_DATA,
+       F2FS_DIRTY_QDATA,
        F2FS_DIRTY_NODES,
        F2FS_DIRTY_META,
        F2FS_INMEM_PAGES,
@@ -877,6 +912,18 @@ enum need_lock_type {
        LOCK_RETRY,
 };
 
+enum cp_reason_type {
+       CP_NO_NEEDED,
+       CP_NON_REGULAR,
+       CP_HARDLINK,
+       CP_SB_NEED_CP,
+       CP_WRONG_PINO,
+       CP_NO_SPC_ROLL,
+       CP_NODE_NEED_CP,
+       CP_FASTBOOT_MODE,
+       CP_SPEC_LOG_NUM,
+};
+
 enum iostat_type {
        APP_DIRECT_IO,                  /* app direct IOs */
        APP_BUFFERED_IO,                /* app buffered IOs */
@@ -896,6 +943,7 @@ enum iostat_type {
 
 struct f2fs_io_info {
        struct f2fs_sb_info *sbi;       /* f2fs_sb_info pointer */
+       nid_t ino;              /* inode number */
        enum page_type type;    /* contains DATA/NODE/META/META_FLUSH */
        enum temp_type temp;    /* contains HOT/WARM/COLD */
        int op;                 /* contains REQ_OP_ */
@@ -940,6 +988,7 @@ enum inode_type {
        DIR_INODE,                      /* for dirty dir inode */
        FILE_INODE,                     /* for dirty regular/symlink inode */
        DIRTY_META,                     /* for all dirtied inode metadata */
+       ATOMIC_FILE,                    /* for all atomic files */
        NR_INODE_TYPE,
 };
 
@@ -1042,12 +1091,15 @@ struct f2fs_sb_info {
        loff_t max_file_blocks;                 /* max block index of file */
        int active_logs;                        /* # of active logs */
        int dir_level;                          /* directory level */
+       int inline_xattr_size;                  /* inline xattr size */
+       unsigned int trigger_ssr_threshold;     /* threshold to trigger ssr */
 
        block_t user_block_count;               /* # of user blocks */
        block_t total_valid_block_count;        /* # of valid blocks */
        block_t discard_blks;                   /* discard command candidats */
        block_t last_valid_block_count;         /* for recovery */
        block_t reserved_blocks;                /* configurable reserved blocks */
+       block_t current_reserved_blocks;        /* current reserved blocks */
 
        u32 s_next_generation;                  /* for NFS support */
 
@@ -1113,6 +1165,8 @@ struct f2fs_sb_info {
        struct list_head s_list;
        int s_ndevs;                            /* number of devices */
        struct f2fs_dev_info *devs;             /* for device list */
+       unsigned int dirty_device;              /* for checkpoint data flush */
+       spinlock_t dev_lock;                    /* protect dirty_device */
        struct mutex umount_mutex;
        unsigned int shrinker_run_no;
 
@@ -1176,8 +1230,7 @@ static inline void f2fs_update_time(struct f2fs_sb_info *sbi, int type)
 
 static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
 {
-       struct timespec ts = {sbi->interval_time[type], 0};
-       unsigned long interval = timespec_to_jiffies(&ts);
+       unsigned long interval = sbi->interval_time[type] * HZ;
 
        return time_after(jiffies, sbi->last_time[type] + interval);
 }
@@ -1344,6 +1397,13 @@ static inline unsigned long long cur_cp_version(struct f2fs_checkpoint *cp)
        return le64_to_cpu(cp->checkpoint_ver);
 }
 
+static inline unsigned long f2fs_qf_ino(struct super_block *sb, int type)
+{
+       if (type < F2FS_MAX_QUOTAS)
+               return le32_to_cpu(F2FS_SB(sb)->raw_super->qf_ino[type]);
+       return 0;
+}
+
 static inline __u64 cur_cp_crc(struct f2fs_checkpoint *cp)
 {
        size_t crc_offset = le32_to_cpu(cp->checksum_offset);
@@ -1522,7 +1582,8 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
 
        spin_lock(&sbi->stat_lock);
        sbi->total_valid_block_count += (block_t)(*count);
-       avail_user_block_count = sbi->user_block_count - sbi->reserved_blocks;
+       avail_user_block_count = sbi->user_block_count -
+                                       sbi->current_reserved_blocks;
        if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
                diff = sbi->total_valid_block_count - avail_user_block_count;
                *count -= diff;
@@ -1556,6 +1617,10 @@ static inline void dec_valid_block_count(struct f2fs_sb_info *sbi,
        f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count);
        f2fs_bug_on(sbi, inode->i_blocks < sectors);
        sbi->total_valid_block_count -= (block_t)count;
+       if (sbi->reserved_blocks &&
+               sbi->current_reserved_blocks < sbi->reserved_blocks)
+               sbi->current_reserved_blocks = min(sbi->reserved_blocks,
+                                       sbi->current_reserved_blocks + count);
        spin_unlock(&sbi->stat_lock);
        f2fs_i_blocks_write(inode, count, false, true);
 }
@@ -1576,6 +1641,8 @@ static inline void inode_inc_dirty_pages(struct inode *inode)
        atomic_inc(&F2FS_I(inode)->dirty_pages);
        inc_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ?
                                F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
+       if (IS_NOQUOTA(inode))
+               inc_page_count(F2FS_I_SB(inode), F2FS_DIRTY_QDATA);
 }
 
 static inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type)
@@ -1592,6 +1659,8 @@ static inline void inode_dec_dirty_pages(struct inode *inode)
        atomic_dec(&F2FS_I(inode)->dirty_pages);
        dec_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ?
                                F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
+       if (IS_NOQUOTA(inode))
+               dec_page_count(F2FS_I_SB(inode), F2FS_DIRTY_QDATA);
 }
 
 static inline s64 get_pages(struct f2fs_sb_info *sbi, int count_type)
@@ -1699,10 +1768,17 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
                        return ret;
        }
 
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+       if (time_to_inject(sbi, FAULT_BLOCK)) {
+               f2fs_show_injection_info(FAULT_BLOCK);
+               goto enospc;
+       }
+#endif
+
        spin_lock(&sbi->stat_lock);
 
        valid_block_count = sbi->total_valid_block_count + 1;
-       if (unlikely(valid_block_count + sbi->reserved_blocks >
+       if (unlikely(valid_block_count + sbi->current_reserved_blocks >
                                                sbi->user_block_count)) {
                spin_unlock(&sbi->stat_lock);
                goto enospc;
@@ -1745,6 +1821,9 @@ static inline void dec_valid_node_count(struct f2fs_sb_info *sbi,
 
        sbi->total_valid_node_count--;
        sbi->total_valid_block_count--;
+       if (sbi->reserved_blocks &&
+               sbi->current_reserved_blocks < sbi->reserved_blocks)
+               sbi->current_reserved_blocks++;
 
        spin_unlock(&sbi->stat_lock);
 
@@ -1791,6 +1870,19 @@ static inline struct page *f2fs_grab_cache_page(struct address_space *mapping,
        return grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
 }
 
+static inline struct page *f2fs_pagecache_get_page(
+                               struct address_space *mapping, pgoff_t index,
+                               int fgp_flags, gfp_t gfp_mask)
+{
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+       if (time_to_inject(F2FS_M_SB(mapping), FAULT_PAGE_GET)) {
+               f2fs_show_injection_info(FAULT_PAGE_GET);
+               return NULL;
+       }
+#endif
+       return pagecache_get_page(mapping, index, fgp_flags, gfp_mask);
+}
+
 static inline void f2fs_copy_page(struct page *src, struct page *dst)
 {
        char *src_kaddr = kmap(src);
@@ -1840,15 +1932,25 @@ static inline void *f2fs_kmem_cache_alloc(struct kmem_cache *cachep,
        return entry;
 }
 
-static inline struct bio *f2fs_bio_alloc(int npages)
+static inline struct bio *f2fs_bio_alloc(struct f2fs_sb_info *sbi,
+                                               int npages, bool no_fail)
 {
        struct bio *bio;
 
-       /* No failure on bio allocation */
-       bio = bio_alloc(GFP_NOIO, npages);
-       if (!bio)
-               bio = bio_alloc(GFP_NOIO | __GFP_NOFAIL, npages);
-       return bio;
+       if (no_fail) {
+               /* No failure on bio allocation */
+               bio = bio_alloc(GFP_NOIO, npages);
+               if (!bio)
+                       bio = bio_alloc(GFP_NOIO | __GFP_NOFAIL, npages);
+               return bio;
+       }
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+       if (time_to_inject(sbi, FAULT_ALLOC_BIO)) {
+               f2fs_show_injection_info(FAULT_ALLOC_BIO);
+               return NULL;
+       }
+#endif
+       return bio_alloc(GFP_KERNEL, npages);
 }
 
 static inline void f2fs_radix_tree_insert(struct radix_tree_root *root,
@@ -2158,25 +2260,20 @@ static inline int f2fs_has_inline_xattr(struct inode *inode)
 
 static inline unsigned int addrs_per_inode(struct inode *inode)
 {
-       if (f2fs_has_inline_xattr(inode))
-               return CUR_ADDRS_PER_INODE(inode) - F2FS_INLINE_XATTR_ADDRS;
-       return CUR_ADDRS_PER_INODE(inode);
+       return CUR_ADDRS_PER_INODE(inode) - F2FS_INLINE_XATTR_ADDRS(inode);
 }
 
-static inline void *inline_xattr_addr(struct page *page)
+static inline void *inline_xattr_addr(struct inode *inode, struct page *page)
 {
        struct f2fs_inode *ri = F2FS_INODE(page);
 
        return (void *)&(ri->i_addr[DEF_ADDRS_PER_INODE -
-                                       F2FS_INLINE_XATTR_ADDRS]);
+                                       F2FS_INLINE_XATTR_ADDRS(inode)]);
 }
 
 static inline int inline_xattr_size(struct inode *inode)
 {
-       if (f2fs_has_inline_xattr(inode))
-               return F2FS_INLINE_XATTR_ADDRS << 2;
-       else
-               return 0;
+       return get_inline_xattr_addrs(inode) * sizeof(__le32);
 }
 
 static inline int f2fs_has_inline_data(struct inode *inode)
@@ -2257,9 +2354,10 @@ static inline void clear_file(struct inode *inode, int type)
 
 static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
 {
+       bool ret;
+
        if (dsync) {
                struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-               bool ret;
 
                spin_lock(&sbi->inode_lock[DIRTY_META]);
                ret = list_empty(&F2FS_I(inode)->gdirty_list);
@@ -2270,7 +2368,12 @@ static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
                        file_keep_isize(inode) ||
                        i_size_read(inode) & PAGE_MASK)
                return false;
-       return F2FS_I(inode)->last_disk_size == i_size_read(inode);
+
+       down_read(&F2FS_I(inode)->i_sem);
+       ret = F2FS_I(inode)->last_disk_size == i_size_read(inode);
+       up_read(&F2FS_I(inode)->i_sem);
+
+       return ret;
 }
 
 static inline int f2fs_readonly(struct super_block *sb)
@@ -2320,6 +2423,12 @@ static inline int get_extra_isize(struct inode *inode)
        return F2FS_I(inode)->i_extra_isize / sizeof(__le32);
 }
 
+static inline int f2fs_sb_has_flexible_inline_xattr(struct super_block *sb);
+static inline int get_inline_xattr_addrs(struct inode *inode)
+{
+       return F2FS_I(inode)->i_inline_xattr_size;
+}
+
 #define get_inode_mode(i) \
        ((is_inode_flag_set(i, FI_ACL_MODE)) ? \
         (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
@@ -2448,7 +2557,7 @@ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode)
  */
 int f2fs_inode_dirtied(struct inode *inode, bool sync);
 void f2fs_inode_synced(struct inode *inode);
-void f2fs_enable_quota_files(struct f2fs_sb_info *sbi);
+int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly);
 void f2fs_quota_off_umount(struct super_block *sb);
 int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
 int f2fs_sync_fs(struct super_block *sb, int sync);
@@ -2476,7 +2585,7 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni);
 pgoff_t get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs);
 int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode);
 int truncate_inode_blocks(struct inode *inode, pgoff_t from);
-int truncate_xattr_node(struct inode *inode, struct page *page);
+int truncate_xattr_node(struct inode *inode);
 int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino);
 int remove_inode_page(struct inode *inode);
 struct page *new_inode_page(struct inode *inode);
@@ -2511,19 +2620,22 @@ void destroy_node_manager_caches(void);
  */
 bool need_SSR(struct f2fs_sb_info *sbi);
 void register_inmem_page(struct inode *inode, struct page *page);
+void drop_inmem_pages_all(struct f2fs_sb_info *sbi);
 void drop_inmem_pages(struct inode *inode);
 void drop_inmem_page(struct inode *inode, struct page *page);
 int commit_inmem_pages(struct inode *inode);
 void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need);
 void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi);
-int f2fs_issue_flush(struct f2fs_sb_info *sbi);
+int f2fs_issue_flush(struct f2fs_sb_info *sbi, nid_t ino);
 int create_flush_cmd_control(struct f2fs_sb_info *sbi);
+int f2fs_flush_device_cache(struct f2fs_sb_info *sbi);
 void destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free);
 void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr);
 bool is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr);
-void refresh_sit_entry(struct f2fs_sb_info *sbi, block_t old, block_t new);
+void init_discard_policy(struct discard_policy *dpolicy, int discard_type,
+                                               unsigned int granularity);
 void stop_discard_thread(struct f2fs_sb_info *sbi);
-void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi, bool umount);
+bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
 void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc);
 void release_discard_addrs(struct f2fs_sb_info *sbi);
 int npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
@@ -2578,6 +2690,10 @@ void add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type);
 void remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type);
 void release_ino_entry(struct f2fs_sb_info *sbi, bool all);
 bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode);
+void set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
+                                       unsigned int devidx, int type);
+bool is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
+                                       unsigned int devidx, int type);
 int f2fs_sync_inode_meta(struct f2fs_sb_info *sbi);
 int acquire_orphan_inode(struct f2fs_sb_info *sbi);
 void release_orphan_inode(struct f2fs_sb_info *sbi);
@@ -2665,14 +2781,16 @@ struct f2fs_stat_info {
        unsigned long long hit_largest, hit_cached, hit_rbtree;
        unsigned long long hit_total, total_ext;
        int ext_tree, zombie_tree, ext_node;
-       int ndirty_node, ndirty_dent, ndirty_meta, ndirty_data, ndirty_imeta;
+       int ndirty_node, ndirty_dent, ndirty_meta, ndirty_imeta;
+       int ndirty_data, ndirty_qdata;
        int inmem_pages;
-       unsigned int ndirty_dirs, ndirty_files, ndirty_all;
+       unsigned int ndirty_dirs, ndirty_files, nquota_files, ndirty_all;
        int nats, dirty_nats, sits, dirty_sits;
        int free_nids, avail_nids, alloc_nids;
        int total_count, utilization;
        int bg_gc, nr_wb_cp_data, nr_wb_data;
-       int nr_flushing, nr_flushed, nr_discarding, nr_discarded;
+       int nr_flushing, nr_flushed, flush_list_empty;
+       int nr_discarding, nr_discarded;
        int nr_discard_cmd;
        unsigned int undiscard_blks;
        int inline_xattr, inline_inode, inline_dir, append, update, orphans;
@@ -2981,6 +3099,16 @@ static inline int f2fs_sb_has_inode_chksum(struct super_block *sb)
        return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_INODE_CHKSUM);
 }
 
+static inline int f2fs_sb_has_flexible_inline_xattr(struct super_block *sb)
+{
+       return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_FLEXIBLE_INLINE_XATTR);
+}
+
+static inline int f2fs_sb_has_quota_ino(struct super_block *sb)
+{
+       return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_QUOTA_INO);
+}
+
 #ifdef CONFIG_BLK_DEV_ZONED
 static inline int get_blkz_type(struct f2fs_sb_info *sbi,
                        struct block_device *bdev, block_t blkaddr)