[PATCH 0/3] btrfs: Add zstd support to btrfs

2018-08-27 Thread Nick Terrell
Hi all,

This patch set imports the upstream kernel zstd library, patches it to work
in grub, adds zstd support to the btrfs module, and adds a test case. I've
separated the importing and patching of the upstream kernel zstd library
for ease of review.

Thanks to David Sterba for starting this project! I started my patch from
where he left off.

Best,
Nick Terrell

Nick Terrell (3):
  Import kernel zstd
  Patch the kernel zstd
  Add btrfs zstd support

 Makefile.util.def   |8 +-
 grub-core/Makefile.core.def |   10 +-
 grub-core/fs/btrfs.c|   85 +-
 grub-core/lib/zstd/bitstream.h  |  380 ++
 grub-core/lib/zstd/decompress.c | 2494 +++
 grub-core/lib/zstd/entropy_common.c |  243 
 grub-core/lib/zstd/error_private.h  |   52 +
 grub-core/lib/zstd/fse.h|  575 
 grub-core/lib/zstd/fse_decompress.c |  329 +
 grub-core/lib/zstd/huf.h|  212 +++
 grub-core/lib/zstd/huf_decompress.c |  957 ++
 grub-core/lib/zstd/kerncompat.h |   69 +
 grub-core/lib/zstd/mem.h|  155 +++
 grub-core/lib/zstd/xxhash.c |  482 +++
 grub-core/lib/zstd/xxhash.h |  236 
 grub-core/lib/zstd/zstd.h   | 1157 
 grub-core/lib/zstd/zstd_common.c|   75 ++
 grub-core/lib/zstd/zstd_internal.h  |  265 
 tests/btrfs_test.in |1 +
 tests/util/grub-fs-tester.in|4 +-
 20 files changed, 7783 insertions(+), 6 deletions(-)
 create mode 100644 grub-core/lib/zstd/bitstream.h
 create mode 100644 grub-core/lib/zstd/decompress.c
 create mode 100644 grub-core/lib/zstd/entropy_common.c
 create mode 100644 grub-core/lib/zstd/error_private.h
 create mode 100644 grub-core/lib/zstd/fse.h
 create mode 100644 grub-core/lib/zstd/fse_decompress.c
 create mode 100644 grub-core/lib/zstd/huf.h
 create mode 100644 grub-core/lib/zstd/huf_decompress.c
 create mode 100644 grub-core/lib/zstd/kerncompat.h
 create mode 100644 grub-core/lib/zstd/mem.h
 create mode 100644 grub-core/lib/zstd/xxhash.c
 create mode 100644 grub-core/lib/zstd/xxhash.h
 create mode 100644 grub-core/lib/zstd/zstd.h
 create mode 100644 grub-core/lib/zstd/zstd_common.c
 create mode 100644 grub-core/lib/zstd/zstd_internal.h

--
2.16.2

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH 3/3] btrfs: Add zstd support to btrfs

2018-08-27 Thread Nick Terrell
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 
---
 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';
-
+
   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 
 #include 
 #include 
+#include 
 #include 
 #include 

@@ -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)
+
 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

 #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);
+
+   /* Ge

[PATCH 2/3] btrfs: Patch the kernel zstd

2018-08-27 Thread Nick Terrell
Applies patches to the upstream kernel zstd needed to compile in grub.
* Replace kernel headers with "kerncompat.h".
* Replace the unaligned memory access functions.
* Add fallthrough statements for newer gcc versions.
* Rename a variable from "byte" because of a conflicting typedef.
* Remove the module code.
* Switch the memcpy() in ZSTD_copy8() to __builtin_memcpy().

Signed-off-by: Nick Terrell 
---
 grub-core/lib/zstd/bitstream.h  |  6 
 grub-core/lib/zstd/decompress.c | 56 ++
 grub-core/lib/zstd/error_private.h  |  3 +-
 grub-core/lib/zstd/fse.h|  2 +-
 grub-core/lib/zstd/fse_decompress.c |  3 --
 grub-core/lib/zstd/huf.h|  2 +-
 grub-core/lib/zstd/huf_decompress.c |  3 --
 grub-core/lib/zstd/kerncompat.h | 69 +
 grub-core/lib/zstd/mem.h| 42 --
 grub-core/lib/zstd/xxhash.c | 22 ++--
 grub-core/lib/zstd/xxhash.h |  2 +-
 grub-core/lib/zstd/zstd.h   |  2 +-
 grub-core/lib/zstd/zstd_common.c|  2 +-
 grub-core/lib/zstd/zstd_internal.h  | 12 ---
 14 files changed, 124 insertions(+), 102 deletions(-)
 create mode 100644 grub-core/lib/zstd/kerncompat.h

diff --git a/grub-core/lib/zstd/bitstream.h b/grub-core/lib/zstd/bitstream.h
index a826b99e1..92a6c3fb9 100644
--- a/grub-core/lib/zstd/bitstream.h
+++ b/grub-core/lib/zstd/bitstream.h
@@ -51,6 +51,7 @@
 *  Dependencies
 **/
 #include "error_private.h" /* error codes and messages */
+#include "kerncompat.h"
 #include "mem.h"  /* unaligned access routines */

 /*=
@@ -259,10 +260,15 @@ ZSTD_STATIC size_t BIT_initDStream(BIT_DStream_t *bitD, 
const void *srcBuffer, s
bitD->bitContainer = *(const BYTE *)(bitD->start);
switch (srcSize) {
case 7: bitD->bitContainer += (size_t)(((const BYTE 
*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer) * 8 - 16);
+   /* fallthrough */
case 6: bitD->bitContainer += (size_t)(((const BYTE 
*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer) * 8 - 24);
+   /* fallthrough */
case 5: bitD->bitContainer += (size_t)(((const BYTE 
*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer) * 8 - 32);
+   /* fallthrough */
case 4: bitD->bitContainer += (size_t)(((const BYTE 
*)(srcBuffer))[3]) << 24;
+   /* fallthrough */
case 3: bitD->bitContainer += (size_t)(((const BYTE 
*)(srcBuffer))[2]) << 16;
+   /* fallthrough */
case 2: bitD->bitContainer += (size_t)(((const BYTE 
*)(srcBuffer))[1]) << 8;
default:;
}
diff --git a/grub-core/lib/zstd/decompress.c b/grub-core/lib/zstd/decompress.c
index b17846725..e7af8df09 100644
--- a/grub-core/lib/zstd/decompress.c
+++ b/grub-core/lib/zstd/decompress.c
@@ -33,9 +33,6 @@
 #include "huf.h"
 #include "mem.h" /* low level memory routines */
 #include "zstd_internal.h"
-#include 
-#include 
-#include  /* memcpy, memmove, memset */

 #define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0)

@@ -123,6 +120,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx *dctx)
return 0;
 }

+static
 ZSTD_DCtx *ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
 {
ZSTD_DCtx *dctx;
@@ -391,6 +389,7 @@ typedef struct {

 /*! ZSTD_getcBlockSize() :
 *   Provides the size of compressed block from block header `src` */
+static
 size_t ZSTD_getcBlockSize(const void *src, size_t srcSize, blockProperties_t 
*bpPtr)
 {
if (srcSize < ZSTD_blockHeaderSize)
@@ -429,6 +428,7 @@ static size_t ZSTD_setRleBlock(void *dst, size_t 
dstCapacity, const void *src, s

 /*! ZSTD_decodeLiteralsBlock() :
@return : nb of bytes read from src (< srcSize ) */
+static
 size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx *dctx, const void *src, size_t 
srcSize) /* note : srcSize < BLOCKSIZE */
 {
if (srcSize < MIN_CBLOCK_SIZE)
@@ -791,6 +791,7 @@ static size_t ZSTD_buildSeqTable(FSE_DTable *DTableSpace, 
const FSE_DTable **DTa
}
 }

+static
 size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx *dctx, int *nbSeqPtr, const void *src, 
size_t srcSize)
 {
const BYTE *const istart = (const BYTE *const)src;
@@ -1494,11 +1495,12 @@ size_t ZSTD_insertBlock(ZSTD_DCtx *dctx, const void 
*blockStart, size_t blockSiz
return blockSize;
 }

-size_t ZSTD_generateNxBytes(void *dst, size_t dstCapacity, BYTE byte, size_t 
length)
+static
+size_t ZSTD_generateNxBytes(void *dst, size_t dstCapacity, BYTE value, size_t 
length)
 {
if (length > dstCapacity)
return ERROR(dstSize_tooSmall);
-   memset(dst, byte, length);
+   memset(dst, value, length);
return length;
 }

@@ -1768,6 +1770,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx *dctx, void 
*dst, size_t dstCapacity, c
r