+++ /dev/null
-From 9aafb2b095b5ccb863934bc226baf5b74a63f109 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 1 Dec 2020 13:08:02 +0900
-Subject: f2fs: add compress_mode mount option
-
-From: Daeho Jeong <daehojeong@google.com>
-
-[ Upstream commit 602a16d58e9aab3c423bcf051033ea6c9e8a6d37 ]
-
-We will add a new "compress_mode" mount option to control file
-compression mode. This supports "fs" and "user". In "fs" mode (default),
-f2fs does automatic compression on the compression enabled files.
-In "user" mode, f2fs disables the automaic compression and gives the
-user discretion of choosing the target file and the timing. It means
-the user can do manual compression/decompression on the compression
-enabled files using ioctls.
-
-Signed-off-by: Daeho Jeong <daehojeong@google.com>
-Reviewed-by: Chao Yu <yuchao0@huawei.com>
-Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-Stable-dep-of: 7e1b150fece0 ("f2fs: compress: fix to avoid redundant compress extension")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- Documentation/filesystems/f2fs.rst | 35 ++++++++++++++++++++++++++++++
- fs/f2fs/compress.c | 2 +-
- fs/f2fs/data.c | 2 +-
- fs/f2fs/f2fs.h | 30 +++++++++++++++++++++++++
- fs/f2fs/segment.c | 2 +-
- fs/f2fs/super.c | 23 ++++++++++++++++++++
- 6 files changed, 91 insertions(+), 3 deletions(-)
-
-diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
-index 3d21a9e86995f..de2bacc418fee 100644
---- a/Documentation/filesystems/f2fs.rst
-+++ b/Documentation/filesystems/f2fs.rst
-@@ -261,6 +261,13 @@ compress_extension=%s Support adding specified extension, so that f2fs can enab
- Note that, there is one reserved special extension '*', it
- can be set to enable compression for all files.
- compress_chksum Support verifying chksum of raw data in compressed cluster.
-+compress_mode=%s Control file compression mode. This supports "fs" and "user"
-+ modes. In "fs" mode (default), f2fs does automatic compression
-+ on the compression enabled files. In "user" mode, f2fs disables
-+ the automaic compression and gives the user discretion of
-+ choosing the target file and the timing. The user can do manual
-+ compression/decompression on the compression enabled files using
-+ ioctls.
- inlinecrypt When possible, encrypt/decrypt the contents of encrypted
- files using the blk-crypto framework rather than
- filesystem-layer encryption. This allows the use of
-@@ -811,6 +818,34 @@ Compress metadata layout::
- | data length | data chksum | reserved | compressed data |
- +-------------+-------------+----------+----------------------------+
-
-+Compression mode
-+--------------------------
-+
-+f2fs supports "fs" and "user" compression modes with "compression_mode" mount option.
-+With this option, f2fs provides a choice to select the way how to compress the
-+compression enabled files (refer to "Compression implementation" section for how to
-+enable compression on a regular inode).
-+
-+1) compress_mode=fs
-+This is the default option. f2fs does automatic compression in the writeback of the
-+compression enabled files.
-+
-+2) compress_mode=user
-+This disables the automaic compression and gives the user discretion of choosing the
-+target file and the timing. The user can do manual compression/decompression on the
-+compression enabled files using F2FS_IOC_DECOMPRESS_FILE and F2FS_IOC_COMPRESS_FILE
-+ioctls like the below.
-+
-+To decompress a file,
-+
-+fd = open(filename, O_WRONLY, 0);
-+ret = ioctl(fd, F2FS_IOC_DECOMPRESS_FILE);
-+
-+To compress a file,
-+
-+fd = open(filename, O_WRONLY, 0);
-+ret = ioctl(fd, F2FS_IOC_COMPRESS_FILE);
-+
- NVMe Zoned Namespace devices
- ----------------------------
-
-diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
-index db8360ae96caf..8da6df3bfb03f 100644
---- a/fs/f2fs/compress.c
-+++ b/fs/f2fs/compress.c
-@@ -929,7 +929,7 @@ int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index)
-
- static bool cluster_may_compress(struct compress_ctx *cc)
- {
-- if (!f2fs_compressed_file(cc->inode))
-+ if (!f2fs_need_compress_data(cc->inode))
- return false;
- if (f2fs_is_atomic_file(cc->inode))
- return false;
-diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
-index e0533cffbb076..fc6c88e80cf4f 100644
---- a/fs/f2fs/data.c
-+++ b/fs/f2fs/data.c
-@@ -3222,7 +3222,7 @@ static inline bool __should_serialize_io(struct inode *inode,
- if (IS_NOQUOTA(inode))
- return false;
-
-- if (f2fs_compressed_file(inode))
-+ if (f2fs_need_compress_data(inode))
- return true;
- if (wbc->sync_mode != WB_SYNC_ALL)
- return true;
-diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
-index 6dfefbf54917d..6a9f4dcea06d6 100644
---- a/fs/f2fs/f2fs.h
-+++ b/fs/f2fs/f2fs.h
-@@ -150,6 +150,7 @@ struct f2fs_mount_info {
- unsigned char compress_log_size; /* cluster log size */
- bool compress_chksum; /* compressed data chksum */
- unsigned char compress_ext_cnt; /* extension count */
-+ int compress_mode; /* compression mode */
- unsigned char extensions[COMPRESS_EXT_NUM][F2FS_EXTENSION_LEN]; /* extensions */
- };
-
-@@ -681,6 +682,7 @@ enum {
- FI_COMPRESSED_FILE, /* indicate file's data can be compressed */
- 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_MAX, /* max flag, never be used */
- };
-
-@@ -1255,6 +1257,18 @@ enum fsync_mode {
- FSYNC_MODE_NOBARRIER, /* fsync behaves nobarrier based on posix */
- };
-
-+enum {
-+ COMPR_MODE_FS, /*
-+ * automatically compress compression
-+ * enabled files
-+ */
-+ COMPR_MODE_USER, /*
-+ * automatical compression is disabled.
-+ * user can control the file compression
-+ * using ioctls
-+ */
-+};
-+
- /*
- * 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.
-@@ -2795,6 +2809,22 @@ static inline int f2fs_compressed_file(struct inode *inode)
- is_inode_flag_set(inode, FI_COMPRESSED_FILE);
- }
-
-+static inline bool f2fs_need_compress_data(struct inode *inode)
-+{
-+ int compress_mode = F2FS_OPTION(F2FS_I_SB(inode)).compress_mode;
-+
-+ if (!f2fs_compressed_file(inode))
-+ return false;
-+
-+ if (compress_mode == COMPR_MODE_FS)
-+ return true;
-+ else if (compress_mode == COMPR_MODE_USER &&
-+ is_inode_flag_set(inode, FI_ENABLE_COMPRESS))
-+ return true;
-+
-+ return false;
-+}
-+
- static inline unsigned int addrs_per_inode(struct inode *inode)
- {
- unsigned int addrs = CUR_ADDRS_PER_INODE(inode) -
-diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
-index a27a934292715..ad30908ac99f3 100644
---- a/fs/f2fs/segment.c
-+++ b/fs/f2fs/segment.c
-@@ -3296,7 +3296,7 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
- else
- return CURSEG_COLD_DATA;
- }
-- if (file_is_cold(inode) || f2fs_compressed_file(inode))
-+ if (file_is_cold(inode) || f2fs_need_compress_data(inode))
- return CURSEG_COLD_DATA;
- if (file_is_hot(inode) ||
- is_inode_flag_set(inode, FI_HOT_DATA) ||
-diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
-index 065aa01958e95..1281b59da6a2a 100644
---- a/fs/f2fs/super.c
-+++ b/fs/f2fs/super.c
-@@ -147,6 +147,7 @@ enum {
- Opt_compress_log_size,
- Opt_compress_extension,
- Opt_compress_chksum,
-+ Opt_compress_mode,
- Opt_atgc,
- Opt_err,
- };
-@@ -216,6 +217,7 @@ static match_table_t f2fs_tokens = {
- {Opt_compress_log_size, "compress_log_size=%u"},
- {Opt_compress_extension, "compress_extension=%s"},
- {Opt_compress_chksum, "compress_chksum"},
-+ {Opt_compress_mode, "compress_mode=%s"},
- {Opt_atgc, "atgc"},
- {Opt_err, NULL},
- };
-@@ -979,11 +981,26 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- case Opt_compress_chksum:
- F2FS_OPTION(sbi).compress_chksum = true;
- break;
-+ case Opt_compress_mode:
-+ name = match_strdup(&args[0]);
-+ if (!name)
-+ return -ENOMEM;
-+ if (!strcmp(name, "fs")) {
-+ F2FS_OPTION(sbi).compress_mode = COMPR_MODE_FS;
-+ } else if (!strcmp(name, "user")) {
-+ F2FS_OPTION(sbi).compress_mode = COMPR_MODE_USER;
-+ } else {
-+ kfree(name);
-+ return -EINVAL;
-+ }
-+ kfree(name);
-+ break;
- #else
- case Opt_compress_algorithm:
- case Opt_compress_log_size:
- case Opt_compress_extension:
- case Opt_compress_chksum:
-+ case Opt_compress_mode:
- f2fs_info(sbi, "compression options not supported");
- break;
- #endif
-@@ -1571,6 +1588,11 @@ static inline void f2fs_show_compress_options(struct seq_file *seq,
-
- if (F2FS_OPTION(sbi).compress_chksum)
- seq_puts(seq, ",compress_chksum");
-+
-+ if (F2FS_OPTION(sbi).compress_mode == COMPR_MODE_FS)
-+ seq_printf(seq, ",compress_mode=%s", "fs");
-+ else if (F2FS_OPTION(sbi).compress_mode == COMPR_MODE_USER)
-+ seq_printf(seq, ",compress_mode=%s", "user");
- }
-
- static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
-@@ -1720,6 +1742,7 @@ static void default_options(struct f2fs_sb_info *sbi)
- F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZ4;
- F2FS_OPTION(sbi).compress_log_size = MIN_COMPRESS_LOG_SIZE;
- F2FS_OPTION(sbi).compress_ext_cnt = 0;
-+ F2FS_OPTION(sbi).compress_mode = COMPR_MODE_FS;
- F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_ON;
-
- sbi->sb->s_flags &= ~SB_INLINECRYPT;
---
-2.42.0
-
+++ /dev/null
-From 107a40f56eb74851697bb37513bc058300424cb8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 8 Jun 2021 19:15:08 +0800
-Subject: f2fs: compress: add nocompress extensions support
-
-From: Fengnan Chang <changfengnan@vivo.com>
-
-[ Upstream commit 151b1982be5d9f4ca641687ee1a4bb4fba5d26cf ]
-
-When we create a directory with enable compression, all file write into
-directory will try to compress.But sometimes we may know, new file
-cannot meet compression ratio requirements.
-We need a nocompress extension to skip those files to avoid unnecessary
-compress page test.
-
-After add nocompress_extension, the priority should be:
-dir_flag < comp_extention,nocompress_extension < comp_file_flag,
-no_comp_file_flag.
-
-Priority in between FS_COMPR_FL, FS_NOCOMP_FS, extensions:
- * compress_extension=so; nocompress_extension=zip; chattr +c dir;
- touch dir/foo.so; touch dir/bar.zip; touch dir/baz.txt; then foo.so
- and baz.txt should be compresse, bar.zip should be non-compressed.
- chattr +c dir/bar.zip can enable compress on bar.zip.
- * compress_extension=so; nocompress_extension=zip; chattr -c dir;
- touch dir/foo.so; touch dir/bar.zip; touch dir/baz.txt; then foo.so
- should be compresse, bar.zip and baz.txt should be non-compressed.
- chattr+c dir/bar.zip; chattr+c dir/baz.txt; can enable compress on
- bar.zip and baz.txt.
-
-Signed-off-by: Fengnan Chang <changfengnan@vivo.com>
-Reviewed-by: Chao Yu <chao@kernel.org>
-Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-Stable-dep-of: 7e1b150fece0 ("f2fs: compress: fix to avoid redundant compress extension")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- Documentation/filesystems/f2fs.rst | 31 +++++++++++-
- fs/f2fs/f2fs.h | 2 +
- fs/f2fs/namei.c | 20 ++++++--
- fs/f2fs/super.c | 79 +++++++++++++++++++++++++++++-
- 4 files changed, 125 insertions(+), 7 deletions(-)
-
-diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
-index 9e302d3dd85a6..ae7b9fe07d5c8 100644
---- a/Documentation/filesystems/f2fs.rst
-+++ b/Documentation/filesystems/f2fs.rst
-@@ -265,6 +265,18 @@ compress_extension=%s Support adding specified extension, so that f2fs can enab
- For other files, we can still enable compression via ioctl.
- Note that, there is one reserved special extension '*', it
- can be set to enable compression for all files.
-+nocompress_extension=%s Support adding specified extension, so that f2fs can disable
-+ compression on those corresponding files, just contrary to compression extension.
-+ If you know exactly which files cannot be compressed, you can use this.
-+ The same extension name can't appear in both compress and nocompress
-+ extension at the same time.
-+ If the compress extension specifies all files, the types specified by the
-+ nocompress extension will be treated as special cases and will not be compressed.
-+ Don't allow use '*' to specifie all file in nocompress extension.
-+ After add nocompress_extension, the priority should be:
-+ dir_flag < comp_extention,nocompress_extension < comp_file_flag,no_comp_file_flag.
-+ See more in compression sections.
-+
- compress_chksum Support verifying chksum of raw data in compressed cluster.
- compress_mode=%s Control file compression mode. This supports "fs" and "user"
- modes. In "fs" mode (default), f2fs does automatic compression
-@@ -798,13 +810,30 @@ Compression implementation
- all logical blocks in cluster contain valid data and compress ratio of
- cluster data is lower than specified threshold.
-
--- To enable compression on regular inode, there are three ways:
-+- To enable compression on regular inode, there are four ways:
-
- * chattr +c file
- * chattr +c dir; touch dir/file
- * mount w/ -o compress_extension=ext; touch file.ext
- * mount w/ -o compress_extension=*; touch any_file
-
-+- To disable compression on regular inode, there are two ways:
-+
-+ * chattr -c file
-+ * mount w/ -o nocompress_extension=ext; touch file.ext
-+
-+- Priority in between FS_COMPR_FL, FS_NOCOMP_FS, extensions:
-+
-+ * compress_extension=so; nocompress_extension=zip; chattr +c dir; touch
-+ dir/foo.so; touch dir/bar.zip; touch dir/baz.txt; then foo.so and baz.txt
-+ should be compresse, bar.zip should be non-compressed. chattr +c dir/bar.zip
-+ can enable compress on bar.zip.
-+ * compress_extension=so; nocompress_extension=zip; chattr -c dir; touch
-+ dir/foo.so; touch dir/bar.zip; touch dir/baz.txt; then foo.so should be
-+ compresse, bar.zip and baz.txt should be non-compressed.
-+ chattr+c dir/bar.zip; chattr+c dir/baz.txt; can enable compress on bar.zip
-+ and baz.txt.
-+
- - At this point, compression feature doesn't expose compressed space to user
- directly in order to guarantee potential data updates later to the space.
- Instead, the main goal is to reduce data writes to flash disk as much as
-diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
-index 01e365aefbc97..cda5dbda7f86d 100644
---- a/fs/f2fs/f2fs.h
-+++ b/fs/f2fs/f2fs.h
-@@ -151,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
-diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
-index 72b109685db47..516b7d27336ec 100644
---- a/fs/f2fs/namei.c
-+++ b/fs/f2fs/namei.c
-@@ -289,14 +289,16 @@ static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode,
- const unsigned char *name)
- {
- __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
-- unsigned char (*ext)[F2FS_EXTENSION_LEN];
-- unsigned int ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt;
-+ unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions;
-+ unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions;
-+ unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt;
-+ unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt;
- int i, cold_count, hot_count;
-
- if (!f2fs_sb_has_compression(sbi) ||
-- is_inode_flag_set(inode, FI_COMPRESSED_FILE) ||
- F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL ||
-- !f2fs_may_compress(inode))
-+ !f2fs_may_compress(inode) ||
-+ (!ext_cnt && !noext_cnt))
- return;
-
- down_read(&sbi->sb_lock);
-@@ -313,7 +315,15 @@ static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode,
-
- up_read(&sbi->sb_lock);
-
-- ext = F2FS_OPTION(sbi).extensions;
-+ for (i = 0; i < noext_cnt; i++) {
-+ if (is_extension_exist(name, noext[i], false)) {
-+ f2fs_disable_compressed_file(inode);
-+ return;
-+ }
-+ }
-+
-+ if (is_inode_flag_set(inode, FI_COMPRESSED_FILE))
-+ return;
-
- for (i = 0; i < ext_cnt; i++) {
- if (!is_extension_exist(name, ext[i], false))
-diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
-index d49160328d53b..daae61df66ffa 100644
---- a/fs/f2fs/super.c
-+++ b/fs/f2fs/super.c
-@@ -148,6 +148,7 @@ enum {
- Opt_compress_algorithm,
- Opt_compress_log_size,
- Opt_compress_extension,
-+ Opt_nocompress_extension,
- Opt_compress_chksum,
- Opt_compress_mode,
- Opt_atgc,
-@@ -218,6 +219,7 @@ static match_table_t f2fs_tokens = {
- {Opt_compress_algorithm, "compress_algorithm=%s"},
- {Opt_compress_log_size, "compress_log_size=%u"},
- {Opt_compress_extension, "compress_extension=%s"},
-+ {Opt_nocompress_extension, "nocompress_extension=%s"},
- {Opt_compress_chksum, "compress_chksum"},
- {Opt_compress_mode, "compress_mode=%s"},
- {Opt_atgc, "atgc"},
-@@ -507,6 +509,43 @@ static int f2fs_set_test_dummy_encryption(struct super_block *sb,
- }
-
- #ifdef CONFIG_F2FS_FS_COMPRESSION
-+/*
-+ * 1. The same extension name cannot not appear in both compress and non-compress extension
-+ * at the same time.
-+ * 2. If the compress extension specifies all files, the types specified by the non-compress
-+ * extension will be treated as special cases and will not be compressed.
-+ * 3. Don't allow the non-compress extension specifies all files.
-+ */
-+static int f2fs_test_compress_extension(struct f2fs_sb_info *sbi)
-+{
-+ unsigned char (*ext)[F2FS_EXTENSION_LEN];
-+ unsigned char (*noext)[F2FS_EXTENSION_LEN];
-+ int ext_cnt, noext_cnt, index = 0, no_index = 0;
-+
-+ ext = F2FS_OPTION(sbi).extensions;
-+ ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt;
-+ noext = F2FS_OPTION(sbi).noextensions;
-+ noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt;
-+
-+ if (!noext_cnt)
-+ return 0;
-+
-+ for (no_index = 0; no_index < noext_cnt; no_index++) {
-+ if (!strcasecmp("*", noext[no_index])) {
-+ f2fs_info(sbi, "Don't allow the nocompress extension specifies all files");
-+ return -EINVAL;
-+ }
-+ for (index = 0; index < ext_cnt; index++) {
-+ if (!strcasecmp(ext[index], noext[no_index])) {
-+ f2fs_info(sbi, "Don't allow the same extension %s appear in both compress and nocompress extension",
-+ ext[index]);
-+ return -EINVAL;
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
- #ifdef CONFIG_F2FS_FS_LZ4
- static int f2fs_set_lz4hc_level(struct f2fs_sb_info *sbi, const char *str)
- {
-@@ -580,7 +619,8 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- substring_t args[MAX_OPT_ARGS];
- #ifdef CONFIG_F2FS_FS_COMPRESSION
- unsigned char (*ext)[F2FS_EXTENSION_LEN];
-- int ext_cnt;
-+ unsigned char (*noext)[F2FS_EXTENSION_LEN];
-+ int ext_cnt, noext_cnt;
- #endif
- char *p, *name;
- int arg = 0;
-@@ -1076,6 +1116,30 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- F2FS_OPTION(sbi).compress_ext_cnt++;
- kfree(name);
- break;
-+ case Opt_nocompress_extension:
-+ if (!f2fs_sb_has_compression(sbi)) {
-+ f2fs_info(sbi, "Image doesn't support compression");
-+ break;
-+ }
-+ name = match_strdup(&args[0]);
-+ if (!name)
-+ return -ENOMEM;
-+
-+ noext = F2FS_OPTION(sbi).noextensions;
-+ noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt;
-+
-+ if (strlen(name) >= F2FS_EXTENSION_LEN ||
-+ noext_cnt >= COMPRESS_EXT_NUM) {
-+ f2fs_err(sbi,
-+ "invalid extension length/number");
-+ kfree(name);
-+ return -EINVAL;
-+ }
-+
-+ strcpy(noext[noext_cnt], name);
-+ F2FS_OPTION(sbi).nocompress_ext_cnt++;
-+ kfree(name);
-+ break;
- case Opt_compress_chksum:
- F2FS_OPTION(sbi).compress_chksum = true;
- break;
-@@ -1097,6 +1161,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- case Opt_compress_algorithm:
- case Opt_compress_log_size:
- case Opt_compress_extension:
-+ case Opt_nocompress_extension:
- case Opt_compress_chksum:
- case Opt_compress_mode:
- f2fs_info(sbi, "compression options not supported");
-@@ -1143,6 +1208,13 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- }
- #endif
-
-+#ifdef CONFIG_F2FS_FS_COMPRESSION
-+ if (f2fs_test_compress_extension(sbi)) {
-+ f2fs_err(sbi, "invalid compress or nocompress extension");
-+ return -EINVAL;
-+ }
-+#endif
-+
- if (F2FS_IO_SIZE_BITS(sbi) && !f2fs_lfs_mode(sbi)) {
- f2fs_err(sbi, "Should set mode=lfs with %uKB-sized IO",
- F2FS_IO_SIZE_KB(sbi));
-@@ -1687,6 +1759,11 @@ static inline void f2fs_show_compress_options(struct seq_file *seq,
- F2FS_OPTION(sbi).extensions[i]);
- }
-
-+ for (i = 0; i < F2FS_OPTION(sbi).nocompress_ext_cnt; i++) {
-+ seq_printf(seq, ",nocompress_extension=%s",
-+ F2FS_OPTION(sbi).noextensions[i]);
-+ }
-+
- if (F2FS_OPTION(sbi).compress_chksum)
- seq_puts(seq, ",compress_chksum");
-
---
-2.42.0
-
+++ /dev/null
-From 3686432492655f3f63be1a9f4ace7100a2b01264 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 22 Jan 2021 17:40:13 +0800
-Subject: f2fs: compress: deny setting unsupported compress algorithm
-
-From: Chao Yu <yuchao0@huawei.com>
-
-[ Upstream commit 32be0e97c71366a19d11d1965e3f0957ea0be609 ]
-
-If kernel doesn't support certain kinds of compress algorithm, deny to set
-them as compress algorithm of f2fs via 'compress_algorithm=%s' mount option.
-
-Signed-off-by: Chao Yu <yuchao0@huawei.com>
-Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-Stable-dep-of: 7e1b150fece0 ("f2fs: compress: fix to avoid redundant compress extension")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/f2fs/super.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
-diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
-index 1281b59da6a2a..e66c2de29eebc 100644
---- a/fs/f2fs/super.c
-+++ b/fs/f2fs/super.c
-@@ -922,17 +922,33 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- if (!name)
- return -ENOMEM;
- if (!strcmp(name, "lzo")) {
-+#ifdef CONFIG_F2FS_FS_LZO
- F2FS_OPTION(sbi).compress_algorithm =
- COMPRESS_LZO;
-+#else
-+ f2fs_info(sbi, "kernel doesn't support lzo compression");
-+#endif
- } else if (!strcmp(name, "lz4")) {
-+#ifdef CONFIG_F2FS_FS_LZ4
- F2FS_OPTION(sbi).compress_algorithm =
- COMPRESS_LZ4;
-+#else
-+ f2fs_info(sbi, "kernel doesn't support lz4 compression");
-+#endif
- } else if (!strcmp(name, "zstd")) {
-+#ifdef CONFIG_F2FS_FS_ZSTD
- F2FS_OPTION(sbi).compress_algorithm =
- COMPRESS_ZSTD;
-+#else
-+ f2fs_info(sbi, "kernel doesn't support zstd compression");
-+#endif
- } else if (!strcmp(name, "lzo-rle")) {
-+#ifdef CONFIG_F2FS_FS_LZORLE
- F2FS_OPTION(sbi).compress_algorithm =
- COMPRESS_LZORLE;
-+#else
-+ f2fs_info(sbi, "kernel doesn't support lzorle compression");
-+#endif
- } else {
- kfree(name);
- return -EINVAL;
---
-2.42.0
-
+++ /dev/null
-From 5c3751456274b97529ba7ac9604c690797d021ae Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 28 Aug 2023 22:04:17 +0800
-Subject: f2fs: compress: fix to avoid redundant compress extension
-
-From: Chao Yu <chao@kernel.org>
-
-[ Upstream commit 7e1b150fece033703a824df1bbc03df091ea53cc ]
-
-With below script, redundant compress extension will be parsed and added
-by parse_options(), because parse_options() doesn't check whether the
-extension is existed or not, fix it.
-
-1. mount -t f2fs -o compress_extension=so /dev/vdb /mnt/f2fs
-2. mount -t f2fs -o remount,compress_extension=so /mnt/f2fs
-3. mount|grep f2fs
-
-/dev/vdb on /mnt/f2fs type f2fs (...,compress_extension=so,compress_extension=so,...)
-
-Fixes: 4c8ff7095bef ("f2fs: support data compression")
-Fixes: 151b1982be5d ("f2fs: compress: add nocompress extensions support")
-Signed-off-by: Chao Yu <chao@kernel.org>
-Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/f2fs/super.c | 33 +++++++++++++++++++++++++++++++++
- 1 file changed, 33 insertions(+)
-
-diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
-index daae61df66ffa..e40bc0aeb7fb5 100644
---- a/fs/f2fs/super.c
-+++ b/fs/f2fs/super.c
-@@ -509,6 +509,29 @@ static int f2fs_set_test_dummy_encryption(struct super_block *sb,
- }
-
- #ifdef CONFIG_F2FS_FS_COMPRESSION
-+static bool is_compress_extension_exist(struct f2fs_sb_info *sbi,
-+ const char *new_ext, bool is_ext)
-+{
-+ unsigned char (*ext)[F2FS_EXTENSION_LEN];
-+ int ext_cnt;
-+ int i;
-+
-+ if (is_ext) {
-+ ext = F2FS_OPTION(sbi).extensions;
-+ ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt;
-+ } else {
-+ ext = F2FS_OPTION(sbi).noextensions;
-+ ext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt;
-+ }
-+
-+ for (i = 0; i < ext_cnt; i++) {
-+ if (!strcasecmp(new_ext, ext[i]))
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
- /*
- * 1. The same extension name cannot not appear in both compress and non-compress extension
- * at the same time.
-@@ -1112,6 +1135,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- return -EINVAL;
- }
-
-+ if (is_compress_extension_exist(sbi, name, true)) {
-+ kfree(name);
-+ break;
-+ }
-+
- strcpy(ext[ext_cnt], name);
- F2FS_OPTION(sbi).compress_ext_cnt++;
- kfree(name);
-@@ -1136,6 +1164,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- return -EINVAL;
- }
-
-+ if (is_compress_extension_exist(sbi, name, false)) {
-+ kfree(name);
-+ break;
-+ }
-+
- strcpy(noext[noext_cnt], name);
- F2FS_OPTION(sbi).nocompress_ext_cnt++;
- kfree(name);
---
-2.42.0
-
+++ /dev/null
-From 0e566ca04faea90c08bd9b41a63f414ce7b65480 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 26 Nov 2020 18:32:09 +0800
-Subject: f2fs: compress: support chksum
-
-From: Chao Yu <yuchao0@huawei.com>
-
-[ Upstream commit b28f047b28c51d0b9864c34b097bb0b221ea7247 ]
-
-This patch supports to store chksum value with compressed
-data, and verify the integrality of compressed data while
-reading the data.
-
-The feature can be enabled through specifying mount option
-'compress_chksum'.
-
-Signed-off-by: Chao Yu <yuchao0@huawei.com>
-Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-Stable-dep-of: 7e1b150fece0 ("f2fs: compress: fix to avoid redundant compress extension")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- Documentation/filesystems/f2fs.rst | 1 +
- fs/f2fs/compress.c | 23 +++++++++++++++++++++++
- fs/f2fs/f2fs.h | 16 ++++++++++++++--
- fs/f2fs/inode.c | 3 +++
- fs/f2fs/super.c | 9 +++++++++
- include/linux/f2fs_fs.h | 2 +-
- 6 files changed, 51 insertions(+), 3 deletions(-)
-
-diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
-index 8c0fbdd8ce6fb..3d21a9e86995f 100644
---- a/Documentation/filesystems/f2fs.rst
-+++ b/Documentation/filesystems/f2fs.rst
-@@ -260,6 +260,7 @@ compress_extension=%s Support adding specified extension, so that f2fs can enab
- For other files, we can still enable compression via ioctl.
- Note that, there is one reserved special extension '*', it
- can be set to enable compression for all files.
-+compress_chksum Support verifying chksum of raw data in compressed cluster.
- inlinecrypt When possible, encrypt/decrypt the contents of encrypted
- files using the blk-crypto framework rather than
- filesystem-layer encryption. This allows the use of
-diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
-index 1be9de40f0b5a..db8360ae96caf 100644
---- a/fs/f2fs/compress.c
-+++ b/fs/f2fs/compress.c
-@@ -589,6 +589,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
- f2fs_cops[fi->i_compress_algorithm];
- unsigned int max_len, new_nr_cpages;
- struct page **new_cpages;
-+ u32 chksum = 0;
- int i, ret;
-
- trace_f2fs_compress_pages_start(cc->inode, cc->cluster_idx,
-@@ -642,6 +643,11 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
-
- cc->cbuf->clen = cpu_to_le32(cc->clen);
-
-+ if (fi->i_compress_flag & 1 << COMPRESS_CHKSUM)
-+ chksum = f2fs_crc32(F2FS_I_SB(cc->inode),
-+ cc->cbuf->cdata, cc->clen);
-+ cc->cbuf->chksum = cpu_to_le32(chksum);
-+
- for (i = 0; i < COMPRESS_DATA_RESERVED_SIZE; i++)
- cc->cbuf->reserved[i] = cpu_to_le32(0);
-
-@@ -777,6 +783,23 @@ void f2fs_decompress_pages(struct bio *bio, struct page *page, bool verity)
-
- ret = cops->decompress_pages(dic);
-
-+ if (!ret && fi->i_compress_flag & 1 << COMPRESS_CHKSUM) {
-+ u32 provided = le32_to_cpu(dic->cbuf->chksum);
-+ u32 calculated = f2fs_crc32(sbi, dic->cbuf->cdata, dic->clen);
-+
-+ if (provided != calculated) {
-+ if (!is_inode_flag_set(dic->inode, FI_COMPRESS_CORRUPT)) {
-+ set_inode_flag(dic->inode, FI_COMPRESS_CORRUPT);
-+ printk_ratelimited(
-+ "%sF2FS-fs (%s): checksum invalid, nid = %lu, %x vs %x",
-+ KERN_INFO, sbi->sb->s_id, dic->inode->i_ino,
-+ provided, calculated);
-+ }
-+ set_sbi_flag(sbi, SBI_NEED_FSCK);
-+ WARN_ON_ONCE(1);
-+ }
-+ }
-+
- out_vunmap_cbuf:
- vm_unmap_ram(dic->cbuf, dic->nr_cpages);
- out_vunmap_rbuf:
-diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
-index 83ebc860508b0..6dfefbf54917d 100644
---- a/fs/f2fs/f2fs.h
-+++ b/fs/f2fs/f2fs.h
-@@ -147,7 +147,8 @@ struct f2fs_mount_info {
-
- /* For compression */
- unsigned char compress_algorithm; /* algorithm type */
-- unsigned compress_log_size; /* cluster log size */
-+ unsigned char compress_log_size; /* cluster log size */
-+ bool compress_chksum; /* compressed data chksum */
- unsigned char compress_ext_cnt; /* extension count */
- unsigned char extensions[COMPRESS_EXT_NUM][F2FS_EXTENSION_LEN]; /* extensions */
- };
-@@ -678,6 +679,7 @@ enum {
- FI_ATOMIC_REVOKE_REQUEST, /* request to drop atomic data */
- FI_VERITY_IN_PROGRESS, /* building fs-verity Merkle tree */
- FI_COMPRESSED_FILE, /* indicate file's data can be compressed */
-+ FI_COMPRESS_CORRUPT, /* indicate compressed cluster is corrupted */
- FI_MMAP_FILE, /* indicate file was mmapped */
- FI_MAX, /* max flag, never be used */
- };
-@@ -736,6 +738,7 @@ struct f2fs_inode_info {
- atomic_t i_compr_blocks; /* # of compressed blocks */
- unsigned char i_compress_algorithm; /* algorithm type */
- unsigned char i_log_cluster_size; /* log of cluster size */
-+ unsigned short i_compress_flag; /* compress flag */
- unsigned int i_cluster_size; /* cluster size */
- };
-
-@@ -1281,9 +1284,15 @@ enum compress_algorithm_type {
- COMPRESS_MAX,
- };
-
--#define COMPRESS_DATA_RESERVED_SIZE 5
-+enum compress_flag {
-+ COMPRESS_CHKSUM,
-+ COMPRESS_MAX_FLAG,
-+};
-+
-+#define COMPRESS_DATA_RESERVED_SIZE 4
- struct compress_data {
- __le32 clen; /* compressed data size */
-+ __le32 chksum; /* compressed data chksum */
- __le32 reserved[COMPRESS_DATA_RESERVED_SIZE]; /* reserved */
- u8 cdata[]; /* compressed data */
- };
-@@ -3925,6 +3934,9 @@ static inline void set_compress_context(struct inode *inode)
- F2FS_OPTION(sbi).compress_algorithm;
- F2FS_I(inode)->i_log_cluster_size =
- F2FS_OPTION(sbi).compress_log_size;
-+ F2FS_I(inode)->i_compress_flag =
-+ F2FS_OPTION(sbi).compress_chksum ?
-+ 1 << COMPRESS_CHKSUM : 0;
- F2FS_I(inode)->i_cluster_size =
- 1 << F2FS_I(inode)->i_log_cluster_size;
- F2FS_I(inode)->i_flags |= F2FS_COMPR_FL;
-diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
-index 87752550f78c8..3e98551f4186d 100644
---- a/fs/f2fs/inode.c
-+++ b/fs/f2fs/inode.c
-@@ -455,6 +455,7 @@ static int do_read_inode(struct inode *inode)
- le64_to_cpu(ri->i_compr_blocks));
- fi->i_compress_algorithm = ri->i_compress_algorithm;
- fi->i_log_cluster_size = ri->i_log_cluster_size;
-+ fi->i_compress_flag = le16_to_cpu(ri->i_compress_flag);
- fi->i_cluster_size = 1 << fi->i_log_cluster_size;
- set_inode_flag(inode, FI_COMPRESSED_FILE);
- }
-@@ -633,6 +634,8 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page)
- &F2FS_I(inode)->i_compr_blocks));
- ri->i_compress_algorithm =
- F2FS_I(inode)->i_compress_algorithm;
-+ ri->i_compress_flag =
-+ cpu_to_le16(F2FS_I(inode)->i_compress_flag);
- ri->i_log_cluster_size =
- F2FS_I(inode)->i_log_cluster_size;
- }
-diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
-index 9a74d60f61dba..065aa01958e95 100644
---- a/fs/f2fs/super.c
-+++ b/fs/f2fs/super.c
-@@ -146,6 +146,7 @@ enum {
- Opt_compress_algorithm,
- Opt_compress_log_size,
- Opt_compress_extension,
-+ Opt_compress_chksum,
- Opt_atgc,
- Opt_err,
- };
-@@ -214,6 +215,7 @@ static match_table_t f2fs_tokens = {
- {Opt_compress_algorithm, "compress_algorithm=%s"},
- {Opt_compress_log_size, "compress_log_size=%u"},
- {Opt_compress_extension, "compress_extension=%s"},
-+ {Opt_compress_chksum, "compress_chksum"},
- {Opt_atgc, "atgc"},
- {Opt_err, NULL},
- };
-@@ -974,10 +976,14 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- F2FS_OPTION(sbi).compress_ext_cnt++;
- kfree(name);
- break;
-+ case Opt_compress_chksum:
-+ F2FS_OPTION(sbi).compress_chksum = true;
-+ break;
- #else
- case Opt_compress_algorithm:
- case Opt_compress_log_size:
- case Opt_compress_extension:
-+ case Opt_compress_chksum:
- f2fs_info(sbi, "compression options not supported");
- break;
- #endif
-@@ -1562,6 +1568,9 @@ static inline void f2fs_show_compress_options(struct seq_file *seq,
- seq_printf(seq, ",compress_extension=%s",
- F2FS_OPTION(sbi).extensions[i]);
- }
-+
-+ if (F2FS_OPTION(sbi).compress_chksum)
-+ seq_puts(seq, ",compress_chksum");
- }
-
- static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
-diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
-index a5dbb57a687fb..7dc2a06cf19a1 100644
---- a/include/linux/f2fs_fs.h
-+++ b/include/linux/f2fs_fs.h
-@@ -273,7 +273,7 @@ struct f2fs_inode {
- __le64 i_compr_blocks; /* # of compressed blocks */
- __u8 i_compress_algorithm; /* compress algorithm */
- __u8 i_log_cluster_size; /* log of cluster size */
-- __le16 i_padding; /* padding */
-+ __le16 i_compress_flag; /* compress flag */
- __le32 i_extra_end[0]; /* for attribute size calculation */
- } __packed;
- __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */
---
-2.42.0
-
+++ /dev/null
-From c8c1c276f06b50c27eab63cd2b78ce81236b8d1e Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 22 Jan 2021 17:46:43 +0800
-Subject: f2fs: compress: support compress level
-
-From: Chao Yu <yuchao0@huawei.com>
-
-[ Upstream commit 3fde13f817e23f05ce407d136325df4cbc913e67 ]
-
-Expand 'compress_algorithm' mount option to accept parameter as format of
-<algorithm>:<level>, by this way, it gives a way to allow user to do more
-specified config on lz4 and zstd compression level, then f2fs compression
-can provide higher compress ratio.
-
-In order to set compress level for lz4 algorithm, it needs to set
-CONFIG_LZ4HC_COMPRESS and CONFIG_F2FS_FS_LZ4HC config to enable lz4hc
-compress algorithm.
-
-CR and performance number on lz4/lz4hc algorithm:
-
-dd if=enwik9 of=compressed_file conv=fsync
-
-Original blocks: 244382
-
- lz4 lz4hc-9
-compressed blocks 170647 163270
-compress ratio 69.8% 66.8%
-speed 16.4207 s, 60.9 MB/s 26.7299 s, 37.4 MB/s
-
-compress ratio = after / before
-
-Signed-off-by: Chao Yu <yuchao0@huawei.com>
-Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-Stable-dep-of: 7e1b150fece0 ("f2fs: compress: fix to avoid redundant compress extension")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- Documentation/filesystems/f2fs.rst | 5 ++
- fs/f2fs/Kconfig | 10 ++++
- fs/f2fs/compress.c | 41 +++++++++++++-
- fs/f2fs/f2fs.h | 9 +++
- fs/f2fs/super.c | 89 +++++++++++++++++++++++++++++-
- include/linux/f2fs_fs.h | 3 +
- 6 files changed, 152 insertions(+), 5 deletions(-)
-
-diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
-index de2bacc418fee..4f51c0be22c45 100644
---- a/Documentation/filesystems/f2fs.rst
-+++ b/Documentation/filesystems/f2fs.rst
-@@ -249,6 +249,11 @@ checkpoint=%s[:%u[%]] Set to "disable" to turn off checkpointing. Set to "enabl
- This space is reclaimed once checkpoint=enable.
- compress_algorithm=%s Control compress algorithm, currently f2fs supports "lzo",
- "lz4", "zstd" and "lzo-rle" algorithm.
-+compress_algorithm=%s:%d Control compress algorithm and its compress level, now, only
-+ "lz4" and "zstd" support compress level config.
-+ algorithm level range
-+ lz4 3 - 16
-+ zstd 1 - 22
- compress_log_size=%u Support configuring compress cluster size, the size will
- be 4KB * (1 << %u), 16KB is minimum size, also it's
- default size.
-diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig
-index d13c5c6a97876..63c1fc1a0e3b2 100644
---- a/fs/f2fs/Kconfig
-+++ b/fs/f2fs/Kconfig
-@@ -119,6 +119,16 @@ config F2FS_FS_LZ4
- help
- Support LZ4 compress algorithm, if unsure, say Y.
-
-+config F2FS_FS_LZ4HC
-+ bool "LZ4HC compression support"
-+ depends on F2FS_FS_COMPRESSION
-+ depends on F2FS_FS_LZ4
-+ select LZ4HC_COMPRESS
-+ default y
-+ help
-+ Support LZ4HC compress algorithm, LZ4HC has compatible on-disk
-+ layout with LZ4, if unsure, say Y.
-+
- config F2FS_FS_ZSTD
- bool "ZSTD compression support"
- depends on F2FS_FS_COMPRESSION
-diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
-index 8da6df3bfb03f..579d3b32db178 100644
---- a/fs/f2fs/compress.c
-+++ b/fs/f2fs/compress.c
-@@ -240,8 +240,14 @@ static const struct f2fs_compress_ops f2fs_lzo_ops = {
- #ifdef CONFIG_F2FS_FS_LZ4
- static int lz4_init_compress_ctx(struct compress_ctx *cc)
- {
-- cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode),
-- LZ4_MEM_COMPRESS, GFP_NOFS);
-+ unsigned int size = LZ4_MEM_COMPRESS;
-+
-+#ifdef CONFIG_F2FS_FS_LZ4HC
-+ if (F2FS_I(cc->inode)->i_compress_flag >> COMPRESS_LEVEL_OFFSET)
-+ size = LZ4HC_MEM_COMPRESS;
-+#endif
-+
-+ cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), size, GFP_NOFS);
- if (!cc->private)
- return -ENOMEM;
-
-@@ -260,10 +266,34 @@ static void lz4_destroy_compress_ctx(struct compress_ctx *cc)
- cc->private = NULL;
- }
-
-+#ifdef CONFIG_F2FS_FS_LZ4HC
-+static int lz4hc_compress_pages(struct compress_ctx *cc)
-+{
-+ unsigned char level = F2FS_I(cc->inode)->i_compress_flag >>
-+ COMPRESS_LEVEL_OFFSET;
-+ int len;
-+
-+ if (level)
-+ len = LZ4_compress_HC(cc->rbuf, cc->cbuf->cdata, cc->rlen,
-+ cc->clen, level, cc->private);
-+ else
-+ len = LZ4_compress_default(cc->rbuf, cc->cbuf->cdata, cc->rlen,
-+ cc->clen, cc->private);
-+ if (!len)
-+ return -EAGAIN;
-+
-+ cc->clen = len;
-+ return 0;
-+}
-+#endif
-+
- static int lz4_compress_pages(struct compress_ctx *cc)
- {
- int len;
-
-+#ifdef CONFIG_F2FS_FS_LZ4HC
-+ return lz4hc_compress_pages(cc);
-+#endif
- len = LZ4_compress_default(cc->rbuf, cc->cbuf->cdata, cc->rlen,
- cc->clen, cc->private);
- if (!len)
-@@ -312,8 +342,13 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)
- ZSTD_CStream *stream;
- void *workspace;
- unsigned int workspace_size;
-+ unsigned char level = F2FS_I(cc->inode)->i_compress_flag >>
-+ COMPRESS_LEVEL_OFFSET;
-+
-+ if (!level)
-+ level = F2FS_ZSTD_DEFAULT_CLEVEL;
-
-- params = ZSTD_getParams(F2FS_ZSTD_DEFAULT_CLEVEL, cc->rlen, 0);
-+ params = ZSTD_getParams(level, cc->rlen, 0);
- workspace_size = ZSTD_CStreamWorkspaceBound(params.cParams);
-
- workspace = f2fs_kvmalloc(F2FS_I_SB(cc->inode),
-diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
-index 6a9f4dcea06d6..01e365aefbc97 100644
---- a/fs/f2fs/f2fs.h
-+++ b/fs/f2fs/f2fs.h
-@@ -148,6 +148,7 @@ struct f2fs_mount_info {
- /* For compression */
- unsigned char compress_algorithm; /* algorithm type */
- unsigned char compress_log_size; /* cluster log size */
-+ unsigned char compress_level; /* compress level */
- bool compress_chksum; /* compressed data chksum */
- unsigned char compress_ext_cnt; /* extension count */
- int compress_mode; /* compression mode */
-@@ -740,6 +741,7 @@ struct f2fs_inode_info {
- atomic_t i_compr_blocks; /* # of compressed blocks */
- unsigned char i_compress_algorithm; /* algorithm type */
- unsigned char i_log_cluster_size; /* log of cluster size */
-+ unsigned char i_compress_level; /* compress level (lz4hc,zstd) */
- unsigned short i_compress_flag; /* compress flag */
- unsigned int i_cluster_size; /* cluster size */
- };
-@@ -1315,6 +1317,8 @@ struct compress_data {
-
- #define F2FS_COMPRESSED_PAGE_MAGIC 0xF5F2C000
-
-+#define COMPRESS_LEVEL_OFFSET 8
-+
- /* compress context */
- struct compress_ctx {
- struct inode *inode; /* inode the context belong to */
-@@ -3969,6 +3973,11 @@ static inline void set_compress_context(struct inode *inode)
- 1 << COMPRESS_CHKSUM : 0;
- F2FS_I(inode)->i_cluster_size =
- 1 << F2FS_I(inode)->i_log_cluster_size;
-+ if (F2FS_I(inode)->i_compress_algorithm == COMPRESS_LZ4 &&
-+ F2FS_OPTION(sbi).compress_level)
-+ F2FS_I(inode)->i_compress_flag |=
-+ F2FS_OPTION(sbi).compress_level <<
-+ COMPRESS_LEVEL_OFFSET;
- F2FS_I(inode)->i_flags |= F2FS_COMPR_FL;
- set_inode_flag(inode, FI_COMPRESSED_FILE);
- stat_inc_compr_inode(inode);
-diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
-index e66c2de29eebc..d49160328d53b 100644
---- a/fs/f2fs/super.c
-+++ b/fs/f2fs/super.c
-@@ -25,6 +25,8 @@
- #include <linux/quota.h>
- #include <linux/unicode.h>
- #include <linux/part_stat.h>
-+#include <linux/zstd.h>
-+#include <linux/lz4.h>
-
- #include "f2fs.h"
- #include "node.h"
-@@ -504,6 +506,74 @@ static int f2fs_set_test_dummy_encryption(struct super_block *sb,
- return 0;
- }
-
-+#ifdef CONFIG_F2FS_FS_COMPRESSION
-+#ifdef CONFIG_F2FS_FS_LZ4
-+static int f2fs_set_lz4hc_level(struct f2fs_sb_info *sbi, const char *str)
-+{
-+#ifdef CONFIG_F2FS_FS_LZ4HC
-+ unsigned int level;
-+#endif
-+
-+ if (strlen(str) == 3) {
-+ F2FS_OPTION(sbi).compress_level = 0;
-+ return 0;
-+ }
-+
-+#ifdef CONFIG_F2FS_FS_LZ4HC
-+ str += 3;
-+
-+ if (str[0] != ':') {
-+ f2fs_info(sbi, "wrong format, e.g. <alg_name>:<compr_level>");
-+ return -EINVAL;
-+ }
-+ if (kstrtouint(str + 1, 10, &level))
-+ return -EINVAL;
-+
-+ if (level < LZ4HC_MIN_CLEVEL || level > LZ4HC_MAX_CLEVEL) {
-+ f2fs_info(sbi, "invalid lz4hc compress level: %d", level);
-+ return -EINVAL;
-+ }
-+
-+ F2FS_OPTION(sbi).compress_level = level;
-+ return 0;
-+#else
-+ f2fs_info(sbi, "kernel doesn't support lz4hc compression");
-+ return -EINVAL;
-+#endif
-+}
-+#endif
-+
-+#ifdef CONFIG_F2FS_FS_ZSTD
-+static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, const char *str)
-+{
-+ unsigned int level;
-+ int len = 4;
-+
-+ if (strlen(str) == len) {
-+ F2FS_OPTION(sbi).compress_level = 0;
-+ return 0;
-+ }
-+
-+ str += len;
-+
-+ if (str[0] != ':') {
-+ f2fs_info(sbi, "wrong format, e.g. <alg_name>:<compr_level>");
-+ return -EINVAL;
-+ }
-+ if (kstrtouint(str + 1, 10, &level))
-+ return -EINVAL;
-+
-+ if (!level || level > ZSTD_maxCLevel()) {
-+ f2fs_info(sbi, "invalid zstd compress level: %d", level);
-+ return -EINVAL;
-+ }
-+
-+ F2FS_OPTION(sbi).compress_level = level;
-+ return 0;
-+}
-+#endif
-+#endif
-+
- static int parse_options(struct super_block *sb, char *options, bool is_remount)
- {
- struct f2fs_sb_info *sbi = F2FS_SB(sb);
-@@ -923,20 +993,31 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- return -ENOMEM;
- if (!strcmp(name, "lzo")) {
- #ifdef CONFIG_F2FS_FS_LZO
-+ F2FS_OPTION(sbi).compress_level = 0;
- F2FS_OPTION(sbi).compress_algorithm =
- COMPRESS_LZO;
- #else
- f2fs_info(sbi, "kernel doesn't support lzo compression");
- #endif
-- } else if (!strcmp(name, "lz4")) {
-+ } else if (!strncmp(name, "lz4", 3)) {
- #ifdef CONFIG_F2FS_FS_LZ4
-+ ret = f2fs_set_lz4hc_level(sbi, name);
-+ if (ret) {
-+ kfree(name);
-+ return -EINVAL;
-+ }
- F2FS_OPTION(sbi).compress_algorithm =
- COMPRESS_LZ4;
- #else
- f2fs_info(sbi, "kernel doesn't support lz4 compression");
- #endif
-- } else if (!strcmp(name, "zstd")) {
-+ } else if (!strncmp(name, "zstd", 4)) {
- #ifdef CONFIG_F2FS_FS_ZSTD
-+ ret = f2fs_set_zstd_level(sbi, name);
-+ if (ret) {
-+ kfree(name);
-+ return -EINVAL;
-+ }
- F2FS_OPTION(sbi).compress_algorithm =
- COMPRESS_ZSTD;
- #else
-@@ -944,6 +1025,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- #endif
- } else if (!strcmp(name, "lzo-rle")) {
- #ifdef CONFIG_F2FS_FS_LZORLE
-+ F2FS_OPTION(sbi).compress_level = 0;
- F2FS_OPTION(sbi).compress_algorithm =
- COMPRESS_LZORLE;
- #else
-@@ -1594,6 +1676,9 @@ static inline void f2fs_show_compress_options(struct seq_file *seq,
- }
- seq_printf(seq, ",compress_algorithm=%s", algtype);
-
-+ if (F2FS_OPTION(sbi).compress_level)
-+ seq_printf(seq, ":%d", F2FS_OPTION(sbi).compress_level);
-+
- seq_printf(seq, ",compress_log_size=%u",
- F2FS_OPTION(sbi).compress_log_size);
-
-diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
-index 7dc2a06cf19a1..c6cc0a566ef5c 100644
---- a/include/linux/f2fs_fs.h
-+++ b/include/linux/f2fs_fs.h
-@@ -274,6 +274,9 @@ struct f2fs_inode {
- __u8 i_compress_algorithm; /* compress algorithm */
- __u8 i_log_cluster_size; /* log of cluster size */
- __le16 i_compress_flag; /* compress flag */
-+ /* 0 bit: chksum flag
-+ * [10,15] bits: compress level
-+ */
- __le32 i_extra_end[0]; /* for attribute size calculation */
- } __packed;
- __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */
---
-2.42.0
-
+++ /dev/null
-From 8a86857d41240a18f01b22fa83f2ee6d8bc5777a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 13 Apr 2021 17:56:53 +0800
-Subject: f2fs: document: add description about compressed space handling
-
-From: Chao Yu <yuchao0@huawei.com>
-
-[ Upstream commit 38740707c5bc1253069eb932bc6d244f80ec21f0 ]
-
-User or developer may still be confused about why f2fs doesn't expose
-compressed space to userspace, add description about compressed space
-handling policy into f2fs documentation.
-
-Signed-off-by: Chao Yu <yuchao0@huawei.com>
-Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-Stable-dep-of: 7e1b150fece0 ("f2fs: compress: fix to avoid redundant compress extension")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- Documentation/filesystems/f2fs.rst | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
-index 4f51c0be22c45..9e302d3dd85a6 100644
---- a/Documentation/filesystems/f2fs.rst
-+++ b/Documentation/filesystems/f2fs.rst
-@@ -803,6 +803,14 @@ Compression implementation
- * chattr +c file
- * chattr +c dir; touch dir/file
- * mount w/ -o compress_extension=ext; touch file.ext
-+ * mount w/ -o compress_extension=*; touch any_file
-+
-+- At this point, compression feature doesn't expose compressed space to user
-+ directly in order to guarantee potential data updates later to the space.
-+ Instead, the main goal is to reduce data writes to flash disk as much as
-+ possible, resulting in extending disk life time as well as relaxing IO
-+ congestion. Alternatively, we've added ioctl interface to reclaim compressed
-+ space and show it to user after putting the immutable bit.
-
- Compress metadata layout::
-
---
-2.42.0
-
mfd-dln2-fix-double-put-in-dln2_probe.patch
leds-pwm-don-t-disable-the-pwm-when-the-led-should-b.patch
leds-trigger-ledtrig-cpu-fix-output-may-be-truncated.patch
-f2fs-compress-support-chksum.patch
-f2fs-add-compress_mode-mount-option.patch
-f2fs-compress-deny-setting-unsupported-compress-algo.patch
-f2fs-compress-support-compress-level.patch
-f2fs-document-add-description-about-compressed-space.patch
-f2fs-compress-add-nocompress-extensions-support.patch
-f2fs-compress-fix-to-avoid-redundant-compress-extens.patch
tty-tty_jobctrl-fix-pid-memleak-in-disassociate_ctty.patch
livepatch-fix-missing-newline-character-in-klp_resol.patch
perf-evlist-add-evlist__add_dummy_on_all_cpus.patch