LKML Archive on lore.kernel.org
 help / color / Atom feed
From: Chao Yu <yuchao0@huawei.com>
To: <jaegeuk@kernel.org>
Cc: <linux-f2fs-devel@lists.sourceforge.net>,
	<linux-kernel@vger.kernel.org>, <chao@kernel.org>,
	Chao Yu <yuchao0@huawei.com>
Subject: [PATCH] f2fs: compress: support lz4hc compression
Date: Mon, 30 Nov 2020 19:26:48 +0800
Message-ID: <20201130112648.95504-1-yuchao0@huawei.com> (raw)

Add a new mount option "compress_lz4hc_clevel=%u" to enable lz4hc compress
algorithm and specify the compress level of lz4hc.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
 Documentation/filesystems/f2fs.rst |  2 ++
 fs/f2fs/compress.c                 | 22 +++++++++++++++++-----
 fs/f2fs/f2fs.h                     |  8 ++++++++
 fs/f2fs/inode.c                    |  4 ++++
 fs/f2fs/super.c                    | 15 +++++++++++++++
 5 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
index 8830a11a11be..cda30ea124ee 100644
--- a/Documentation/filesystems/f2fs.rst
+++ b/Documentation/filesystems/f2fs.rst
@@ -264,6 +264,8 @@ compress_chksum		 Support verifying chksum of raw data in compressed cluster.
 compress_cache		 Support to use address space of inner inode to cache
 			 compressed block, in order to improve cache hit ratio of
 			 random read.
+compress_lz4hc_clevel	 Support to enable LZ4 high compression algorithm, compress
+			 level range is [3, 16].
 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 2ec34168adbb..233be7f71e48 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -253,17 +253,24 @@ 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;
+
+	size = F2FS_I(cc->inode)->i_lz4hc_clevel ?
+			LZ4HC_MEM_COMPRESS : LZ4_MEM_COMPRESS;
+
+	cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), size, GFP_NOFS);
 	if (!cc->private)
 		return -ENOMEM;
 
 	/*
 	 * we do not change cc->clen to LZ4_compressBound(inputsize) to
 	 * adapt worst compress case, because lz4 compressor can handle
-	 * output budget properly.
+	 * output budget properly; for lz4hc case, keep it as it is.
 	 */
-	cc->clen = cc->rlen - PAGE_SIZE - COMPRESS_HEADER_SIZE;
+	if (F2FS_I(cc->inode)->i_lz4hc_clevel)
+		cc->clen = LZ4_compressBound(cc->rlen);
+	else
+		cc->clen = cc->rlen - PAGE_SIZE - COMPRESS_HEADER_SIZE;
 	return 0;
 }
 
@@ -275,9 +282,14 @@ static void lz4_destroy_compress_ctx(struct compress_ctx *cc)
 
 static int lz4_compress_pages(struct compress_ctx *cc)
 {
+	unsigned char clevel = F2FS_I(cc->inode)->i_lz4hc_clevel;
 	int len;
 
-	len = LZ4_compress_default(cc->rbuf, cc->cbuf->cdata, cc->rlen,
+	if (clevel)
+		len = LZ4_compress_HC(cc->rbuf, cc->cbuf->cdata, cc->rlen,
+						cc->clen, clevel, cc->private);
+	else
+		len = LZ4_compress_default(cc->rbuf, cc->cbuf->cdata, cc->rlen,
 						cc->clen, cc->private);
 	if (!len)
 		return -EAGAIN;
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index d32065417616..d3d5583ea9e5 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -149,6 +149,7 @@ struct f2fs_mount_info {
 	/* For compression */
 	unsigned char compress_algorithm;	/* algorithm type */
 	unsigned char compress_log_size;	/* cluster log size */
+	unsigned char lz4hc_clevel;		/* lz4hc compress level */
 	bool compress_chksum;			/* compressed data chksum */
 	unsigned char compress_ext_cnt;		/* extension count */
 	unsigned char extensions[COMPRESS_EXT_NUM][F2FS_EXTENSION_LEN];	/* extensions */
@@ -736,6 +737,10 @@ struct f2fs_inode_info {
 	unsigned char i_log_cluster_size;	/* log of cluster size */
 	unsigned short i_compress_flag;		/* compress flag */
 	unsigned int i_cluster_size;		/* cluster size */
+	unsigned char i_lz4hc_clevel;		/*
+						 * lz4hc compress level,
+						 * range: 3-16, disable: 0
+						 */
 };
 
 static inline void get_extent_info(struct extent_info *ext,
@@ -3932,6 +3937,9 @@ 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).lz4hc_clevel)
+		F2FS_I(inode)->i_lz4hc_clevel = F2FS_OPTION(sbi).lz4hc_clevel;
 	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/inode.c b/fs/f2fs/inode.c
index 39fad324ca52..98be4d87e067 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -461,6 +461,10 @@ static int do_read_inode(struct inode *inode)
 			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);
+			if (fi->i_compress_algorithm == COMPRESS_LZ4 &&
+					F2FS_OPTION(sbi).lz4hc_clevel)
+				fi->i_lz4hc_clevel =
+					F2FS_OPTION(sbi).lz4hc_clevel;
 			fi->i_cluster_size = 1 << fi->i_log_cluster_size;
 			set_inode_flag(inode, FI_COMPRESSED_FILE);
 		}
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index b0c6ef2df7b8..2cd7fcc400b8 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -25,6 +25,7 @@
 #include <linux/quota.h>
 #include <linux/unicode.h>
 #include <linux/part_stat.h>
+#include <linux/lz4.h>
 
 #include "f2fs.h"
 #include "node.h"
@@ -148,6 +149,7 @@ enum {
 	Opt_compress_extension,
 	Opt_compress_chksum,
 	Opt_compress_cache,
+	Opt_compress_lz4hc_clevel,
 	Opt_atgc,
 	Opt_err,
 };
@@ -218,6 +220,7 @@ static match_table_t f2fs_tokens = {
 	{Opt_compress_extension, "compress_extension=%s"},
 	{Opt_compress_chksum, "compress_chksum"},
 	{Opt_compress_cache, "compress_cache"},
+	{Opt_compress_lz4hc_clevel, "compress_lz4hc_clevel=%u"},
 	{Opt_atgc, "atgc"},
 	{Opt_err, NULL},
 };
@@ -944,12 +947,20 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
 		case Opt_compress_cache:
 			set_opt(sbi, COMPRESS_CACHE);
 			break;
+		case Opt_compress_lz4hc_clevel:
+			if (args->from && match_int(args, &arg))
+				return -EINVAL;
+			if (arg < LZ4HC_MIN_CLEVEL || arg > LZ4HC_MAX_CLEVEL)
+				return -EINVAL;
+			F2FS_OPTION(sbi).lz4hc_clevel = arg;
+			break;
 #else
 		case Opt_compress_algorithm:
 		case Opt_compress_log_size:
 		case Opt_compress_extension:
 		case Opt_compress_chksum:
 		case Opt_compress_cache:
+		case Opt_compress_lz4hc_clevel:
 			f2fs_info(sbi, "compression options not supported");
 			break;
 #endif
@@ -1543,6 +1554,10 @@ static inline void f2fs_show_compress_options(struct seq_file *seq,
 
 	if (test_opt(sbi, COMPRESS_CACHE))
 		seq_puts(seq, ",compress_cache");
+
+	if (F2FS_OPTION(sbi).lz4hc_clevel)
+		seq_printf(seq, ",compress_lz4hc_clevel=%u",
+				F2FS_OPTION(sbi).lz4hc_clevel);
 }
 
 static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
-- 
2.26.2


             reply index

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-30 11:26 Chao Yu [this message]
2020-11-30 11:35 ` [f2fs-dev] " Ju Hyung Park
2020-11-30 15:04   ` Chao Yu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201130112648.95504-1-yuchao0@huawei.com \
    --to=yuchao0@huawei.com \
    --cc=chao@kernel.org \
    --cc=jaegeuk@kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git
	git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git