linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Kiper <dkiper@net-space.pl>
To: Nick Terrell <terrelln@fb.com>
Cc: grub-devel@gnu.org, kernel-team@fb.com,
	David Sterba <dsterba@suse.cz>,
	linux-btrfs@vger.kernel.org
Subject: Re: [PATCH 3/3] btrfs: Add zstd support to btrfs
Date: Fri, 21 Sep 2018 20:29:20 +0200	[thread overview]
Message-ID: <20180921182920.GD29978@router-fw-old.i.net-space.pl> (raw)
In-Reply-To: <20180828013654.1627080-4-terrelln@fb.com>

On Mon, Aug 27, 2018 at 06:36:54PM -0700, Nick Terrell wrote:
> Adds zstd support to the btrfs module. I'm not sure that my changes to the
> Makefiles are correct, please let me know if I need to do something
> differently.
>
> Tested on Ubuntu-18.04 with a btrfs /boot partition with and without zstd
> compression. A test case was also added to the test suite that fails before
> the patch, and passes after.
>
> Signed-off-by: Nick Terrell <terrelln@fb.com>
> ---
>  Makefile.util.def            |  8 ++++-
>  grub-core/Makefile.core.def  | 10 ++++--
>  grub-core/fs/btrfs.c         | 85 +++++++++++++++++++++++++++++++++++++++++++-
>  tests/btrfs_test.in          |  1 +
>  tests/util/grub-fs-tester.in |  4 +--
>  5 files changed, 102 insertions(+), 6 deletions(-)
>
> diff --git a/Makefile.util.def b/Makefile.util.def
> index 3180ac880..b987dc637 100644
> --- a/Makefile.util.def
> +++ b/Makefile.util.def
> @@ -54,7 +54,7 @@ library = {
>  library = {
>    name = libgrubmods.a;
>    cflags = '-fno-builtin -Wno-undef';
> -  cppflags = '-I$(top_srcdir)/grub-core/lib/minilzo -I$(srcdir)/grub-core/lib/xzembed -DMINILZO_HAVE_CONFIG_H';
> +  cppflags = '-I$(top_srcdir)/grub-core/lib/minilzo -I$(srcdir)/grub-core/lib/xzembed -I$(top_srcdir)/grub-core/lib/zstd -DMINILZO_HAVE_CONFIG_H';
>
>    common_nodist = grub_script.tab.c;
>    common_nodist = grub_script.yy.c;
> @@ -165,6 +165,12 @@ library = {
>    common = grub-core/lib/xzembed/xz_dec_bcj.c;
>    common = grub-core/lib/xzembed/xz_dec_lzma2.c;
>    common = grub-core/lib/xzembed/xz_dec_stream.c;
> +  common = grub-core/lib/zstd/zstd_common.c;
> +  common = grub-core/lib/zstd/huf_decompress.c;
> +  common = grub-core/lib/zstd/fse_decompress.c;
> +  common = grub-core/lib/zstd/entropy_common.c;
> +  common = grub-core/lib/zstd/decompress.c;
> +  common = grub-core/lib/zstd/xxhash.c;
>  };
>
>  program = {
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index 9590e87d9..c24bf9147 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -404,7 +404,7 @@ image = {
>    i386_pc = boot/i386/pc/boot.S;
>
>    cppflags = '-DHYBRID_BOOT=1';
> -
> +

Please do not introduce such noise...

>    i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
>    i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00';
>
> @@ -1264,8 +1264,14 @@ module = {
>    name = btrfs;
>    common = fs/btrfs.c;
>    common = lib/crc.c;
> +  common = lib/zstd/zstd_common.c;
> +  common = lib/zstd/huf_decompress.c;
> +  common = lib/zstd/fse_decompress.c;
> +  common = lib/zstd/entropy_common.c;
> +  common = lib/zstd/decompress.c;
> +  common = lib/zstd/xxhash.c;
>    cflags = '$(CFLAGS_POSIX) -Wno-undef';
> -  cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H';
> +  cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -I$(srcdir)/lib/zstd -DMINILZO_HAVE_CONFIG_H';
>  };
>
>  module = {
> diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
> index be195448d..89ed4884e 100644
> --- a/grub-core/fs/btrfs.c
> +++ b/grub-core/fs/btrfs.c
> @@ -27,6 +27,7 @@
>  #include <grub/lib/crc.h>
>  #include <grub/deflate.h>
>  #include <minilzo.h>
> +#include <zstd.h>
>  #include <grub/i18n.h>
>  #include <grub/btrfs.h>
>
> @@ -45,6 +46,9 @@ GRUB_MOD_LICENSE ("GPLv3+");
>  #define GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE (GRUB_BTRFS_LZO_BLOCK_SIZE + \
>  				     (GRUB_BTRFS_LZO_BLOCK_SIZE / 16) + 64 + 3)
>
> +#define ZSTD_BTRFS_MAX_WINDOWLOG 17
> +#define ZSTD_BTRFS_MAX_INPUT (1 << ZSTD_BTRFS_MAX_WINDOWLOG)

Please align stuff properly, i.e.

#define ZSTD_BTRFS_MAX_WINDOWLOG 17
#define ZSTD_BTRFS_MAX_INPUT     (1 << ZSTD_BTRFS_MAX_WINDOWLOG)

> +
>  typedef grub_uint8_t grub_btrfs_checksum_t[0x20];
>  typedef grub_uint16_t grub_btrfs_uuid_t[8];
>
> @@ -212,6 +216,7 @@ struct grub_btrfs_extent_data
>  #define GRUB_BTRFS_COMPRESSION_NONE 0
>  #define GRUB_BTRFS_COMPRESSION_ZLIB 1
>  #define GRUB_BTRFS_COMPRESSION_LZO  2
> +#define GRUB_BTRFS_COMPRESSION_ZSTD  3

Ditto.

>  #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100
>
> @@ -912,6 +917,70 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data,
>    return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode), 0);
>  }
>
> +static grub_ssize_t
> +grub_btrfs_zstd_decompress(char *ibuf, grub_size_t isize, grub_off_t off,
> +			  char *obuf, grub_size_t osize)
> +{
> +	void *allocated = NULL;
> +	char *otmpbuf = obuf;
> +	grub_size_t otmpsize = osize;
> +	void *wmem = NULL;
> +	const grub_size_t wmem_size = ZSTD_DCtxWorkspaceBound ();
> +	ZSTD_DCtx *dctx;
> +	grub_size_t zstd_ret;
> +	grub_ssize_t ret = -1;
> +
> +	/* Zstd will fail if it can't fit the entire output in the destination
> +	 * buffer, so if osize isn't large enough, allocate a temporary buffer.
> +	 */
> +	if (otmpsize < ZSTD_BTRFS_MAX_INPUT) {
> +		allocated = grub_malloc (ZSTD_BTRFS_MAX_INPUT);
> +		if (!allocated) {
> +			grub_dprintf ("zstd", "outtmpbuf allocation failed\n");
> +			goto out;
> +		}
> +		otmpbuf = (char*)allocated;
> +		otmpsize = ZSTD_BTRFS_MAX_INPUT;
> +	}
> +
> +	/* Allocate space for, and initialize, the ZSTD_DCtx. */
> +	wmem = grub_malloc (wmem_size);
> +	if (!wmem) {
> +		grub_dprintf ("zstd", "wmem allocation failed\n");
> +		goto out;
> +	}
> +	dctx = ZSTD_initDCtx (wmem, wmem_size);
> +
> +	/* Get the real input size, there may be junk at the
> +	 * end of the frame.
> +	 */
> +	isize = ZSTD_findFrameCompressedSize (ibuf, isize);
> +	if (ZSTD_isError (isize)) {
> +		grub_dprintf ("zstd", "first frame is invalid %d\n",
> +				(int)ZSTD_getErrorCode (isize));
> +		goto out;
> +	}
> +
> +	/* Decompress and check for errors */
> +	zstd_ret = ZSTD_decompressDCtx (dctx, otmpbuf, otmpsize, ibuf, isize);
> +	if (ZSTD_isError (zstd_ret)) {
> +		grub_dprintf ("zstd", "zstd failed with  code %d\n",
> +				(int)ZSTD_getErrorCode (zstd_ret));
> +		goto out;
> +	}
> +
> +	/* Move the requested data into the obuf.
> +	 * obuf may be equal to otmpbuf, which is why grub_memmove() is required.
> +	 */
> +	grub_memmove (obuf, otmpbuf + off, osize);
> +	ret = osize;
> +
> +out:

s/out/err/

> +	grub_free (allocated);
> +	grub_free (wmem);
> +	return ret;
> +}
> +
>  static grub_ssize_t
>  grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off,
>  			  char *obuf, grub_size_t osize)
> @@ -1087,7 +1156,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
>
>        if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE
>  	  && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB
> -	  && data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO)
> +	  && data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO
> +	  && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZSTD)
>  	{
>  	  grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
>  		      "compression type 0x%x not supported",
> @@ -1127,6 +1197,15 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
>  		  != (grub_ssize_t) csize)
>  		return -1;
>  	    }
> +	  else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZSTD)
> +	    {
> +	      if (grub_btrfs_zstd_decompress(data->extent->inl, data->extsize -
> +					   ((grub_uint8_t *) data->extent->inl
> +					    - (grub_uint8_t *) data->extent),
> +					   extoff, buf, csize)
> +		  != (grub_ssize_t) csize)
> +		return -1;
> +	    }
>  	  else
>  	    grub_memcpy (buf, data->extent->inl + extoff, csize);
>  	  break;
> @@ -1164,6 +1243,10 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
>  		ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff
>  				    + grub_le_to_cpu64 (data->extent->offset),
>  				    buf, csize);
> +	      else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZSTD)
> +		ret = grub_btrfs_zstd_decompress (tmp, zsize, extoff
> +				    + grub_le_to_cpu64 (data->extent->offset),
> +				    buf, csize);
>  	      else
>  		ret = -1;
>
> diff --git a/tests/btrfs_test.in b/tests/btrfs_test.in
> index 2b37ddd33..0c9bf3a68 100644
> --- a/tests/btrfs_test.in
> +++ b/tests/btrfs_test.in
> @@ -18,6 +18,7 @@ fi
>  "@builddir@/grub-fs-tester" btrfs
>  "@builddir@/grub-fs-tester" btrfs_zlib
>  "@builddir@/grub-fs-tester" btrfs_lzo
> +"@builddir@/grub-fs-tester" btrfs_zstd
>  "@builddir@/grub-fs-tester" btrfs_raid0
>  "@builddir@/grub-fs-tester" btrfs_raid1
>  "@builddir@/grub-fs-tester" btrfs_single
> diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in
> index ef65fbc93..147d946d2 100644
> --- a/tests/util/grub-fs-tester.in
> +++ b/tests/util/grub-fs-tester.in
> @@ -600,7 +600,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do
>  	    GENERATED=n
>  	    LODEVICES=
>  	    MOUNTDEVICE=
> -
> +

Ditto.

Daniel

  reply	other threads:[~2018-09-22  0:19 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-28  1:36 [PATCH 0/3] btrfs: Add zstd support to btrfs Nick Terrell
2018-08-28  1:36 ` [PATCH 2/3] btrfs: Patch the kernel zstd Nick Terrell
2018-09-21 18:23   ` Daniel Kiper
2018-08-28  1:36 ` [PATCH 3/3] btrfs: Add zstd support to btrfs Nick Terrell
2018-09-21 18:29   ` Daniel Kiper [this message]
2018-09-11 10:23 ` [PATCH 0/3] " David Sterba
2018-09-11 19:48   ` Nick Terrell
     [not found] ` <20180828013654.1627080-2-terrelln@fb.com>
2018-09-21 18:10   ` [PATCH 1/3] btrfs: Import kernel zstd Daniel Kiper
2018-09-21 18:48     ` Nick Terrell

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=20180921182920.GD29978@router-fw-old.i.net-space.pl \
    --to=dkiper@net-space.pl \
    --cc=dsterba@suse.cz \
    --cc=grub-devel@gnu.org \
    --cc=kernel-team@fb.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=terrelln@fb.com \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).