aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Martinez Canillas <javierm@redhat.com>2021-05-24 19:40:07 +0200
committerDaniel Kiper <daniel.kiper@oracle.com>2021-06-01 17:20:20 +0200
commit777276063e2ec146d5bd0e379717c199967c65ed (patch)
treef73cecfdfafaa58ca0b2bc61f4068ac03478184d
parent8b1e5d1936fffc490510e85c95f93248453586c1 (diff)
downloadgrub-777276063e2ec146d5bd0e379717c199967c65ed.tar.gz
fs/xfs: Add needsrepair incompat feature support
The XFS now has an incompat feature flag to indicate that a filesystem needs to be repaired. The Linux kernel refuses to mount the filesystem that has it set and only the xfs_repair tool is able to clear that flag. The GRUB doesn't have the concept of mounting filesystems and just attempts to read the files. But it does some sanity checking before attempting to read from the filesystem. Among the things which are tested, is if the super block only has set of incompatible features flags that are supported by GRUB. If it contains any flags that are not listed as supported, reading the XFS filesystem fails. Since the GRUB doesn't attempt to detect if the filesystem is inconsistent nor replays the journal, the filesystem access is a best effort. For this reason, ignore if the filesystem needs to be repaired and just print a debug message. That way, if reading or booting fails later, the user is able to figure out that the failures can be related to broken XFS filesystem. Suggested-by: Eric Sandeen <esandeen@redhat.com> Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-rw-r--r--grub-core/fs/xfs.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index a7f8900bc..0f524c3a8 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -85,6 +85,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
+#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */
/*
* Directory entries with ftype are explicitly handled by GRUB code.
@@ -99,7 +100,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
(XFS_SB_FEAT_INCOMPAT_FTYPE | \
XFS_SB_FEAT_INCOMPAT_SPINODES | \
XFS_SB_FEAT_INCOMPAT_META_UUID | \
- XFS_SB_FEAT_INCOMPAT_BIGTIME)
+ XFS_SB_FEAT_INCOMPAT_BIGTIME | \
+ XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
struct grub_xfs_sblock
{
@@ -310,6 +312,16 @@ static int grub_xfs_sb_valid(struct grub_xfs_data *data)
return 0;
}
+static int
+grub_xfs_sb_needs_repair (struct grub_xfs_data *data)
+{
+ return ((data->sblock.version &
+ grub_cpu_to_be16_compile_time (XFS_SB_VERSION_NUMBITS)) ==
+ grub_cpu_to_be16_compile_time (XFS_SB_VERSION_5) &&
+ (data->sblock.sb_features_incompat &
+ grub_cpu_to_be32_compile_time (XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)));
+}
+
/* Filetype information as used in inodes. */
#define FILETYPE_INO_MASK 0170000
#define FILETYPE_INO_REG 0100000
@@ -925,6 +937,9 @@ grub_xfs_mount (grub_disk_t disk)
if (!grub_xfs_sb_valid(data))
goto fail;
+ if (grub_xfs_sb_needs_repair (data))
+ grub_dprintf ("xfs", "XFS filesystem needs repair, boot may fail\n");
+
if (grub_add (grub_xfs_inode_size (data),
sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz))
goto fail;