grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
From: Anthony Iliopoulos via Grub-devel <grub-devel@gnu.org>
To: grub-devel@gnu.org
Cc: Anthony Iliopoulos <ailiop@suse.com>
Subject: [PATCH] fs/xfs: add large extent counters incompat feature support
Date: Thu, 26 Oct 2023 11:53:39 +0200	[thread overview]
Message-ID: <20231026095339.31802-1-ailiop@suse.com> (raw)

XFS introduced 64-bit extent counters for inodes via a series of
upstream commits, and the feature was marked as stable in v6.5 via
commit 61d7e8274cd8 ("xfs: drop EXPERIMENTAL tag for large extent
counts").

Further, xfsprogs release v6.5.0 switched this feature on by default in
mkfs.xfs via commit e5b18d7d1d96 ("mkfs: enable large extent counts by
default").

Filesystems formatted with large extent count support (nrext64=1) are
thus currently not recognizable by grub, since this is an incompat
feature. Add the required support so that those filesystems and inodes
with large extent counters can be read by grub.

Signed-off-by: Anthony Iliopoulos <ailiop@suse.com>
---
 grub-core/fs/xfs.c | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index b91cd32b49ab..ab0d2cdf55a2 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -79,6 +79,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
 /* Inode flags2 flags */
 #define XFS_DIFLAG2_BIGTIME_BIT	3
 #define XFS_DIFLAG2_BIGTIME		(1 << XFS_DIFLAG2_BIGTIME_BIT)
+#define XFS_DIFLAG2_NREXT64_BIT	4
+#define XFS_DIFLAG2_NREXT64		(1 << XFS_DIFLAG2_NREXT64_BIT)
 
 /* incompat feature flags */
 #define XFS_SB_FEAT_INCOMPAT_FTYPE      (1 << 0)        /* filetype in dirent */
@@ -86,6 +88,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
 #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 */
+#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5)           /* large extent counters */
 
 /*
  * Directory entries with ftype are explicitly handled by GRUB code.
@@ -101,7 +104,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
 	 XFS_SB_FEAT_INCOMPAT_SPINODES | \
 	 XFS_SB_FEAT_INCOMPAT_META_UUID | \
 	 XFS_SB_FEAT_INCOMPAT_BIGTIME | \
-	 XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
+	 XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \
+	 XFS_SB_FEAT_INCOMPAT_NREXT64)
 
 struct grub_xfs_sblock
 {
@@ -203,7 +207,8 @@ struct grub_xfs_inode
   grub_uint16_t mode;
   grub_uint8_t version;
   grub_uint8_t format;
-  grub_uint8_t unused2[26];
+  grub_uint8_t unused2[18];
+  grub_uint64_t nextents_big;
   grub_uint64_t atime;
   grub_uint64_t mtime;
   grub_uint64_t ctime;
@@ -539,11 +544,26 @@ get_fsb (const void *keys, int idx)
   return grub_be_to_cpu64 (grub_get_unaligned64 (p));
 }
 
+static int
+grub_xfs_inode_has_large_extent_counts (const struct grub_xfs_inode *inode)
+{
+  return inode->version >= 3 &&
+	 (inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_NREXT64));
+}
+
+static grub_uint64_t
+grub_xfs_get_inode_nextents (struct grub_xfs_inode *inode)
+{
+  return (grub_xfs_inode_has_large_extent_counts (inode)) ?
+	  grub_be_to_cpu64 (inode->nextents_big) :
+	  grub_be_to_cpu32 (inode->nextents);
+}
+
 static grub_disk_addr_t
 grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
 {
   struct grub_xfs_btree_node *leaf = 0;
-  int ex, nrec;
+  grub_uint64_t ex, nrec;
   struct grub_xfs_extent *exts;
   grub_uint64_t ret = 0;
 
@@ -568,7 +588,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
 				/ (2 * sizeof (grub_uint64_t));
       do
         {
-          int i;
+          grub_uint64_t i;
 
           for (i = 0; i < nrec; i++)
             {
@@ -615,7 +635,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
       grub_addr_t exts_end = 0;
       grub_addr_t data_end = 0;
 
-      nrec = grub_be_to_cpu32 (node->inode.nextents);
+      nrec = grub_xfs_get_inode_nextents (&node->inode);
       exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode);
 
       if (grub_mul (sizeof (struct grub_xfs_extent), nrec, &exts_end) ||
-- 
2.41.0


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

             reply	other threads:[~2023-10-26 12:48 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-26  9:53 Anthony Iliopoulos via Grub-devel [this message]
2023-10-26 15:55 ` [PATCH] fs/xfs: add large extent counters incompat feature support Andrey Albershteyn
2023-10-30 18:48   ` Daniel Kiper
2023-11-01  8:09     ` Marta Lewandowska
2023-11-06 18:17     ` Daniel Kiper
2023-11-06 21:53       ` Sebastian Andrzej Siewior
2023-11-07 18:45         ` Daniel Kiper
2023-11-07 19:22           ` Sebastian Andrzej Siewior
2023-11-07 19:31           ` Sebastian Andrzej Siewior
2023-11-01  8:13 ` Marta Lewandowska
2023-11-05  7:33 ` Philip Hands
2023-11-07 18:47   ` Daniel Kiper
2023-11-06  8:07 ` Philip Hands

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231026095339.31802-1-ailiop@suse.com \
    --to=grub-devel@gnu.org \
    --cc=ailiop@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).