Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package grub2 for openSUSE:Factory checked in at 2022-11-25 13:11:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/grub2 (Old) and /work/SRC/openSUSE:Factory/.grub2.new.1597 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "grub2" Fri Nov 25 13:11:15 2022 rev:276 rq:1037800 version:2.06 Changes: -------- --- /work/SRC/openSUSE:Factory/grub2/grub2.changes 2022-11-23 09:47:43.210920548 +0100 +++ /work/SRC/openSUSE:Factory/.grub2.new.1597/grub2.changes 2022-11-25 13:11:17.891726429 +0100 @@ -1,0 +2,9 @@ +Tue Nov 22 08:11:17 UTC 2022 - Michael Chang <mch...@suse.com> + +- Make full utilization of btrfs bootloader area (bsc#1161823) + * 0001-fs-btrfs-Use-full-btrfs-bootloader-area.patch + * 0002-Mark-environmet-blocks-as-used-for-image-embedding.patch +- Patch removed + * 0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch + +------------------------------------------------------------------- Old: ---- 0001-i386-pc-build-btrfs-zstd-support-into-separate-modul.patch New: ---- 0001-fs-btrfs-Use-full-btrfs-bootloader-area.patch 0002-Mark-environmet-blocks-as-used-for-image-embedding.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ grub2.spec ++++++ --- /var/tmp/diff_new_pack.V6s5Vy/_old 2022-11-25 13:11:20.535741197 +0100 +++ /var/tmp/diff_new_pack.V6s5Vy/_new 2022-11-25 13:11:20.539741219 +0100 @@ -313,7 +313,6 @@ 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 Patch792: 0001-templates-Follow-the-path-of-usr-merged-kernel-confi.patch Patch793: 0001-tpm-Pass-unknown-error-as-non-fatal-but-debug-print-.patch Patch794: 0001-Filter-out-POSIX-locale-for-translation.patch @@ -477,6 +476,8 @@ Patch947: 0010-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch Patch948: 0011-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch Patch949: 0012-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch +Patch950: 0001-fs-btrfs-Use-full-btrfs-bootloader-area.patch +Patch951: 0002-Mark-environmet-blocks-as-used-for-image-embedding.patch Requires: gettext-runtime %if 0%{?suse_version} >= 1140 ++++++ 0001-fs-btrfs-Use-full-btrfs-bootloader-area.patch ++++++ >From b78aca6e1c4f72a6491457e849b76c8e0af77765 Mon Sep 17 00:00:00 2001 From: Michael Chang <mch...@suse.com> Date: Mon, 13 Dec 2021 14:25:49 +0800 Subject: [PATCH 1/2] fs/btrfs: Use full btrfs bootloader area Up to now GRUB can only embed to the first 64 KiB before primary superblock of btrfs, effectively limiting the GRUB core size. That could consequently pose restrictions to feature enablement like advanced zstd compression. This patch attempts to utilize full unused area reserved by btrfs for the bootloader outlined in the document [1]: The first 1MiB on each device is unused with the exception of primary superblock that is on the offset 64KiB and spans 4KiB. Apart from that, adjacent sectors to superblock and first block group are not used for embedding in case of overflow and logged access to adjacent sectors could be useful for tracing it up. This patch has been tested to provide out of the box support for btrfs zstd compression with which GRUB has been installed to the partition. [1] https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)#BOOTLOADER_SUPPORT Signed-off-by: Michael Chang <mch...@suse.com> Reviewed-by: Daniel Kiper <daniel.ki...@oracle.com> --- grub-core/fs/btrfs.c | 90 +++++++++++++++++++++++++++++++++++++------- include/grub/disk.h | 2 + 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 7007463c6..979ba1b28 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -2537,6 +2537,33 @@ grub_btrfs_label (grub_device_t device, char **label) } #ifdef GRUB_UTIL + +struct embed_region { + unsigned int start; + unsigned int secs; +}; + +/* + * https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)#BOOTLOADER_SUPPORT + * The first 1 MiB on each device is unused with the exception of primary + * superblock that is on the offset 64 KiB and spans 4 KiB. + */ + +static const struct { + struct embed_region available; + struct embed_region used[6]; +} btrfs_head = { + .available = {0, GRUB_DISK_KiB_TO_SECTORS (1024)}, /* The first 1 MiB. */ + .used = { + {0, 1}, /* boot.S. */ + {GRUB_DISK_KiB_TO_SECTORS (64) - 1, 1}, /* Overflow guard. */ + {GRUB_DISK_KiB_TO_SECTORS (64), GRUB_DISK_KiB_TO_SECTORS (4)}, /* 4 KiB superblock. */ + {GRUB_DISK_KiB_TO_SECTORS (68), 1}, /* Overflow guard. */ + {GRUB_DISK_KiB_TO_SECTORS (1024) - 1, 1}, /* Overflow guard. */ + {0, 0} /* Array terminator. */ + } +}; + static grub_err_t grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), unsigned int *nsectors, @@ -2544,25 +2571,62 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), grub_embed_type_t embed_type, grub_disk_addr_t **sectors) { - unsigned i; + unsigned int i, j, n = 0; + const struct embed_region *u; + grub_disk_addr_t *map; if (embed_type != GRUB_EMBED_PCBIOS) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "BtrFS currently supports only PC-BIOS embedding"); - if (64 * 2 - 1 < *nsectors) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("your core.img is unusually large. " - "It won't fit in the embedding area")); - - *nsectors = 64 * 2 - 1; - if (*nsectors > max_nsectors) - *nsectors = max_nsectors; - *sectors = grub_calloc (*nsectors, sizeof (**sectors)); - if (!*sectors) + map = grub_calloc (btrfs_head.available.secs, sizeof (*map)); + if (map == NULL) return grub_errno; - for (i = 0; i < *nsectors; i++) - (*sectors)[i] = i + 1; + + /* + * Populating the map array so that it can be used to index if a disk + * address is available to embed: + * - 0: available, + * - 1: unavailable. + */ + for (u = btrfs_head.used; u->secs; ++u) + { + unsigned int end = u->start + u->secs; + + if (end > btrfs_head.available.secs) + end = btrfs_head.available.secs; + for (i = u->start; i < end; ++i) + map[i] = 1; + } + + /* Adding up n until it matches total size of available embedding area. */ + for (i = 0; i < btrfs_head.available.secs; ++i) + if (map[i] == 0) + n++; + + if (n < *nsectors) + { + grub_free (map); + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("your core.img is unusually large. " + "It won't fit in the embedding area")); + } + + if (n > max_nsectors) + n = max_nsectors; + + /* + * Populating the array so that it can used to index disk block address for + * an image file's offset to be embedded on disk (the unit is in sectors): + * - i: The disk block address relative to btrfs_head.available.start, + * - j: The offset in image file. + */ + for (i = 0, j = 0; i < btrfs_head.available.secs && j < n; ++i) + if (map[i] == 0) + map[j++] = btrfs_head.available.start + i; + + *nsectors = n; + *sectors = map; return GRUB_ERR_NONE; } diff --git a/include/grub/disk.h b/include/grub/disk.h index 6d656c431..a10fa3bc7 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -182,6 +182,8 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; /* Return value of grub_disk_native_sectors() in case disk size is unknown. */ #define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL +#define GRUB_DISK_KiB_TO_SECTORS(x) ((x) << (10 - GRUB_DISK_SECTOR_BITS)) + /* Convert sector number from one sector size to another. */ static inline grub_disk_addr_t grub_convert_sector (grub_disk_addr_t sector, -- 2.35.3 ++++++ 0002-Mark-environmet-blocks-as-used-for-image-embedding.patch ++++++ >From f01314a822dbe9ad39b2f7d0f3717ef6e4c24f4a Mon Sep 17 00:00:00 2001 From: Michael Chang <mch...@suse.com> Date: Fri, 15 Apr 2022 21:45:04 +0800 Subject: [PATCH 2/2] Mark environmet blocks as used for image embedding. Now that grub will attempt to use full btrfs bootloader area, the embedded image could have overlapped with environment blocks if it's size grows too much. Let's define a dedicated area for environment blocks to the used block mappings for the embedding process so it can be skipped. Signed-off-by: Michael Chang <mch...@suse.com> --- grub-core/fs/btrfs.c | 3 ++- include/grub/fs.h | 2 ++ util/grub-editenv.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 979ba1b28..7017248d1 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -2551,7 +2551,7 @@ struct embed_region { static const struct { struct embed_region available; - struct embed_region used[6]; + struct embed_region used[7]; } btrfs_head = { .available = {0, GRUB_DISK_KiB_TO_SECTORS (1024)}, /* The first 1 MiB. */ .used = { @@ -2559,6 +2559,7 @@ static const struct { {GRUB_DISK_KiB_TO_SECTORS (64) - 1, 1}, /* Overflow guard. */ {GRUB_DISK_KiB_TO_SECTORS (64), GRUB_DISK_KiB_TO_SECTORS (4)}, /* 4 KiB superblock. */ {GRUB_DISK_KiB_TO_SECTORS (68), 1}, /* Overflow guard. */ + {GRUB_DISK_KiB_TO_SECTORS (ENV_BTRFS_OFFSET) - 1, 3}, /* Environment Block. */ {GRUB_DISK_KiB_TO_SECTORS (1024) - 1, 1}, /* Overflow guard. */ {0, 0} /* Array terminator. */ } diff --git a/include/grub/fs.h b/include/grub/fs.h index 026bc3bb8..4c380e334 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -128,4 +128,6 @@ grub_fs_unregister (grub_fs_t fs) grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device); +#define ENV_BTRFS_OFFSET (256) + #endif /* ! GRUB_FS_HEADER */ diff --git a/util/grub-editenv.c b/util/grub-editenv.c index a02d3f2a6..af30aabe7 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -128,7 +128,7 @@ struct fs_envblk_spec { int offset; int size; } fs_envblk_spec[] = { - { "btrfs", 256 * 1024, GRUB_DISK_SECTOR_SIZE }, + { "btrfs", ENV_BTRFS_OFFSET * 1024, GRUB_DISK_SECTOR_SIZE }, { NULL, 0, 0 } }; -- 2.35.3