f2fs: initialize page->private when using for our internal use
[linux-2.6-microblaze.git] / fs / f2fs / f2fs.h
index 11a20dc..ee8eb33 100644 (file)
@@ -97,6 +97,8 @@ extern const char *f2fs_fault_name[FAULT_MAX];
 #define F2FS_MOUNT_NORECOVERY          0x04000000
 #define F2FS_MOUNT_ATGC                        0x08000000
 #define F2FS_MOUNT_MERGE_CHECKPOINT    0x10000000
+#define        F2FS_MOUNT_GC_MERGE             0x20000000
+#define F2FS_MOUNT_COMPRESS_CACHE      0x40000000
 
 #define F2FS_OPTION(sbi)       ((sbi)->mount_opt)
 #define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option)
@@ -149,8 +151,10 @@ struct f2fs_mount_info {
        unsigned char compress_level;           /* compress level */
        bool compress_chksum;                   /* compressed data chksum */
        unsigned char compress_ext_cnt;         /* extension count */
+       unsigned char nocompress_ext_cnt;               /* nocompress extension count */
        int compress_mode;                      /* compression mode */
        unsigned char extensions[COMPRESS_EXT_NUM][F2FS_EXTENSION_LEN]; /* extensions */
+       unsigned char noextensions[COMPRESS_EXT_NUM][F2FS_EXTENSION_LEN]; /* extensions */
 };
 
 #define F2FS_FEATURE_ENCRYPT           0x0001
@@ -167,6 +171,7 @@ struct f2fs_mount_info {
 #define F2FS_FEATURE_SB_CHKSUM         0x0800
 #define F2FS_FEATURE_CASEFOLD          0x1000
 #define F2FS_FEATURE_COMPRESSION       0x2000
+#define F2FS_FEATURE_RO                        0x4000
 
 #define __F2FS_HAS_FEATURE(raw_super, mask)                            \
        ((raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -637,21 +642,26 @@ enum {
 #define FADVISE_MODIFIABLE_BITS        (FADVISE_COLD_BIT | FADVISE_HOT_BIT)
 
 #define file_is_cold(inode)    is_file(inode, FADVISE_COLD_BIT)
-#define file_wrong_pino(inode) is_file(inode, FADVISE_LOST_PINO_BIT)
 #define file_set_cold(inode)   set_file(inode, FADVISE_COLD_BIT)
-#define file_lost_pino(inode)  set_file(inode, FADVISE_LOST_PINO_BIT)
 #define file_clear_cold(inode) clear_file(inode, FADVISE_COLD_BIT)
+
+#define file_wrong_pino(inode) is_file(inode, FADVISE_LOST_PINO_BIT)
+#define file_lost_pino(inode)  set_file(inode, FADVISE_LOST_PINO_BIT)
 #define file_got_pino(inode)   clear_file(inode, FADVISE_LOST_PINO_BIT)
+
 #define file_is_encrypt(inode) is_file(inode, FADVISE_ENCRYPT_BIT)
 #define file_set_encrypt(inode)        set_file(inode, FADVISE_ENCRYPT_BIT)
-#define file_clear_encrypt(inode) clear_file(inode, FADVISE_ENCRYPT_BIT)
+
 #define file_enc_name(inode)   is_file(inode, FADVISE_ENC_NAME_BIT)
 #define file_set_enc_name(inode) set_file(inode, FADVISE_ENC_NAME_BIT)
+
 #define file_keep_isize(inode) is_file(inode, FADVISE_KEEP_SIZE_BIT)
 #define file_set_keep_isize(inode) set_file(inode, FADVISE_KEEP_SIZE_BIT)
+
 #define file_is_hot(inode)     is_file(inode, FADVISE_HOT_BIT)
 #define file_set_hot(inode)    set_file(inode, FADVISE_HOT_BIT)
 #define file_clear_hot(inode)  clear_file(inode, FADVISE_HOT_BIT)
+
 #define file_is_verity(inode)  is_file(inode, FADVISE_VERITY_BIT)
 #define file_set_verity(inode) set_file(inode, FADVISE_VERITY_BIT)
 
@@ -700,6 +710,8 @@ enum {
        FI_COMPRESS_CORRUPT,    /* indicate compressed cluster is corrupted */
        FI_MMAP_FILE,           /* indicate file was mmapped */
        FI_ENABLE_COMPRESS,     /* enable compression in "user" compression mode */
+       FI_COMPRESS_RELEASED,   /* compressed blocks were released */
+       FI_ALIGNED_WRITE,       /* enable aligned write */
        FI_MAX,                 /* max flag, never be used */
 };
 
@@ -860,7 +872,7 @@ struct f2fs_nm_info {
        /* NAT cache management */
        struct radix_tree_root nat_root;/* root of the nat entry cache */
        struct radix_tree_root nat_set_root;/* root of the nat set cache */
-       struct rw_semaphore nat_tree_lock;      /* protect nat_tree_lock */
+       struct rw_semaphore nat_tree_lock;      /* protect nat entry tree */
        struct list_head nat_entries;   /* cached nat entry list (clean) */
        spinlock_t nat_list_lock;       /* protect clean nat entry list */
        unsigned int nat_cnt[MAX_NAT_STATE]; /* the # of cached nat entries */
@@ -933,6 +945,7 @@ static inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode,
 #define        NR_CURSEG_DATA_TYPE     (3)
 #define NR_CURSEG_NODE_TYPE    (3)
 #define NR_CURSEG_INMEM_TYPE   (2)
+#define NR_CURSEG_RO_TYPE      (2)
 #define NR_CURSEG_PERSIST_TYPE (NR_CURSEG_DATA_TYPE + NR_CURSEG_NODE_TYPE)
 #define NR_CURSEG_TYPE         (NR_CURSEG_INMEM_TYPE + NR_CURSEG_PERSIST_TYPE)
 
@@ -1285,25 +1298,119 @@ enum {
                                 */
 };
 
+static inline int f2fs_test_bit(unsigned int nr, char *addr);
+static inline void f2fs_set_bit(unsigned int nr, char *addr);
+static inline void f2fs_clear_bit(unsigned int nr, char *addr);
+
 /*
- * this value is set in page as a private data which indicate that
- * the page is atomically written, and it is in inmem_pages list.
+ * Layout of f2fs page.private:
+ *
+ * Layout A: lowest bit should be 1
+ * | bit0 = 1 | bit1 | bit2 | ... | bit MAX | private data .... |
+ * bit 0       PAGE_PRIVATE_NOT_POINTER
+ * bit 1       PAGE_PRIVATE_ATOMIC_WRITE
+ * bit 2       PAGE_PRIVATE_DUMMY_WRITE
+ * bit 3       PAGE_PRIVATE_ONGOING_MIGRATION
+ * bit 4       PAGE_PRIVATE_INLINE_INODE
+ * bit 5       PAGE_PRIVATE_REF_RESOURCE
+ * bit 6-      f2fs private data
+ *
+ * Layout B: lowest bit should be 0
+ * page.private is a wrapped pointer.
  */
-#define ATOMIC_WRITTEN_PAGE            ((unsigned long)-1)
-#define DUMMY_WRITTEN_PAGE             ((unsigned long)-2)
-
-#define IS_ATOMIC_WRITTEN_PAGE(page)                   \
-               (page_private(page) == ATOMIC_WRITTEN_PAGE)
-#define IS_DUMMY_WRITTEN_PAGE(page)                    \
-               (page_private(page) == DUMMY_WRITTEN_PAGE)
-
-#ifdef CONFIG_F2FS_IO_TRACE
-#define IS_IO_TRACED_PAGE(page)                        \
-               (page_private(page) > 0 &&              \
-                page_private(page) < (unsigned long)PID_MAX_LIMIT)
-#else
-#define IS_IO_TRACED_PAGE(page) (0)
-#endif
+enum {
+       PAGE_PRIVATE_NOT_POINTER,               /* private contains non-pointer data */
+       PAGE_PRIVATE_ATOMIC_WRITE,              /* data page from atomic write path */
+       PAGE_PRIVATE_DUMMY_WRITE,               /* data page for padding aligned IO */
+       PAGE_PRIVATE_ONGOING_MIGRATION,         /* data page which is on-going migrating */
+       PAGE_PRIVATE_INLINE_INODE,              /* inode page contains inline data */
+       PAGE_PRIVATE_REF_RESOURCE,              /* dirty page has referenced resources */
+       PAGE_PRIVATE_MAX
+};
+
+#define PAGE_PRIVATE_GET_FUNC(name, flagname) \
+static inline bool page_private_##name(struct page *page) \
+{ \
+       return PagePrivate(page) && \
+               test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
+               test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
+}
+
+#define PAGE_PRIVATE_SET_FUNC(name, flagname) \
+static inline void set_page_private_##name(struct page *page) \
+{ \
+       if (!PagePrivate(page)) { \
+               get_page(page); \
+               SetPagePrivate(page); \
+               set_page_private(page, 0); \
+       } \
+       set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
+       set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
+}
+
+#define PAGE_PRIVATE_CLEAR_FUNC(name, flagname) \
+static inline void clear_page_private_##name(struct page *page) \
+{ \
+       clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
+       if (page_private(page) == 1 << PAGE_PRIVATE_NOT_POINTER) { \
+               set_page_private(page, 0); \
+               if (PagePrivate(page)) { \
+                       ClearPagePrivate(page); \
+                       put_page(page); \
+               }\
+       } \
+}
+
+PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
+PAGE_PRIVATE_GET_FUNC(reference, REF_RESOURCE);
+PAGE_PRIVATE_GET_FUNC(inline, INLINE_INODE);
+PAGE_PRIVATE_GET_FUNC(gcing, ONGOING_MIGRATION);
+PAGE_PRIVATE_GET_FUNC(atomic, ATOMIC_WRITE);
+PAGE_PRIVATE_GET_FUNC(dummy, DUMMY_WRITE);
+
+PAGE_PRIVATE_SET_FUNC(reference, REF_RESOURCE);
+PAGE_PRIVATE_SET_FUNC(inline, INLINE_INODE);
+PAGE_PRIVATE_SET_FUNC(gcing, ONGOING_MIGRATION);
+PAGE_PRIVATE_SET_FUNC(atomic, ATOMIC_WRITE);
+PAGE_PRIVATE_SET_FUNC(dummy, DUMMY_WRITE);
+
+PAGE_PRIVATE_CLEAR_FUNC(reference, REF_RESOURCE);
+PAGE_PRIVATE_CLEAR_FUNC(inline, INLINE_INODE);
+PAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION);
+PAGE_PRIVATE_CLEAR_FUNC(atomic, ATOMIC_WRITE);
+PAGE_PRIVATE_CLEAR_FUNC(dummy, DUMMY_WRITE);
+
+static inline unsigned long get_page_private_data(struct page *page)
+{
+       unsigned long data = page_private(page);
+
+       if (!test_bit(PAGE_PRIVATE_NOT_POINTER, &data))
+               return 0;
+       return data >> PAGE_PRIVATE_MAX;
+}
+
+static inline void set_page_private_data(struct page *page, unsigned long data)
+{
+       if (!PagePrivate(page)) {
+               get_page(page);
+               SetPagePrivate(page);
+               set_page_private(page, 0);
+       }
+       set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page));
+       page_private(page) |= data << PAGE_PRIVATE_MAX;
+}
+
+static inline void clear_page_private_data(struct page *page)
+{
+       page_private(page) &= (1 << PAGE_PRIVATE_MAX) - 1;
+       if (page_private(page) == 1 << PAGE_PRIVATE_NOT_POINTER) {
+               set_page_private(page, 0);
+               if (PagePrivate(page)) {
+                       ClearPagePrivate(page);
+                       put_page(page);
+               }
+       }
+}
 
 /* For compression */
 enum compress_algorithm_type {
@@ -1319,6 +1426,9 @@ enum compress_flag {
        COMPRESS_MAX_FLAG,
 };
 
+#define        COMPRESS_WATERMARK                      20
+#define        COMPRESS_PERCENT                        20
+
 #define COMPRESS_DATA_RESERVED_SIZE            4
 struct compress_data {
        __le32 clen;                    /* compressed data size */
@@ -1596,6 +1706,9 @@ struct f2fs_sb_info {
        struct kobject s_stat_kobj;             /* /sys/fs/f2fs/<devname>/stat */
        struct completion s_stat_kobj_unregister;
 
+       struct kobject s_feature_list_kobj;             /* /sys/fs/f2fs/<devname>/feature_list */
+       struct completion s_feature_list_kobj_unregister;
+
        /* For shrinker support */
        struct list_head s_list;
        int s_ndevs;                            /* number of devices */
@@ -1623,6 +1736,17 @@ struct f2fs_sb_info {
 #ifdef CONFIG_F2FS_FS_COMPRESSION
        struct kmem_cache *page_array_slab;     /* page array entry */
        unsigned int page_array_slab_size;      /* default page array slab size */
+
+       /* For runtime compression statistics */
+       u64 compr_written_block;
+       u64 compr_saved_block;
+       u32 compr_new_inode;
+
+       /* For compressed block cache */
+       struct inode *compress_inode;           /* cache compressed blocks */
+       unsigned int compress_percent;          /* cache page percentage */
+       unsigned int compress_watermark;        /* cache page watermark */
+       atomic_t compress_page_hit;             /* cache hit count */
 #endif
 };
 
@@ -2215,6 +2339,7 @@ static inline block_t __cp_payload(struct f2fs_sb_info *sbi)
 static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag)
 {
        struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
+       void *tmp_ptr = &ckpt->sit_nat_version_bitmap;
        int offset;
 
        if (is_set_ckpt_flags(sbi, CP_LARGE_NAT_BITMAP_FLAG)) {
@@ -2224,7 +2349,7 @@ static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag)
                 * if large_nat_bitmap feature is enabled, leave checksum
                 * protection for all nat/sit bitmaps.
                 */
-               return &ckpt->sit_nat_version_bitmap + offset + sizeof(__le32);
+               return tmp_ptr + offset + sizeof(__le32);
        }
 
        if (__cp_payload(sbi) > 0) {
@@ -2235,7 +2360,7 @@ static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag)
        } else {
                offset = (flag == NAT_BITMAP) ?
                        le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0;
-               return &ckpt->sit_nat_version_bitmap + offset;
+               return tmp_ptr + offset;
        }
 }
 
@@ -2674,6 +2799,7 @@ static inline void __mark_inode_dirty_flag(struct inode *inode,
        case FI_DATA_EXIST:
        case FI_INLINE_DOTS:
        case FI_PIN_FILE:
+       case FI_COMPRESS_RELEASED:
                f2fs_mark_inode_dirty_sync(inode, true);
        }
 }
@@ -2795,6 +2921,8 @@ static inline void get_inline_info(struct inode *inode, struct f2fs_inode *ri)
                set_bit(FI_EXTRA_ATTR, fi->flags);
        if (ri->i_inline & F2FS_PIN_FILE)
                set_bit(FI_PIN_FILE, fi->flags);
+       if (ri->i_inline & F2FS_COMPRESS_RELEASED)
+               set_bit(FI_COMPRESS_RELEASED, fi->flags);
 }
 
 static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri)
@@ -2815,6 +2943,8 @@ static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri)
                ri->i_inline |= F2FS_EXTRA_ATTR;
        if (is_inode_flag_set(inode, FI_PIN_FILE))
                ri->i_inline |= F2FS_PIN_FILE;
+       if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED))
+               ri->i_inline |= F2FS_COMPRESS_RELEASED;
 }
 
 static inline int f2fs_has_extra_attr(struct inode *inode)
@@ -3023,25 +3153,6 @@ static inline bool is_dot_dotdot(const u8 *name, size_t len)
        return false;
 }
 
-static inline bool f2fs_may_extent_tree(struct inode *inode)
-{
-       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-
-       if (!test_opt(sbi, EXTENT_CACHE) ||
-                       is_inode_flag_set(inode, FI_NO_EXTENT) ||
-                       is_inode_flag_set(inode, FI_COMPRESSED_FILE))
-               return false;
-
-       /*
-        * for recovered files during mount do not create extents
-        * if shrinker is not registered.
-        */
-       if (list_empty(&sbi->s_list))
-               return false;
-
-       return S_ISREG(inode->i_mode);
-}
-
 static inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi,
                                        size_t size, gfp_t flags)
 {
@@ -3165,20 +3276,6 @@ static inline bool __is_valid_data_blkaddr(block_t blkaddr)
        return true;
 }
 
-static inline void f2fs_set_page_private(struct page *page,
-                                               unsigned long data)
-{
-       if (PagePrivate(page))
-               return;
-
-       attach_page_private(page, (void *)data);
-}
-
-static inline void f2fs_clear_page_private(struct page *page)
-{
-       detach_page_private(page);
-}
-
 /*
  * file.c
  */
@@ -3302,7 +3399,6 @@ void f2fs_hash_filename(const struct inode *dir, struct f2fs_filename *fname);
 /*
  * node.c
  */
-struct dnode_of_data;
 struct node_info;
 
 int f2fs_check_nid_range(struct f2fs_sb_info *sbi, nid_t nid);
@@ -3379,6 +3475,7 @@ block_t f2fs_get_unusable_blocks(struct f2fs_sb_info *sbi);
 int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable);
 void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
 int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
+bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
 void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
@@ -3386,7 +3483,7 @@ void f2fs_get_new_segment(struct f2fs_sb_info *sbi,
                        unsigned int *newseg, bool new_sec, int dir);
 void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
                                        unsigned int start, unsigned int end);
-void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type);
+void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force);
 void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
 int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
 bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
@@ -3550,7 +3647,7 @@ void f2fs_destroy_post_read_wq(struct f2fs_sb_info *sbi);
 int f2fs_start_gc_thread(struct f2fs_sb_info *sbi);
 void f2fs_stop_gc_thread(struct f2fs_sb_info *sbi);
 block_t f2fs_start_bidx_of_node(unsigned int node_ofs, struct inode *inode);
-int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, bool background,
+int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, bool background, bool force,
                        unsigned int segno);
 void f2fs_build_gc_manager(struct f2fs_sb_info *sbi);
 int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count);
@@ -3562,6 +3659,8 @@ void f2fs_destroy_garbage_collection_cache(void);
  */
 int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only);
 bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi);
+int __init f2fs_create_recovery_cache(void);
+void f2fs_destroy_recovery_cache(void);
 
 /*
  * debug.c
@@ -3600,7 +3699,8 @@ struct f2fs_stat_info {
        unsigned int bimodal, avg_vblocks;
        int util_free, util_valid, util_invalid;
        int rsvd_segs, overp_segs;
-       int dirty_count, node_pages, meta_pages;
+       int dirty_count, node_pages, meta_pages, compress_pages;
+       int compress_page_hit;
        int prefree_count, call_count, cp_count, bg_cp_count;
        int tot_segs, node_segs, data_segs, free_segs, free_secs;
        int bg_node_segs, bg_data_segs;
@@ -3936,7 +4036,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page);
 bool f2fs_is_compress_backend_ready(struct inode *inode);
 int f2fs_init_compress_mempool(void);
 void f2fs_destroy_compress_mempool(void);
-void f2fs_end_read_compressed_page(struct page *page, bool failed);
+void f2fs_decompress_cluster(struct decompress_io_ctx *dic);
+void f2fs_end_read_compressed_page(struct page *page, bool failed,
+                                                       block_t blkaddr);
 bool f2fs_cluster_is_empty(struct compress_ctx *cc);
 bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index);
 void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page);
@@ -3952,12 +4054,33 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc);
 void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed);
 void f2fs_put_page_dic(struct page *page);
 int f2fs_init_compress_ctx(struct compress_ctx *cc);
-void f2fs_destroy_compress_ctx(struct compress_ctx *cc);
+void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse);
 void f2fs_init_compress_info(struct f2fs_sb_info *sbi);
+int f2fs_init_compress_inode(struct f2fs_sb_info *sbi);
+void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi);
 int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi);
 void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi);
 int __init f2fs_init_compress_cache(void);
 void f2fs_destroy_compress_cache(void);
+struct address_space *COMPRESS_MAPPING(struct f2fs_sb_info *sbi);
+void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, block_t blkaddr);
+void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page,
+                                               nid_t ino, block_t blkaddr);
+bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page,
+                                                               block_t blkaddr);
+void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino);
+#define inc_compr_inode_stat(inode)                                    \
+       do {                                                            \
+               struct f2fs_sb_info *sbi = F2FS_I_SB(inode);            \
+               sbi->compr_new_inode++;                                 \
+       } while (0)
+#define add_compr_block_stat(inode, blocks)                            \
+       do {                                                            \
+               struct f2fs_sb_info *sbi = F2FS_I_SB(inode);            \
+               int diff = F2FS_I(inode)->i_cluster_size - blocks;      \
+               sbi->compr_written_block += blocks;                     \
+               sbi->compr_saved_block += diff;                         \
+       } while (0)
 #else
 static inline bool f2fs_is_compressed_page(struct page *page) { return false; }
 static inline bool f2fs_is_compress_backend_ready(struct inode *inode)
@@ -3974,7 +4097,9 @@ static inline struct page *f2fs_compress_control_page(struct page *page)
 }
 static inline int f2fs_init_compress_mempool(void) { return 0; }
 static inline void f2fs_destroy_compress_mempool(void) { }
-static inline void f2fs_end_read_compressed_page(struct page *page, bool failed)
+static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { }
+static inline void f2fs_end_read_compressed_page(struct page *page,
+                                               bool failed, block_t blkaddr)
 {
        WARN_ON_ONCE(1);
 }
@@ -3982,10 +4107,21 @@ static inline void f2fs_put_page_dic(struct page *page)
 {
        WARN_ON_ONCE(1);
 }
+static inline int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) { return 0; }
+static inline void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) { }
 static inline int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) { return 0; }
 static inline void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi) { }
 static inline int __init f2fs_init_compress_cache(void) { return 0; }
 static inline void f2fs_destroy_compress_cache(void) { }
+static inline void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi,
+                               block_t blkaddr) { }
+static inline void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi,
+                               struct page *page, nid_t ino, block_t blkaddr) { }
+static inline bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi,
+                               struct page *page, block_t blkaddr) { return false; }
+static inline void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi,
+                                                       nid_t ino) { }
+#define inc_compr_inode_stat(inode)            do { } while (0)
 #endif
 
 static inline void set_compress_context(struct inode *inode)
@@ -4009,6 +4145,7 @@ static inline void set_compress_context(struct inode *inode)
        F2FS_I(inode)->i_flags |= F2FS_COMPR_FL;
        set_inode_flag(inode, FI_COMPRESSED_FILE);
        stat_inc_compr_inode(inode);
+       inc_compr_inode_stat(inode);
        f2fs_mark_inode_dirty_sync(inode, true);
 }
 
@@ -4048,6 +4185,27 @@ F2FS_FEATURE_FUNCS(verity, VERITY);
 F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM);
 F2FS_FEATURE_FUNCS(casefold, CASEFOLD);
 F2FS_FEATURE_FUNCS(compression, COMPRESSION);
+F2FS_FEATURE_FUNCS(readonly, RO);
+
+static inline bool f2fs_may_extent_tree(struct inode *inode)
+{
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+
+       if (!test_opt(sbi, EXTENT_CACHE) ||
+                       is_inode_flag_set(inode, FI_NO_EXTENT) ||
+                       (is_inode_flag_set(inode, FI_COMPRESSED_FILE) &&
+                        !f2fs_sb_has_readonly(sbi)))
+               return false;
+
+       /*
+        * for recovered files during mount do not create extents
+        * if shrinker is not registered.
+        */
+       if (list_empty(&sbi->s_list))
+               return false;
+
+       return S_ISREG(inode->i_mode);
+}
 
 #ifdef CONFIG_BLK_DEV_ZONED
 static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
@@ -4179,8 +4337,7 @@ static inline bool f2fs_force_buffered_io(struct inode *inode,
                if (F2FS_IO_ALIGNED(sbi))
                        return true;
        }
-       if (is_sbi_flag_set(F2FS_I_SB(inode), SBI_CP_DISABLED) &&
-                                       !IS_SWAPFILE(inode))
+       if (is_sbi_flag_set(F2FS_I_SB(inode), SBI_CP_DISABLED))
                return true;
 
        return false;