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.
This commit is contained in:
parent
35a492e4a2
commit
e20aa39ea4
3 changed files with 63 additions and 5 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue