forked from pool/grub2
Accepting request 916104 from home:michael-chang:branches:Base:System
- Add btrfs zstd compression on i386-pc and also make sure it won't break existing grub installations (bsc#1161823) * deleted 0001-btrfs-disable-zstd-support-for-i386-pc.patch * added 0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch OBS-URL: https://build.opensuse.org/request/show/916104 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=392
This commit is contained in:
parent
473231b79f
commit
39eeed1efc
@ -1,135 +0,0 @@
|
||||
From adf02937d4859495aab539818a116efa23505eaa Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 28 Oct 2019 05:48:11 -0400
|
||||
Subject: [PATCH] btrfs: disable zstd support for i386-pc
|
||||
|
||||
The zstd support in btrfs has dependenciy to zstd module and core.img
|
||||
grows its size significantly to 75KB on my system. The resulted image
|
||||
cannot be installed into btrfs bootloader area in the size of 64KB and
|
||||
eventually fails with following message.
|
||||
|
||||
/usr/sbin/grub-install: warning: your core.img is unusually large. It
|
||||
won't fit in the embedding area.
|
||||
/usr/sbin/grub-install: error: filesystem `btrfs' doesn't support
|
||||
blocklists.
|
||||
|
||||
The patch disabled the zstd support of btrfs in pc-bios platform to
|
||||
avoid the regression. The resulting size is 56KB, albeit a bit too close
|
||||
to the 64KB but works. This is simple workaround until a proper fix
|
||||
landed upstream.
|
||||
---
|
||||
grub-core/fs/btrfs.c | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
|
||||
index eed7099d8..21a7641c0 100644
|
||||
--- a/grub-core/fs/btrfs.c
|
||||
+++ b/grub-core/fs/btrfs.c
|
||||
@@ -17,6 +17,7 @@
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
/*
|
||||
* Tell zstd to expose functions that aren't part of the stable API, which
|
||||
* aren't safe to use when linking against a dynamic library. We vendor in a
|
||||
@@ -24,6 +25,7 @@
|
||||
* functions to provide our own allocator, which uses grub_malloc(), to zstd.
|
||||
*/
|
||||
#define ZSTD_STATIC_LINKING_ONLY
|
||||
+#endif
|
||||
|
||||
#include <grub/err.h>
|
||||
#include <grub/file.h>
|
||||
@@ -35,7 +37,9 @@
|
||||
#include <grub/lib/crc.h>
|
||||
#include <grub/deflate.h>
|
||||
#include <minilzo.h>
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
#include <zstd.h>
|
||||
+#endif
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/btrfs.h>
|
||||
#include <grub/crypto.h>
|
||||
@@ -60,8 +64,10 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#define GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE (GRUB_BTRFS_LZO_BLOCK_SIZE + \
|
||||
(GRUB_BTRFS_LZO_BLOCK_SIZE / 16) + 64 + 3)
|
||||
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
#define ZSTD_BTRFS_MAX_WINDOWLOG 17
|
||||
#define ZSTD_BTRFS_MAX_INPUT (1 << ZSTD_BTRFS_MAX_WINDOWLOG)
|
||||
+#endif
|
||||
|
||||
typedef grub_uint8_t grub_btrfs_checksum_t[0x20];
|
||||
typedef grub_uint16_t grub_btrfs_uuid_t[8];
|
||||
@@ -244,7 +250,9 @@ struct grub_btrfs_extent_data
|
||||
#define GRUB_BTRFS_COMPRESSION_NONE 0
|
||||
#define GRUB_BTRFS_COMPRESSION_ZLIB 1
|
||||
#define GRUB_BTRFS_COMPRESSION_LZO 2
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
#define GRUB_BTRFS_COMPRESSION_ZSTD 3
|
||||
+#endif
|
||||
|
||||
#define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100
|
||||
|
||||
@@ -1372,6 +1380,7 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data,
|
||||
return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode), 0);
|
||||
}
|
||||
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
static void *grub_zstd_malloc (void *state __attribute__((unused)), size_t size)
|
||||
{
|
||||
return grub_malloc (size);
|
||||
@@ -1461,6 +1470,7 @@ err:
|
||||
|
||||
return ret;
|
||||
}
|
||||
+#endif
|
||||
|
||||
static grub_ssize_t
|
||||
grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off,
|
||||
@@ -1637,8 +1647,12 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||
|
||||
if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE
|
||||
&& data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
&& data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO
|
||||
&& data->extent->compression != GRUB_BTRFS_COMPRESSION_ZSTD)
|
||||
+#else
|
||||
+ && data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO)
|
||||
+#endif
|
||||
{
|
||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"compression type 0x%x not supported",
|
||||
@@ -1678,6 +1692,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||
!= (grub_ssize_t) csize)
|
||||
return -1;
|
||||
}
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZSTD)
|
||||
{
|
||||
if (grub_btrfs_zstd_decompress (data->extent->inl, data->extsize -
|
||||
@@ -1687,6 +1702,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||
!= (grub_ssize_t) csize)
|
||||
return -1;
|
||||
}
|
||||
+#endif
|
||||
else
|
||||
grub_memcpy (buf, data->extent->inl + extoff, csize);
|
||||
break;
|
||||
@@ -1724,10 +1740,12 @@ 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);
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
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);
|
||||
+#endif
|
||||
else
|
||||
ret = -1;
|
||||
|
||||
--
|
||||
2.21.0
|
||||
|
550
0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch
Normal file
550
0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch
Normal file
@ -0,0 +1,550 @@
|
||||
From e7fe15db1736e038a7705973424708d3151fde99 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 12 Aug 2021 21:43:22 +0800
|
||||
Subject: [PATCH] i386-pc: build btrfs zstd support into separate module
|
||||
|
||||
The zstd support in btrfs brings significant size increment to the
|
||||
on-disk image that it can no longer fit into btrfs bootloader area and
|
||||
short mbr gap.
|
||||
|
||||
In order to support grub update on outstanding i386-pc setup with these
|
||||
size constraints remain in place, here we build the zstd suppprt of
|
||||
btrfs into a separate module, named btrfs_zstd, to alleviate the size
|
||||
change. Please note this only makes it's way to i386-pc, other
|
||||
architecture is not affected.
|
||||
|
||||
Therefore if the system has enough space of embedding area for grub then
|
||||
zstd support for btrfs will be enabled automatically in the process of
|
||||
running grub-install through inserting btrfs_zstd module to the on-disk
|
||||
image, otherwise a warning will be logged on screen to indicate user
|
||||
that zstd support for btrfs is disabled due to the size limit.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
Makefile.util.def | 1 +
|
||||
grub-core/Makefile.core.def | 11 ++++
|
||||
grub-core/fs/btrfs.c | 114 +++++---------------------------
|
||||
grub-core/fs/btrfs_zstd.c | 36 +++++++++++
|
||||
grub-core/lib/zstd.c | 126 ++++++++++++++++++++++++++++++++++++
|
||||
include/grub/btrfs.h | 6 ++
|
||||
include/grub/lib/zstd.h | 26 ++++++++
|
||||
include/grub/util/install.h | 2 +
|
||||
util/grub-install.c | 20 ++++++
|
||||
util/setup.c | 43 ++++++++++++
|
||||
10 files changed, 288 insertions(+), 97 deletions(-)
|
||||
create mode 100644 grub-core/fs/btrfs_zstd.c
|
||||
create mode 100644 grub-core/lib/zstd.c
|
||||
create mode 100644 include/grub/lib/zstd.h
|
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def
|
||||
index 2f2881cb7..ac2b6aab1 100644
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -176,6 +176,7 @@ library = {
|
||||
common = grub-core/lib/zstd/xxhash.c;
|
||||
common = grub-core/lib/zstd/zstd_common.c;
|
||||
common = grub-core/lib/zstd/zstd_decompress.c;
|
||||
+ common = grub-core/lib/zstd.c;
|
||||
};
|
||||
|
||||
program = {
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index dd1777bd3..b5328d7a0 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1370,10 +1370,21 @@ module = {
|
||||
name = btrfs;
|
||||
common = fs/btrfs.c;
|
||||
common = lib/crc.c;
|
||||
+ nopc = lib/zstd.c;
|
||||
cflags = '$(CFLAGS_POSIX) -Wno-undef';
|
||||
+ i386_pc_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 = {
|
||||
+ name = btrfs_zstd;
|
||||
+ common = fs/btrfs_zstd.c;
|
||||
+ common = lib/zstd.c;
|
||||
+ cflags = '$(CFLAGS_POSIX) -Wno-undef';
|
||||
+ cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/zstd';
|
||||
+ enable = i386_pc;
|
||||
+};
|
||||
+
|
||||
module = {
|
||||
name = archelp;
|
||||
common = fs/archelp.c;
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
|
||||
index c908b460f..9625bdf16 100644
|
||||
--- a/grub-core/fs/btrfs.c
|
||||
+++ b/grub-core/fs/btrfs.c
|
||||
@@ -17,14 +17,6 @@
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
-/*
|
||||
- * Tell zstd to expose functions that aren't part of the stable API, which
|
||||
- * aren't safe to use when linking against a dynamic library. We vendor in a
|
||||
- * specific zstd version, so we know what we're getting. We need these unstable
|
||||
- * functions to provide our own allocator, which uses grub_malloc(), to zstd.
|
||||
- */
|
||||
-#define ZSTD_STATIC_LINKING_ONLY
|
||||
-
|
||||
#include <grub/err.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/mm.h>
|
||||
@@ -35,7 +27,9 @@
|
||||
#include <grub/lib/crc.h>
|
||||
#include <grub/deflate.h>
|
||||
#include <minilzo.h>
|
||||
-#include <zstd.h>
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
+#include <grub/lib/zstd.h>
|
||||
+#endif
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/btrfs.h>
|
||||
#include <grub/crypto.h>
|
||||
@@ -61,12 +55,15 @@ 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];
|
||||
|
||||
+#ifdef GRUB_MACHINE_PCBIOS
|
||||
+grub_ssize_t (*grub_btrfs_zstd_decompress_func) (char *ibuf,
|
||||
+ grub_size_t isize, grub_off_t off,
|
||||
+ char *obuf, grub_size_t osize) = NULL;
|
||||
+#endif
|
||||
+
|
||||
struct grub_btrfs_device
|
||||
{
|
||||
grub_uint64_t device_id;
|
||||
@@ -1392,94 +1389,17 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data,
|
||||
return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode), 0);
|
||||
}
|
||||
|
||||
-static void *grub_zstd_malloc (void *state __attribute__((unused)), size_t size)
|
||||
-{
|
||||
- return grub_malloc (size);
|
||||
-}
|
||||
-
|
||||
-static void grub_zstd_free (void *state __attribute__((unused)), void *address)
|
||||
-{
|
||||
- return grub_free (address);
|
||||
-}
|
||||
-
|
||||
-static ZSTD_customMem grub_zstd_allocator (void)
|
||||
-{
|
||||
- ZSTD_customMem allocator;
|
||||
-
|
||||
- allocator.customAlloc = &grub_zstd_malloc;
|
||||
- allocator.customFree = &grub_zstd_free;
|
||||
- allocator.opaque = NULL;
|
||||
-
|
||||
- return allocator;
|
||||
-}
|
||||
-
|
||||
-static grub_ssize_t
|
||||
+static inline 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;
|
||||
- ZSTD_DCtx *dctx = NULL;
|
||||
- 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_error (GRUB_ERR_OUT_OF_MEMORY, "failed allocate a zstd buffer");
|
||||
- goto err;
|
||||
- }
|
||||
- otmpbuf = (char *) allocated;
|
||||
- otmpsize = ZSTD_BTRFS_MAX_INPUT;
|
||||
- }
|
||||
-
|
||||
- /* Create the ZSTD_DCtx. */
|
||||
- dctx = ZSTD_createDCtx_advanced (grub_zstd_allocator ());
|
||||
- if (!dctx)
|
||||
- {
|
||||
- /* ZSTD_createDCtx_advanced() only fails if it is out of memory. */
|
||||
- grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to create a zstd context");
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * 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_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data corrupted");
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- /* Decompress and check for errors. */
|
||||
- zstd_ret = ZSTD_decompressDCtx (dctx, otmpbuf, otmpsize, ibuf, isize);
|
||||
- if (ZSTD_isError (zstd_ret))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data corrupted");
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * 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;
|
||||
-
|
||||
-err:
|
||||
- grub_free (allocated);
|
||||
- ZSTD_freeDCtx (dctx);
|
||||
-
|
||||
- return ret;
|
||||
+#ifdef GRUB_MACHINE_PCBIOS
|
||||
+ if (!grub_btrfs_zstd_decompress_func)
|
||||
+ return -1;
|
||||
+ return grub_btrfs_zstd_decompress_func (ibuf, isize, off, obuf, osize);
|
||||
+#else
|
||||
+ return grub_zstd_decompress (ibuf, isize, off, obuf, osize);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static grub_ssize_t
|
||||
diff --git a/grub-core/fs/btrfs_zstd.c b/grub-core/fs/btrfs_zstd.c
|
||||
new file mode 100644
|
||||
index 000000000..d5d1e013c
|
||||
--- /dev/null
|
||||
+++ b/grub-core/fs/btrfs_zstd.c
|
||||
@@ -0,0 +1,36 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * GRUB is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * GRUB is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/dl.h>
|
||||
+/* For NULL. */
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/btrfs.h>
|
||||
+#include <grub/lib/zstd.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+GRUB_MOD_INIT (btrfs_zstd)
|
||||
+{
|
||||
+ grub_btrfs_zstd_decompress_func = grub_zstd_decompress;
|
||||
+}
|
||||
+
|
||||
+GRUB_MOD_FINI (btrfs_zstd)
|
||||
+{
|
||||
+ grub_btrfs_zstd_decompress_func = NULL;
|
||||
+}
|
||||
diff --git a/grub-core/lib/zstd.c b/grub-core/lib/zstd.c
|
||||
new file mode 100644
|
||||
index 000000000..643e90d84
|
||||
--- /dev/null
|
||||
+++ b/grub-core/lib/zstd.c
|
||||
@@ -0,0 +1,126 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * GRUB is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * GRUB is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Tell zstd to expose functions that aren't part of the stable API, which
|
||||
+ * aren't safe to use when linking against a dynamic library. We vendor in a
|
||||
+ * specific zstd version, so we know what we're getting. We need these unstable
|
||||
+ * functions to provide our own allocator, which uses grub_malloc(), to zstd.
|
||||
+ */
|
||||
+#define ZSTD_STATIC_LINKING_ONLY
|
||||
+
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/lib/zstd.h>
|
||||
+#include <zstd.h>
|
||||
+
|
||||
+#define ZSTD_MAX_WINDOWLOG 17
|
||||
+#define ZSTD_MAX_INPUT (1 << ZSTD_MAX_WINDOWLOG)
|
||||
+
|
||||
+static void *grub_zstd_malloc (void *state __attribute__((unused)), size_t size)
|
||||
+{
|
||||
+ return grub_malloc (size);
|
||||
+}
|
||||
+
|
||||
+static void grub_zstd_free (void *state __attribute__((unused)), void *address)
|
||||
+{
|
||||
+ return grub_free (address);
|
||||
+}
|
||||
+
|
||||
+static ZSTD_customMem grub_zstd_allocator (void)
|
||||
+{
|
||||
+ ZSTD_customMem allocator;
|
||||
+
|
||||
+ allocator.customAlloc = &grub_zstd_malloc;
|
||||
+ allocator.customFree = &grub_zstd_free;
|
||||
+ allocator.opaque = NULL;
|
||||
+
|
||||
+ return allocator;
|
||||
+}
|
||||
+
|
||||
+grub_ssize_t
|
||||
+grub_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;
|
||||
+ ZSTD_DCtx *dctx = NULL;
|
||||
+ 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_MAX_INPUT)
|
||||
+ {
|
||||
+ allocated = grub_malloc (ZSTD_MAX_INPUT);
|
||||
+ if (!allocated)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed allocate a zstd buffer");
|
||||
+ goto err;
|
||||
+ }
|
||||
+ otmpbuf = (char *) allocated;
|
||||
+ otmpsize = ZSTD_MAX_INPUT;
|
||||
+ }
|
||||
+
|
||||
+ /* Create the ZSTD_DCtx. */
|
||||
+ dctx = ZSTD_createDCtx_advanced (grub_zstd_allocator ());
|
||||
+ if (!dctx)
|
||||
+ {
|
||||
+ /* ZSTD_createDCtx_advanced() only fails if it is out of memory. */
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to create a zstd context");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * 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_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data corrupted");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ /* Decompress and check for errors. */
|
||||
+ zstd_ret = ZSTD_decompressDCtx (dctx, otmpbuf, otmpsize, ibuf, isize);
|
||||
+ if (ZSTD_isError (zstd_ret))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data corrupted");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * 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;
|
||||
+
|
||||
+err:
|
||||
+ grub_free (allocated);
|
||||
+ ZSTD_freeDCtx (dctx);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
diff --git a/include/grub/btrfs.h b/include/grub/btrfs.h
|
||||
index 234ad9767..f8e551982 100644
|
||||
--- a/include/grub/btrfs.h
|
||||
+++ b/include/grub/btrfs.h
|
||||
@@ -69,4 +69,10 @@ struct grub_btrfs_inode_ref
|
||||
char name[0];
|
||||
};
|
||||
|
||||
+#ifdef GRUB_MACHINE_PCBIOS
|
||||
+extern grub_ssize_t (*EXPORT_VAR (grub_btrfs_zstd_decompress_func)) (char *ibuf,
|
||||
+ grub_size_t isize, grub_off_t off,
|
||||
+ char *obuf, grub_size_t osize);
|
||||
+#endif
|
||||
+
|
||||
#endif
|
||||
diff --git a/include/grub/lib/zstd.h b/include/grub/lib/zstd.h
|
||||
new file mode 100644
|
||||
index 000000000..0867b0c34
|
||||
--- /dev/null
|
||||
+++ b/include/grub/lib/zstd.h
|
||||
@@ -0,0 +1,26 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * GRUB is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * GRUB is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_ZSTD_HEADER
|
||||
+#define GRUB_ZSTD_HEADER 1
|
||||
+
|
||||
+grub_ssize_t
|
||||
+grub_zstd_decompress (char *ibuf, grub_size_t isize, grub_off_t off,
|
||||
+ char *obuf, grub_size_t osize);
|
||||
+
|
||||
+#endif /* ! GRUB_ZSTD_HEADER */
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index faf9ff1ab..9e83e1339 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -208,6 +208,8 @@ grub_util_sparc_setup (const char *dir,
|
||||
const char *dest, int force,
|
||||
int fs_probe, int allow_floppy,
|
||||
int add_rs_codes, int warn_short_mbr_gap);
|
||||
+int
|
||||
+grub_util_try_partmap_embed (const char *dest, unsigned int *nsec);
|
||||
|
||||
char *
|
||||
grub_install_get_image_targets_string (void);
|
||||
diff --git a/util/grub-install.c b/util/grub-install.c
|
||||
index 891e3ced8..a2286b3dd 100644
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -1482,6 +1482,26 @@ main (int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
+ if (install_drive
|
||||
+ && platform == GRUB_INSTALL_PLATFORM_I386_PC
|
||||
+ && grub_strcmp (grub_fs->name, "btrfs") == 0)
|
||||
+ {
|
||||
+ char *mod;
|
||||
+ mod = grub_util_path_concat (2, grub_install_source_directory, "btrfs_zstd.mod");
|
||||
+ if (grub_util_is_regular (mod))
|
||||
+ {
|
||||
+ unsigned int nsec = GRUB_MIN_RECOMMENDED_MBR_GAP;
|
||||
+ int ret = grub_util_try_partmap_embed (install_drive, &nsec);
|
||||
+ if (ret == 0)
|
||||
+ grub_install_push_module ("btrfs_zstd");
|
||||
+ else if (ret == 1)
|
||||
+ grub_util_warn ("%s", _("btrfs zstd compression is disabled, please change install device to disk"));
|
||||
+ else
|
||||
+ grub_util_warn ("%s", _("btrfs zstd compression is disabled due to not enough space to embed image"));
|
||||
+ }
|
||||
+ grub_free (mod);
|
||||
+ }
|
||||
+
|
||||
if (!have_abstractions)
|
||||
{
|
||||
if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0)
|
||||
diff --git a/util/setup.c b/util/setup.c
|
||||
index 980e74374..6604d86bb 100644
|
||||
--- a/util/setup.c
|
||||
+++ b/util/setup.c
|
||||
@@ -241,6 +241,49 @@ identify_partmap (grub_disk_t disk __attribute__ ((unused)),
|
||||
return 1;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_SETUP_BIOS
|
||||
+int
|
||||
+grub_util_try_partmap_embed (const char *dest, unsigned int *nsec)
|
||||
+{
|
||||
+ grub_device_t dest_dev;
|
||||
+
|
||||
+ dest_dev = grub_device_open (dest);
|
||||
+ if (! dest_dev)
|
||||
+ grub_util_error ("%s", grub_errmsg);
|
||||
+
|
||||
+ struct identify_partmap_ctx ctx = {
|
||||
+ .dest_partmap = NULL,
|
||||
+ .container = dest_dev->disk->partition,
|
||||
+ .multiple_partmaps = 0
|
||||
+ };
|
||||
+
|
||||
+ grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx);
|
||||
+
|
||||
+ if (ctx.dest_partmap && ctx.dest_partmap->embed)
|
||||
+ {
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ grub_disk_addr_t *sectors = NULL;
|
||||
+
|
||||
+ err = ctx.dest_partmap->embed (dest_dev->disk, nsec, *nsec,
|
||||
+ GRUB_EMBED_PCBIOS, §ors, 0);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ goto no_embed;
|
||||
+ }
|
||||
+ grub_free (sectors);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+no_embed:
|
||||
+ grub_device_close (dest_dev);
|
||||
+ if (ctx.container)
|
||||
+ return 1;
|
||||
+ return 2;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#ifdef GRUB_SETUP_BIOS
|
||||
#define SETUP grub_util_bios_setup
|
||||
#elif GRUB_SETUP_SPARC64
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,3 +1,11 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Sep 1 05:49:47 UTC 2021 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Add btrfs zstd compression on i386-pc and also make sure it won't break
|
||||
existing grub installations (bsc#1161823)
|
||||
* deleted 0001-btrfs-disable-zstd-support-for-i386-pc.patch
|
||||
* added 0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Aug 31 05:56:56 UTC 2021 - Petr Vorel <pvorel@suse.cz>
|
||||
|
||||
|
@ -235,7 +235,6 @@ Patch107: grub2-btrfs-07-subvol-fallback.patch
|
||||
Patch108: grub2-btrfs-08-workaround-snapshot-menu-default-entry.patch
|
||||
Patch109: grub2-btrfs-09-get-default-subvolume.patch
|
||||
Patch110: grub2-btrfs-10-config-directory.patch
|
||||
Patch111: 0001-btrfs-disable-zstd-support-for-i386-pc.patch
|
||||
# Support EFI xen loader
|
||||
Patch120: grub2-efi-xen-chainload.patch
|
||||
Patch121: grub2-efi-chainloader-root.patch
|
||||
@ -306,6 +305,7 @@ Patch786: 0046-squash-verifiers-Move-verifiers-API-to-kernel-image.patch
|
||||
Patch788: 0001-ieee1275-Avoiding-many-unecessary-open-close.patch
|
||||
Patch789: 0001-Workaround-volatile-efi-boot-variable.patch
|
||||
Patch790: 0001-30_uefi-firmware-fix-printf-format-with-null-byte.patch
|
||||
Patch791: 0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch
|
||||
|
||||
Requires: gettext-runtime
|
||||
%if 0%{?suse_version} >= 1140
|
||||
|
Loading…
Reference in New Issue
Block a user