The XFS now has an incompat feature flag to indicate that the filesystem
needs to be repaired. The Linux kernel refuses to mount a 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 a filesystem.

Among the things which are tested, is if the super block only has set the
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, also ignore if a filesystem needs to be repaired and just print a
debug message in this case.

That way, if later reading or booting fails, the user can figure out that
the failures may be related to the XFS filesystem needing to be repaired.

Suggested-by: Eric Sandeen <esand...@redhat.com>
Signed-off-by: Javier Martinez Canillas <javi...@redhat.com>
---

Changes in v3:
- Improved commit message in patch #4 (dkiper).
- Make the debug message more clear (dkiper).

Changes in v2:
- Improve commit message of patch #4 (dkiper).
- Fix typo in debug message of patch #4 (dkiper).

 grub-core/fs/xfs.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 2e6a24d034a..6452961ecbb 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;
-- 
2.31.1


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to