SHA256
1
0
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:
Michael Chang 2021-09-06 08:56:32 +00:00 committed by Git OBS Bridge
parent 473231b79f
commit 39eeed1efc
4 changed files with 559 additions and 136 deletions

View File

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

View 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, &sectors, 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

View File

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

View File

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