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 \
|
#define EXT2_DRIVER_SUPPORTED_INCOMPAT ( EXT2_FEATURE_INCOMPAT_FILETYPE \
|
||||||
| EXT4_FEATURE_INCOMPAT_EXTENTS \
|
| EXT4_FEATURE_INCOMPAT_EXTENTS \
|
||||||
| EXT4_FEATURE_INCOMPAT_FLEX_BG \
|
| EXT4_FEATURE_INCOMPAT_FLEX_BG \
|
||||||
|
| EXT2_FEATURE_INCOMPAT_META_BG \
|
||||||
| EXT4_FEATURE_INCOMPAT_64BIT)
|
| EXT4_FEATURE_INCOMPAT_64BIT)
|
||||||
/* List of rationales for the ignored "incompatible" features:
|
/* List of rationales for the ignored "incompatible" features:
|
||||||
* needs_recovery: Not really back-incompatible - was added as such to forbid
|
* 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
|
/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of
|
||||||
the mounted filesystem DATA. */
|
the mounted filesystem DATA. */
|
||||||
inline static grub_err_t
|
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)
|
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,
|
return grub_disk_read (data->disk,
|
||||||
((grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
|
((grub_le_to_cpu32 (data->sblock.first_data_block)
|
||||||
<< LOG2_EXT2_BLOCK_SIZE (data)),
|
+ block)
|
||||||
group << data->log_group_desc_size,
|
<< LOG2_EXT2_BLOCK_SIZE (data)), offset,
|
||||||
sizeof (struct grub_ext2_block_group), blkgrp);
|
sizeof (struct grub_ext2_block_group), blkgrp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,3 +29,4 @@ fi
|
||||||
"@builddir@/grub-fs-tester" ext2
|
"@builddir@/grub-fs-tester" ext2
|
||||||
"@builddir@/grub-fs-tester" ext3
|
"@builddir@/grub-fs-tester" ext3
|
||||||
"@builddir@/grub-fs-tester" ext4
|
"@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"
|
#FSLABEL="g;/_é莭莽😁кит u"
|
||||||
;;
|
;;
|
||||||
# FS LIMITATION: reiserfs, extN and jfs label is at most 16 UTF-8 characters
|
# 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;/éт 莭😁";;
|
FSLABEL="g;/éт 莭😁";;
|
||||||
# FS LIMITATION: No underscore, space, semicolon, slash or international characters in UFS* in label. Limited to 32 UTF-8 characters
|
# 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")
|
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]}"
|
MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext2" -r 0 -b $BLKSIZE -L "$FSLABEL" -q "${LODEVICES[0]}"
|
||||||
MOUNTFS=ext2
|
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*)
|
xext*)
|
||||||
MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.$fs" -b $BLKSIZE -L "$FSLABEL" -q "${LODEVICES[0]}" ;;
|
MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.$fs" -b $BLKSIZE -L "$FSLABEL" -q "${LODEVICES[0]}" ;;
|
||||||
xxfs)
|
xxfs)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue