commit: f88fdd48fbb263498caae394786036a43c552b32
parent d701f8d7f76b649843fb927315dbb72d517495d9
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Mon, 14 Apr 2025 09:33:15 +0200
sys-boot/grub: Add support for zfs zstd decompression
Diffstat:
3 files changed, 179 insertions(+), 0 deletions(-)
diff --git a/patches/sys-boot/grub/grub-2.12-vdev_zaps_v2_head_errlog.patch b/patches/sys-boot/grub/grub-2.12-vdev_zaps_v2_head_errlog.patch
@@ -0,0 +1,29 @@
+From c464f1ec3486469cc47718a4de6730fefd1d9bf4 Mon Sep 17 00:00:00 2001
+From: Vladimir Serbinenko <phcoder@gmail.com>
+Date: Thu, 16 May 2024 22:27:41 +0300
+Subject: fs/zfs/zfs: Mark vdev_zaps_v2 and head_errlog as supported
+
+We don't need any actual adjustments as we don't use the affected structures.
+
+Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+---
+ grub-core/fs/zfs/zfs.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
+index b5453e0..dbe4ea5 100644
+--- a/grub-core/fs/zfs/zfs.c
++++ b/grub-core/fs/zfs/zfs.c
+@@ -291,6 +291,8 @@ static const char *spa_feature_names[] = {
+ "com.delphix:embedded_data",
+ "com.delphix:extensible_dataset",
+ "org.open-zfs:large_blocks",
++ "com.klarasystems:vdev_zaps_v2",
++ "com.delphix:head_errlog",
+ NULL
+ };
+
+--
+cgit v1.1
+
diff --git a/patches/sys-boot/grub/grub-2.12-zstd.patch b/patches/sys-boot/grub/grub-2.12-zstd.patch
@@ -0,0 +1,110 @@
+From f96df6fe9f6faa328c82820af88f14af07b2c9b9 Mon Sep 17 00:00:00 2001
+From: Vladimir Serbinenko <phcoder@gmail.com>
+Date: Mon, 17 Jun 2024 14:44:08 +0300
+Subject: fs/zfs/zfs: Add support for zstd compression
+
+Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+---
+ grub-core/Makefile.core.def | 1 +
+ grub-core/fs/zfs/zfs.c | 38 ++++++++++++++++++++++++++++++++++++++
+ include/grub/zfs/zio.h | 1 +
+ 3 files changed, 40 insertions(+)
+
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
+index 7fa9446..705d73f 100644
+--- a/grub-core/Makefile.core.def
++++ b/grub-core/Makefile.core.def
+@@ -1601,6 +1601,7 @@ module = {
+ common = fs/zfs/zfs_lz4.c;
+ common = fs/zfs/zfs_sha256.c;
+ common = fs/zfs/zfs_fletcher.c;
++ cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/zstd';
+ };
+
+ module = {
+diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
+index dbe4ea5..3fdf9bd 100644
+--- a/grub-core/fs/zfs/zfs.c
++++ b/grub-core/fs/zfs/zfs.c
+@@ -57,6 +57,8 @@
+ #include <grub/i18n.h>
+ #include <grub/safemath.h>
+
++#include <zstd.h>
++
+ GRUB_MOD_LICENSE ("GPLv3+");
+
+ #define ZPOOL_PROP_BOOTFS "bootfs"
+@@ -293,6 +295,7 @@ static const char *spa_feature_names[] = {
+ "org.open-zfs:large_blocks",
+ "com.klarasystems:vdev_zaps_v2",
+ "com.delphix:head_errlog",
++ "org.freebsd:zstd_compress",
+ NULL
+ };
+
+@@ -315,6 +318,40 @@ zlib_decompress (void *s, void *d,
+ }
+
+ static grub_err_t
++zstd_decompress (void *ibuf, void *obuf, grub_size_t isize,
++ grub_size_t osize)
++{
++ grub_size_t zstd_ret;
++ grub_uint32_t c_len;
++ grub_uint8_t *byte_buf = (grub_uint8_t *) ibuf;
++
++ if (isize < 8)
++ return grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data too short");
++
++ c_len = grub_be_to_cpu32 (grub_get_unaligned32 (byte_buf));
++
++ if (c_len > isize - 8)
++ return grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
++ "zstd data announced size overflow");
++
++ /*
++ * ZFS uses non-stadard magic for zstd streams. Rather than adjusting
++ * library functions, replace non-standard magic with standard one.
++ */
++ byte_buf[4] = 0x28;
++ byte_buf[5] = 0xb5;
++ byte_buf[6] = 0x2f;
++ byte_buf[7] = 0xfd;
++ zstd_ret = ZSTD_decompress (obuf, osize, byte_buf + 4, c_len + 4);
++
++ if (ZSTD_isError (zstd_ret))
++ return grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
++ "zstd data corrupted (error %d)", (int) zstd_ret);
++
++ return GRUB_ERR_NONE;
++}
++
++static grub_err_t
+ zle_decompress (void *s, void *d,
+ grub_size_t slen, grub_size_t dlen)
+ {
+@@ -364,6 +401,7 @@ static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = {
+ {"gzip-9", zlib_decompress}, /* ZIO_COMPRESS_GZIP9 */
+ {"zle", zle_decompress}, /* ZIO_COMPRESS_ZLE */
+ {"lz4", lz4_decompress}, /* ZIO_COMPRESS_LZ4 */
++ {"zstd", zstd_decompress}, /* ZIO_COMPRESS_ZSTD */
+ };
+
+ static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian,
+diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h
+index 19ce136..997b0c4 100644
+--- a/include/grub/zfs/zio.h
++++ b/include/grub/zfs/zio.h
+@@ -89,6 +89,7 @@ enum zio_compress {
+ ZIO_COMPRESS_GZIP9,
+ ZIO_COMPRESS_ZLE,
+ ZIO_COMPRESS_LZ4,
++ ZIO_COMPRESS_ZSTD,
+ ZIO_COMPRESS_FUNCTIONS
+ };
+
+--
+cgit v1.1
+
diff --git a/patches/sys-boot/grub/grub-2.12-zstd_test.patch b/patches/sys-boot/grub/grub-2.12-zstd_test.patch
@@ -0,0 +1,40 @@
+From 9a2134a70fc6c7cad6d6954db5ab6732828dbfc1 Mon Sep 17 00:00:00 2001
+From: Vladimir Serbinenko <phcoder@gmail.com>
+Date: Mon, 17 Jun 2024 14:44:09 +0300
+Subject: tests: Add test for ZFS zstd
+
+Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+---
+ tests/util/grub-fs-tester.in | 2 +-
+ tests/zfs_test.in | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in
+index 2f5e9be..cac58da 100644
+--- a/tests/util/grub-fs-tester.in
++++ b/tests/util/grub-fs-tester.in
+@@ -785,7 +785,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do
+ sleep 1
+ "zfs" create -o casesensitivity=insensitive "$FSLABEL"/"grub fs"
+ sleep 1;;
+- x"zfs_lzjb" | xzfs_gzip | xzfs_zle)
++ x"zfs_lzjb" | xzfs_gzip | xzfs_zle | xzfs_zstd)
+ "zpool" create -O compression=${fs/zfs_/} -R "$MNTPOINTRW" "$FSLABEL" "${MOUNTDEVICE}"
+ sleep 1
+ "zfs" create -o compression=${fs/zfs_/} "$FSLABEL"/"grub fs"
+diff --git a/tests/zfs_test.in b/tests/zfs_test.in
+index 58cc25b..0d0a57f 100644
+--- a/tests/zfs_test.in
++++ b/tests/zfs_test.in
+@@ -19,6 +19,7 @@ fi
+ "@builddir@/grub-fs-tester" zfs_lzjb
+ "@builddir@/grub-fs-tester" zfs_gzip
+ "@builddir@/grub-fs-tester" zfs_zle
++"@builddir@/grub-fs-tester" zfs_zstd
+ "@builddir@/grub-fs-tester" zfs_raidz3
+ "@builddir@/grub-fs-tester" zfs_raidz2
+ "@builddir@/grub-fs-tester" zfs_raidz
+--
+cgit v1.1
+