From 39eeed1efc15d04a2fadb2727fac4c062cefd7d0e34bef69de8efcbeeac60d75 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Mon, 6 Sep 2021 08:56:32 +0000 Subject: [PATCH] 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 --- ...rfs-disable-zstd-support-for-i386-pc.patch | 135 ----- ...rfs-zstd-support-into-separate-modul.patch | 550 ++++++++++++++++++ grub2.changes | 8 + grub2.spec | 2 +- 4 files changed, 559 insertions(+), 136 deletions(-) delete mode 100644 0001-btrfs-disable-zstd-support-for-i386-pc.patch create mode 100644 0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch diff --git a/0001-btrfs-disable-zstd-support-for-i386-pc.patch b/0001-btrfs-disable-zstd-support-for-i386-pc.patch deleted file mode 100644 index 449a869..0000000 --- a/0001-btrfs-disable-zstd-support-for-i386-pc.patch +++ /dev/null @@ -1,135 +0,0 @@ -From adf02937d4859495aab539818a116efa23505eaa Mon Sep 17 00:00:00 2001 -From: Michael Chang -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 . - */ - -+#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 - #include -@@ -35,7 +37,9 @@ - #include - #include - #include -+#ifndef GRUB_MACHINE_PCBIOS - #include -+#endif - #include - #include - #include -@@ -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 - diff --git a/0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch b/0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch new file mode 100644 index 0000000..8eb6f08 --- /dev/null +++ b/0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch @@ -0,0 +1,550 @@ +From e7fe15db1736e038a7705973424708d3151fde99 Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 . + */ + +-/* +- * 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 + #include + #include +@@ -35,7 +27,9 @@ + #include + #include + #include +-#include ++#ifndef GRUB_MACHINE_PCBIOS ++#include ++#endif + #include + #include + #include +@@ -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 . ++ */ ++ ++#include ++#include ++/* For NULL. */ ++#include ++#include ++#include ++ ++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 . ++ */ ++ ++/* ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#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 . ++ */ ++ ++#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 + diff --git a/grub2.changes b/grub2.changes index 3fdb0f1..fcd8e0a 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Wed Sep 1 05:49:47 UTC 2021 - Michael Chang + +- 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 diff --git a/grub2.spec b/grub2.spec index 478eeb5..45e4043 100644 --- a/grub2.spec +++ b/grub2.spec @@ -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