grub2/0293-ext2-Support-META_BG.patch
Peter Jones 8c6b1ac71e Reconcile with upstream once again.
Also include some minor fixes for gcc 5.1.1

Signed-off-by: Peter Jones <pjones@redhat.com>
2015-07-22 09:46:32 -04:00

135 lines
5.2 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From e20aa39ea4298011ba716087713cff26c6c52006 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <phcoder@gmail.com>
Date: Mon, 16 Feb 2015 20:53:26 +0100
Subject: [PATCH 293/506] ext2: Support META_BG.
This fixes bug that system would become unbootable after ext*
online resize if no resize_inode was created at ext* format time.
---
grub-core/fs/ext2.c | 61 +++++++++++++++++++++++++++++++++++++++++---
tests/ext234_test.in | 1 +
tests/util/grub-fs-tester.in | 6 ++++-
3 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
index 44c7974..4d45edc 100644
--- a/grub-core/fs/ext2.c
+++ b/grub-core/fs/ext2.c
@@ -107,6 +107,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define EXT2_DRIVER_SUPPORTED_INCOMPAT ( EXT2_FEATURE_INCOMPAT_FILETYPE \
| EXT4_FEATURE_INCOMPAT_EXTENTS \
| EXT4_FEATURE_INCOMPAT_FLEX_BG \
+ | EXT2_FEATURE_INCOMPAT_META_BG \
| EXT4_FEATURE_INCOMPAT_64BIT)
/* List of rationales for the ignored "incompatible" features:
* needs_recovery: Not really back-incompatible - was added as such to forbid
@@ -331,16 +332,68 @@ static grub_dl_t my_mod;
+/* Check is a = b^x for some x. */
+static inline int
+is_power_of (grub_uint64_t a, grub_uint32_t b)
+{
+ grub_uint64_t c;
+ /* Prevent overflow assuming b < 8. */
+ if (a >= (1LL << 60))
+ return 0;
+ for (c = 1; c <= a; c *= b);
+ return (c == a);
+}
+
+
+static inline int
+group_has_super_block (struct grub_ext2_data *data, grub_uint64_t group)
+{
+ if (!(data->sblock.feature_ro_compat
+ & grub_cpu_to_le32_compile_time(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)))
+ return 1;
+ /* Algorithm looked up in Linux source. */
+ if (group <= 1)
+ return 1;
+ /* Even number is never a power of odd number. */
+ if (!(group & 1))
+ return 0;
+ return (is_power_of(group, 7) || is_power_of(group, 5) ||
+ is_power_of(group, 3));
+}
+
/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of
the mounted filesystem DATA. */
inline static grub_err_t
-grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
+grub_ext2_blockgroup (struct grub_ext2_data *data, grub_uint64_t group,
struct grub_ext2_block_group *blkgrp)
{
+ grub_uint64_t full_offset = (group << data->log_group_desc_size);
+ grub_uint64_t block, offset;
+ block = (full_offset >> LOG2_BLOCK_SIZE (data));
+ offset = (full_offset & ((1 << LOG2_BLOCK_SIZE (data)) - 1));
+ if ((data->sblock.feature_incompat
+ & grub_cpu_to_le32_compile_time (EXT2_FEATURE_INCOMPAT_META_BG))
+ && block >= grub_le_to_cpu32(data->sblock.first_meta_bg))
+ {
+ grub_uint64_t first_block_group;
+ /* Find the first block group for which a descriptor
+ is stored in given block. */
+ first_block_group = (block << (LOG2_BLOCK_SIZE (data)
+ - data->log_group_desc_size));
+
+ block = (first_block_group
+ * grub_le_to_cpu32(data->sblock.blocks_per_group));
+
+ if (group_has_super_block (data, first_block_group))
+ block++;
+ }
+ else
+ /* Superblock. */
+ block++;
return grub_disk_read (data->disk,
- ((grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
- << LOG2_EXT2_BLOCK_SIZE (data)),
- group << data->log_group_desc_size,
+ ((grub_le_to_cpu32 (data->sblock.first_data_block)
+ + block)
+ << LOG2_EXT2_BLOCK_SIZE (data)), offset,
sizeof (struct grub_ext2_block_group), blkgrp);
}
diff --git a/tests/ext234_test.in b/tests/ext234_test.in
index 8910b71..c986960 100644
--- a/tests/ext234_test.in
+++ b/tests/ext234_test.in
@@ -29,3 +29,4 @@ fi
"@builddir@/grub-fs-tester" ext2
"@builddir@/grub-fs-tester" ext3
"@builddir@/grub-fs-tester" ext4
+"@builddir@/grub-fs-tester" ext4_metabg
diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in
index 5656927..9ecbe0f 100644
--- a/tests/util/grub-fs-tester.in
+++ b/tests/util/grub-fs-tester.in
@@ -281,7 +281,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
#FSLABEL="g;/_é莭莽😁кит u"
;;
# FS LIMITATION: reiserfs, extN and jfs label is at most 16 UTF-8 characters
- x"reiserfs_old" | x"reiserfs" | x"ext2" | xext2_old | x"ext3" | x"ext4" | x"lvm"* | x"mdraid"* | x"jfs" | x"jfs_caseins")
+ x"reiserfs_old" | x"reiserfs" | x"ext"* | x"lvm"* | x"mdraid"* | x"jfs" | x"jfs_caseins")
FSLABEL="g;/éт 莭😁";;
# FS LIMITATION: No underscore, space, semicolon, slash or international characters in UFS* in label. Limited to 32 UTF-8 characters
x"ufs1" | x"ufs1_sun" | x"ufs2")
@@ -746,6 +746,10 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext2" -r 0 -b $BLKSIZE -L "$FSLABEL" -q "${LODEVICES[0]}"
MOUNTFS=ext2
;;
+ xext4_metabg)
+ MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext4" -O meta_bg,^resize_inode -b $BLKSIZE -L "$FSLABEL" -q "${LODEVICES[0]}"
+ MOUNTFS=ext4
+ ;;
xext*)
MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.$fs" -b $BLKSIZE -L "$FSLABEL" -q "${LODEVICES[0]}" ;;
xxfs)
--
2.4.3