Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp247510pxu; Wed, 2 Dec 2020 21:50:54 -0800 (PST) X-Google-Smtp-Source: ABdhPJzVPEbR3yX7KXFViIgTGHPlwdX/N6LTELEz83J8NtEQ7QRwt6r43423wgXEXKgE85DkB07/ X-Received: by 2002:a17:906:4d47:: with SMTP id b7mr1085201ejv.420.1606974654037; Wed, 02 Dec 2020 21:50:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1606974654; cv=none; d=google.com; s=arc-20160816; b=AUfXhQ9YM8OZlSzPELmVm4IWNr6dcTnvYU4goOkt2nt++zfPh+mEkIN1307sCHMEBP RZotiB334M7aWup1IAZZwJ70Q/amZi0IPnT+uO83vSH4/8Hje0TUOKKrvPKwcsM/d8uQ w0xqFkF9s/xYqFZqzE+8NHsBJWuKBJprRPXgsTYWU4Xl4B9TJpblxZ4lf8/8PB8xbe9U +KEooeTYpRPQ1t3lkNeWuMBu2nqlz0NZft6VvGr9boFsTZlrXs7arogfIhsG8hk/j2yR tBM6bE/UMWOxdpugceNVw+yyfMFcDHPICfzM8t1lPiTHWB+y5+fMb3gvJun8NY2t5pwF QTcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:dkim-signature:date; bh=Tt/yb5hFPCswc+SqcMyVsq27HyocfyunY2Qxm1q8+K4=; b=szaLLXMZdG3j5sdZHiC923pHqqyVxxlFYFCjBOliCOxxWDCU1qefYNczh2S4RAApl5 cJjgL3WJfiqeH8MZbtsYslbR5rImlgbBOcpi7eTUsd4Wlt792qNU8CWao5QIhjXzxT1M JCcQc9yjkGOrMEpfhzP+hExNWgZkWUui6xxx0Q6Uo39g5uwPnywTSCnBUEDv6IdHmeuX wJ3Y/vgFu3xrOOuqly67la815E8D3T243g5gEWfLarwn3cx2tQJcI+e2/Qg4vmDdj9ur iv8rL9CVtLH86VEYUQE3X8IDzzAQcEy6ON7S4HVQGUX8PaXLsXPVaNgiNH7HssLYM06X GRIQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=rCEroEIS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b24si339912eds.235.2020.12.02.21.50.31; Wed, 02 Dec 2020 21:50:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=rCEroEIS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728538AbgLCFsF (ORCPT + 99 others); Thu, 3 Dec 2020 00:48:05 -0500 Received: from mail.kernel.org ([198.145.29.99]:33468 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728023AbgLCFsE (ORCPT ); Thu, 3 Dec 2020 00:48:04 -0500 Date: Wed, 2 Dec 2020 21:47:21 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1606974443; bh=sjBL4bXjKo5x6Xl3BjEQeVq24MLGIR3Ca86zeF4PGp8=; h=From:To:Cc:Subject:References:In-Reply-To:From; b=rCEroEISuXwe0OLs6Li4Yl/5NYKgwnHqAAicDGrA7mqAOOLbEN1GX/6y7oeW+ud9A ZQVIq+8hmEzxFZiivbYQRxDslM8RMHXzjnUO63XGEAvUPqfOHLfJBnsqzlgIfGY0fv cOln5js77GG4A4OjBYQeNTBi6yQ5aOr+BzBkoFay8YSbG5vPPloxMoY0Y9JXjwYUXQ gePsEUIZAJRPruoVTCOwRln9V4FO0TGbqYO2lnuu+4V6gKmkGR5ko+1Iak5ofscs2u CInzsp7syZoHkcv50Koumaz2SNgjMPkui0ENh+e3WwSm+JCIP6/FiWQJcAzli26tlB nlywnYy4T0+xA== From: Jaegeuk Kim To: Chao Yu Cc: linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org, chao@kernel.org Subject: Re: [PATCH v5] f2fs: compress: support compress level Message-ID: References: <20201203033104.42484-1-yuchao0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20201203033104.42484-1-yuchao0@huawei.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 12/03, Chao Yu wrote: > Expand 'compress_algorithm' mount option to accept parameter as format of > :, 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. > > Signed-off-by: Chao Yu > --- > v5: > - avoid compile error if CONFIG_F2FS_FS_ZSTD is off. > Documentation/filesystems/f2fs.rst | 5 +++ > fs/f2fs/Kconfig | 9 ++++ > fs/f2fs/compress.c | 40 +++++++++++++++-- > fs/f2fs/f2fs.h | 9 ++++ > fs/f2fs/super.c | 72 +++++++++++++++++++++++++++++- > include/linux/f2fs_fs.h | 3 ++ > 6 files changed, 133 insertions(+), 5 deletions(-) > > diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst > index fd413d319e93..eef683c3266f 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. > + level range This gives a warning like below. Applying: f2fs: compress: support compress level .git/rebase-apply/patch:22: space before tab in indent. level range warning: 1 line adds whitespace errors. > + 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 d13c5c6a9787..8134b145ae4f 100644 > --- a/fs/f2fs/Kconfig > +++ b/fs/f2fs/Kconfig > @@ -119,6 +119,15 @@ 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, 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 db82da311fe4..dfadbc78946c 100644 > --- a/fs/f2fs/compress.c > +++ b/fs/f2fs/compress.c > @@ -254,8 +254,13 @@ 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; > + unsigned char level = F2FS_I(cc->inode)->i_compress_flag >> > + COMPRESS_LEVEL_OFFSET; > + > + size = level ? LZ4HC_MEM_COMPRESS : LZ4_MEM_COMPRESS; > + > + cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), size, GFP_NOFS); > if (!cc->private) > return -ENOMEM; > > @@ -274,10 +279,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) > @@ -327,8 +356,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 377a2e2bf466..76edec7483f3 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -147,6 +147,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 */ > @@ -736,6 +737,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 */ > }; > @@ -1308,6 +1310,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 */ > @@ -3959,6 +3963,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 8442333ca0e2..44ba870bb352 100644 > --- a/fs/f2fs/super.c > +++ b/fs/f2fs/super.c > @@ -25,6 +25,8 @@ > #include > #include > #include > +#include > +#include > > #include "f2fs.h" > #include "node.h" > @@ -466,6 +468,57 @@ static int f2fs_set_test_dummy_encryption(struct super_block *sb, > return 0; > } > > +#ifdef CONFIG_F2FS_FS_COMPRESSION > +static int f2fs_compress_set_level(struct f2fs_sb_info *sbi, const char *str, > + int type) > +{ > + unsigned int level; > + int len; > + > + if (type == COMPRESS_LZ4) > + len = 3; > + else if (type == COMPRESS_ZSTD) > + len = 4; > + else > + return 0; > + > + if (strlen(str) == len) > + return 0; > + > + str += len; > + > + if (str[0] != ':') { > + f2fs_info(sbi, "wrong format, e.g. :"); > + return -EINVAL; > + } > + if (kstrtouint(str + 1, 10, &level)) > + return -EINVAL; > + if (type == COMPRESS_LZ4) { > +#ifdef CONFIG_F2FS_FS_LZ4HC > + if (level < LZ4HC_MIN_CLEVEL || level > LZ4HC_MAX_CLEVEL) { > + f2fs_info(sbi, "invalid lz4hc compress level: %d", level); > + return -EINVAL; > + } > +#else > + f2fs_info(sbi, "doesn't support lz4hc compression"); > + return 0; > +#endif > + } else if (type == COMPRESS_ZSTD) { > +#ifdef CONFIG_F2FS_FS_ZSTD > + if (!level || level > ZSTD_maxCLevel()) { > + f2fs_info(sbi, "invalid zstd compress level: %d", level); > + return -EINVAL; > + } > +#else > + f2fs_info(sbi, "doesn't support zstd compression"); > + return 0; > +#endif > + } > + F2FS_OPTION(sbi).compress_level = level; > + return 0; > +} > +#endif > + > static int parse_options(struct super_block *sb, char *options, bool is_remount) > { > struct f2fs_sb_info *sbi = F2FS_SB(sb); > @@ -886,10 +939,22 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) > if (!strcmp(name, "lzo")) { > F2FS_OPTION(sbi).compress_algorithm = > COMPRESS_LZO; > - } else if (!strcmp(name, "lz4")) { > + } else if (!strncmp(name, "lz4", 3)) { > + ret = f2fs_compress_set_level(sbi, name, > + COMPRESS_LZ4); > + if (ret) { > + kfree(name); > + return -EINVAL; > + } > F2FS_OPTION(sbi).compress_algorithm = > COMPRESS_LZ4; > - } else if (!strcmp(name, "zstd")) { > + } else if (!strncmp(name, "zstd", 4)) { > + ret = f2fs_compress_set_level(sbi, name, > + COMPRESS_ZSTD); > + if (ret) { > + kfree(name); > + return -EINVAL; > + } > F2FS_OPTION(sbi).compress_algorithm = > COMPRESS_ZSTD; > } else if (!strcmp(name, "lzo-rle")) { > @@ -1547,6 +1612,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 55be7afeee90..2dcc63fe8494 100644 > --- a/include/linux/f2fs_fs.h > +++ b/include/linux/f2fs_fs.h > @@ -275,6 +275,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.26.2