Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package grub2 for openSUSE:Factory checked 
in at 2026-08-31 15:56:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/grub2 (Old)
 and      /work/SRC/openSUSE:Factory/.grub2.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "grub2"

Mon Aug 31 15:56:16 2026 rev:398 rq:1374774 version:2.14

Changes:
--------
--- /work/SRC/openSUSE:Factory/grub2/grub2.changes      2026-08-06 
16:18:32.932796830 +0200
+++ /work/SRC/openSUSE:Factory/.grub2.new.1265/grub2.changes    2026-08-31 
15:56:32.017626951 +0200
@@ -1,0 +2,15 @@
+Thu Aug 27 08:24:15 UTC 2026 - Michael Chang <[email protected]>
+
+- Backport merged upstream patch
+  * 0001-fs-btrfs-mark-Btrfs-on-disk-structs-as-GRUB_PACKED.patch
+  * 0002-fs-btrfs-add-btrfs-info-command.patch
+  * 0003-fs-btrfs-add-btrfs-list-subvols-command.patch
+  * 0004-fs-btrfs-add-btrfs-get-default-subvol-command.patch
+- Patch rebased
+  * grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch
+  * grub2-btrfs-06-subvol-mount.patch
+  * grub2-btrfs-10-config-directory.patch
+- Drop local patch
+  * grub2-btrfs-09-get-default-subvolume.patch
+
+-------------------------------------------------------------------

Old:
----
  grub2-btrfs-09-get-default-subvolume.patch

New:
----
  0001-fs-btrfs-mark-Btrfs-on-disk-structs-as-GRUB_PACKED.patch
  0002-fs-btrfs-add-btrfs-info-command.patch
  0003-fs-btrfs-add-btrfs-list-subvols-command.patch
  0004-fs-btrfs-add-btrfs-get-default-subvol-command.patch

----------(Old B)----------
  Old:- Drop local patch
  * grub2-btrfs-09-get-default-subvolume.patch
----------(Old E)----------

----------(New B)----------
  New:- Backport merged upstream patch
  * 0001-fs-btrfs-mark-Btrfs-on-disk-structs-as-GRUB_PACKED.patch
  * 0002-fs-btrfs-add-btrfs-info-command.patch
  New:  * 0001-fs-btrfs-mark-Btrfs-on-disk-structs-as-GRUB_PACKED.patch
  * 0002-fs-btrfs-add-btrfs-info-command.patch
  * 0003-fs-btrfs-add-btrfs-list-subvols-command.patch
  New:  * 0002-fs-btrfs-add-btrfs-info-command.patch
  * 0003-fs-btrfs-add-btrfs-list-subvols-command.patch
  * 0004-fs-btrfs-add-btrfs-get-default-subvol-command.patch
  New:  * 0003-fs-btrfs-add-btrfs-list-subvols-command.patch
  * 0004-fs-btrfs-add-btrfs-get-default-subvol-command.patch
- Patch rebased
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ grub2.spec ++++++
--- /var/tmp/diff_new_pack.Pb5Vh4/_old  2026-08-31 15:56:35.893762184 +0200
+++ /var/tmp/diff_new_pack.Pb5Vh4/_new  2026-08-31 15:56:35.896762289 +0200
@@ -198,6 +198,10 @@
 Source18:       grub2-check-default.sh
 Source19:       grub2-instdev-fixup.pl
 Source1000:     PATCH_POLICY
+Patch:          0001-fs-btrfs-mark-Btrfs-on-disk-structs-as-GRUB_PACKED.patch
+Patch:          0002-fs-btrfs-add-btrfs-info-command.patch
+Patch:          0003-fs-btrfs-add-btrfs-list-subvols-command.patch
+Patch:          0004-fs-btrfs-add-btrfs-get-default-subvol-command.patch
 Patch:          0001-lvm-allocate-metadata-buffer-from-raw-contents.patch
 Patch:          0001-net-http-Check-result-of-grub_netbuff_put-in-http_re.patch
 Patch:          0002-efinet-Add-structures-for-PXE-messages.patch
@@ -269,7 +273,6 @@
 Patch:          grub2-btrfs-06-subvol-mount.patch
 Patch:          grub2-btrfs-07-subvol-fallback.patch
 Patch:          grub2-btrfs-08-workaround-snapshot-menu-default-entry.patch
-Patch:          grub2-btrfs-09-get-default-subvolume.patch
 Patch:          grub2-btrfs-10-config-directory.patch
 Patch:          grub2-efi-xen-chainload.patch
 Patch:          grub2-efi-xen-cmdline.patch

++++++ 0001-fs-btrfs-mark-Btrfs-on-disk-structs-as-GRUB_PACKED.patch ++++++
>From 28e4c0b4f681e8f49f2d945888fe84ac078cb88e Mon Sep 17 00:00:00 2001
From: Michael Chang <[email protected]>
Date: Tue, 16 Jun 2026 12:00:02 +0800
Subject: [PATCH 1/4] fs/btrfs: mark Btrfs on-disk structs as GRUB_PACKED

This also aligns them with other Btrfs on-disk structs in this header
that already use GRUB_PACKED.

Signed-off-by: Michael Chang <[email protected]>
Reviewed-by: Neal Gompa <[email protected]>
Reviewed-by: Leo Sandoval <[email protected]>
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/160>
---
 include/grub/btrfs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/grub/btrfs.h b/include/grub/btrfs.h
index 9d93fb6c1..9aad88754 100644
--- a/include/grub/btrfs.h
+++ b/include/grub/btrfs.h
@@ -43,7 +43,7 @@ struct grub_btrfs_root_item
   grub_uint8_t dummy[0xb0];
   grub_uint64_t tree;
   grub_uint64_t inode;
-};
+} GRUB_PACKED;
 
 struct grub_btrfs_key
 {
@@ -59,13 +59,13 @@ struct grub_btrfs_root_backref
   grub_uint64_t seqnr;
   grub_uint16_t n;
   char name[0];
-};
+} GRUB_PACKED;
 
 struct grub_btrfs_inode_ref
 {
   grub_uint64_t idxid;
   grub_uint16_t n;
   char name[0];
-};
+} GRUB_PACKED;
 
 #endif
-- 
2.55.0


++++++ 0002-fs-btrfs-add-btrfs-info-command.patch ++++++
>From 1cc790ce376fc77a736e3430b32bf330bff13fb3 Mon Sep 17 00:00:00 2001
From: Michael Chang <[email protected]>
Date: Mon, 8 Jun 2026 18:51:40 +0800
Subject: [PATCH 2/4] fs/btrfs: add btrfs-info command

Add new "btrfs-info" GRUB command to print basic filesystem metadata for
a given device, including label, UUID, total device count, and bytes
used.

Signed-off-by: Michael Chang <[email protected]>
Reviewed-by: Neal Gompa <[email protected]>
Reviewed-by: Leo Sandoval <[email protected]>
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/160>
---
 grub-core/fs/btrfs.c | 103 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 92 insertions(+), 11 deletions(-)

diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
index 61dd1676a..5948530ff 100644
--- a/grub-core/fs/btrfs.c
+++ b/grub-core/fs/btrfs.c
@@ -41,6 +41,7 @@
 #include <grub/crypto.h>
 #include <grub/diskfilter.h>
 #include <grub/safemath.h>
+#include <grub/command.h>
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -79,9 +80,11 @@ struct grub_btrfs_superblock
   grub_uint64_t generation;
   grub_uint64_t root_tree;
   grub_uint64_t chunk_tree;
-  grub_uint8_t dummy2[0x20];
+  grub_uint8_t dummy2[0x18];
+  grub_uint64_t bytes_used;
   grub_uint64_t root_dir_objectid;
-  grub_uint8_t dummy3[0x41];
+  grub_uint64_t num_devices;
+  grub_uint8_t dummy3[0x39];
   struct grub_btrfs_device this_device;
   char label[0x100];
   grub_uint8_t dummy4[0x100];
@@ -2282,6 +2285,20 @@ grub_btrfs_read (grub_file_t file, char *buf, 
grub_size_t len)
                                 data->tree, file->offset, buf, len);
 }
 
+static char *
+btrfs_unparse_uuid(struct grub_btrfs_data *data)
+{
+  return grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
+                        grub_be_to_cpu16 (data->sblock.uuid[0]),
+                        grub_be_to_cpu16 (data->sblock.uuid[1]),
+                        grub_be_to_cpu16 (data->sblock.uuid[2]),
+                        grub_be_to_cpu16 (data->sblock.uuid[3]),
+                        grub_be_to_cpu16 (data->sblock.uuid[4]),
+                        grub_be_to_cpu16 (data->sblock.uuid[5]),
+                        grub_be_to_cpu16 (data->sblock.uuid[6]),
+                        grub_be_to_cpu16 (data->sblock.uuid[7]));
+}
+
 static grub_err_t
 grub_btrfs_uuid (grub_device_t device, char **uuid)
 {
@@ -2293,15 +2310,7 @@ grub_btrfs_uuid (grub_device_t device, char **uuid)
   if (!data)
     return grub_errno;
 
-  *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
-                         grub_be_to_cpu16 (data->sblock.uuid[0]),
-                         grub_be_to_cpu16 (data->sblock.uuid[1]),
-                         grub_be_to_cpu16 (data->sblock.uuid[2]),
-                         grub_be_to_cpu16 (data->sblock.uuid[3]),
-                         grub_be_to_cpu16 (data->sblock.uuid[4]),
-                         grub_be_to_cpu16 (data->sblock.uuid[5]),
-                         grub_be_to_cpu16 (data->sblock.uuid[6]),
-                         grub_be_to_cpu16 (data->sblock.uuid[7]));
+  *uuid = btrfs_unparse_uuid (data);
 
   grub_btrfs_unmount (data);
 
@@ -2431,6 +2440,71 @@ grub_btrfs_embed (grub_device_t device __attribute__ 
((unused)),
 }
 #endif
 
+static grub_err_t
+grub_cmd_btrfs_info (grub_command_t cmd __attribute__ ((unused)), int argc,
+                    char **argv)
+{
+  grub_device_t dev;
+  char *devname;
+  struct grub_btrfs_data *data;
+  char *uuid;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+
+  devname = grub_file_get_device_name(argv[0]);
+
+  if (!devname)
+    return grub_errno;
+
+  dev = grub_device_open (devname);
+  grub_free (devname);
+  if (!dev)
+    return grub_errno;
+
+  data = grub_btrfs_mount (dev);
+  if (!data)
+    {
+      grub_device_close(dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to open fs");
+    }
+
+  if (*data->sblock.label != '\0')
+    {
+      char *label = grub_strndup (data->sblock.label, sizeof 
(data->sblock.label));
+      if (!label)
+       {
+         grub_btrfs_unmount (data);
+         grub_device_close (dev);
+         return grub_errno;
+       }
+      grub_printf("Label: '%s' ", label);
+      grub_free (label);
+    }
+  else
+    grub_printf("Label: none ");
+
+  uuid = btrfs_unparse_uuid (data);
+  if (!uuid)
+    {
+      grub_btrfs_unmount (data);
+      grub_device_close (dev);
+      return grub_errno;
+    }
+
+  grub_printf (" uuid: %s\n\tTotal devices %" PRIuGRUB_UINT64_T
+              " FS bytes used %" PRIuGRUB_UINT64_T "\n",
+              uuid,
+              grub_le_to_cpu64 (data->sblock.num_devices),
+              grub_le_to_cpu64 (data->sblock.bytes_used));
+
+  grub_free (uuid);
+  grub_btrfs_unmount (data);
+  grub_device_close (dev);
+
+  return GRUB_ERR_NONE;
+}
+
 static struct grub_fs grub_btrfs_fs = {
   .name = "btrfs",
   .fs_dir = grub_btrfs_dir,
@@ -2446,13 +2520,20 @@ static struct grub_fs grub_btrfs_fs = {
 #endif
 };
 
+static grub_command_t cmd_info;
+
 GRUB_MOD_INIT (btrfs)
 {
   grub_btrfs_fs.mod = mod;
   grub_fs_register (&grub_btrfs_fs);
+  cmd_info = grub_register_command ("btrfs-info",
+                                   grub_cmd_btrfs_info,
+                                   "DEVICE",
+                                   "Print BtrFS info about DEVICE.");
 }
 
 GRUB_MOD_FINI (btrfs)
 {
   grub_fs_unregister (&grub_btrfs_fs);
+  grub_unregister_command (cmd_info);
 }
-- 
2.55.0


++++++ 0003-fs-btrfs-add-btrfs-list-subvols-command.patch ++++++
>From 38136c6a8aa0c8d31a4dbf6f21efc432c14b3506 Mon Sep 17 00:00:00 2001
From: Michael Chang <[email protected]>
Date: Tue, 16 Jun 2026 11:33:23 +0800
Subject: [PATCH 3/4] fs/btrfs: add btrfs-list-subvols command

Add a new "btrfs-list-subvols" GRUB command to enumerate subvolumes on a
Btrfs device. Support output filtering and formatting with options for
path-only, id-only, read-only, and storing output in an environment
variable.

Signed-off-by: Michael Chang <[email protected]>
Reviewed-by: Neal Gompa <[email protected]>
Reviewed-by: Leo Sandoval <[email protected]>
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/160>
---
 grub-core/fs/btrfs.c | 412 +++++++++++++++++++++++++++++++++++++++++++
 include/grub/btrfs.h |   6 +-
 2 files changed, 417 insertions(+), 1 deletion(-)

diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
index 5948530ff..5714642af 100644
--- a/grub-core/fs/btrfs.c
+++ b/grub-core/fs/btrfs.c
@@ -42,6 +42,8 @@
 #include <grub/diskfilter.h>
 #include <grub/safemath.h>
 #include <grub/command.h>
+#include <grub/env.h>
+#include <grub/extcmd.h>
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -194,6 +196,14 @@ struct grub_btrfs_leaf_descriptor
   } *data;
 };
 
+struct grub_btrfs_root_ref
+{
+  grub_uint64_t dirid;
+  grub_uint64_t sequence;
+  grub_uint16_t name_len;
+  const char name[0];
+} GRUB_PACKED;
+
 struct grub_btrfs_time
 {
   grub_int64_t sec;
@@ -239,6 +249,10 @@ struct grub_btrfs_extent_data
 
 #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100
 
+#define GRUB_BTRFS_FS_TREE_OBJECTID 5ULL
+#define GRUB_BTRFS_ROOT_REF_KEY     156
+#define GRUB_BTRFS_ROOT_ITEM_KEY     132
+
 static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2,
   256 * 1048576 * 2, 1048576ULL * 1048576ULL * 2
 };
@@ -248,6 +262,13 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
                         grub_disk_addr_t addr, void *buf, grub_size_t size,
                         int recursion_depth);
 
+static grub_err_t
+grub_btrfs_get_parent_subvol_path (struct grub_btrfs_data *data,
+               grub_uint64_t child_id,
+               const char *child_path,
+               grub_uint64_t *parent_id,
+               char **path_out);
+
 static grub_err_t
 read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb)
 {
@@ -1790,6 +1811,103 @@ get_root (struct grub_btrfs_data *data, struct 
grub_btrfs_key *key,
   return GRUB_ERR_NONE;
 }
 
+static grub_err_t
+find_pathname(struct grub_btrfs_data *data, grub_uint64_t objectid,
+              grub_uint64_t fs_root, const char *name, char **pathname)
+{
+  grub_err_t err;
+  struct grub_btrfs_key key = {
+    .object_id = grub_cpu_to_le64 (objectid),
+    .type = GRUB_BTRFS_ITEM_TYPE_INODE_REF,
+    .offset = 0ULL,
+  };
+  struct grub_btrfs_key key_out;
+  struct grub_btrfs_leaf_descriptor desc;
+  char *p = grub_strdup (name);
+  grub_disk_addr_t elemaddr;
+  grub_size_t elemsize;
+  grub_size_t alloc = grub_strlen(name) + 1;
+
+  err = lower_bound(data, &key, &key_out, fs_root,
+                    &elemaddr, &elemsize, &desc, 0);
+  if (err)
+    {
+      free_iterator(&desc);
+      return grub_error(err, "lower_bound caught %d\n", err);
+    }
+
+  if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF)
+    next(data, &desc, &elemaddr, &elemsize, &key_out);
+
+  free_iterator(&desc);
+  if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF)
+    {
+      return grub_error(GRUB_ERR_FILE_NOT_FOUND,
+                        "Can't find inode ref for {%"PRIuGRUB_UINT64_T
+                        ", %u, %"PRIuGRUB_UINT64_T"} %"PRIuGRUB_UINT64_T
+                        "/%"PRIuGRUB_SIZE"\n",
+                        key_out.object_id, key_out.type,
+                        key_out.offset, elemaddr, elemsize);
+    }
+
+  while (key_out.type == GRUB_BTRFS_ITEM_TYPE_INODE_REF &&
+         key_out.object_id != key_out.offset)
+    {
+      struct grub_btrfs_inode_ref *inode_ref;
+      char *new;
+      grub_size_t sz;
+
+      if (grub_add (elemsize, 1, &sz))
+       return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+
+      inode_ref = grub_malloc(sz);
+      if (!inode_ref)
+       return grub_error(GRUB_ERR_OUT_OF_MEMORY,
+                         "couldn't allocate memory for inode_ref 
(%"PRIuGRUB_SIZE")\n", elemsize);
+
+      err = grub_btrfs_read_logical(data, elemaddr, inode_ref, elemsize, 0);
+      if (err)
+       return grub_error(err, "read_logical caught %d\n", err);
+
+      if (grub_add (grub_le_to_cpu16 (inode_ref->n), 2, &sz) ||
+         grub_add (alloc, sz, &alloc))
+       return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+
+      new = grub_malloc(alloc);
+      if (!new)
+       return grub_error(GRUB_ERR_OUT_OF_MEMORY,
+                         "couldn't allocate memory for name 
(%"PRIuGRUB_SIZE")\n", alloc);
+
+      grub_memcpy(new, inode_ref->name, grub_le_to_cpu16 (inode_ref->n));
+      if (p)
+       {
+         new[grub_le_to_cpu16 (inode_ref->n)] = '/';
+         grub_strcpy (new + grub_le_to_cpu16 (inode_ref->n) + 1, p);
+         grub_free(p);
+       }
+      else
+       new[grub_le_to_cpu16 (inode_ref->n)] = 0;
+      grub_free(inode_ref);
+
+      p = new;
+      key.object_id = key_out.offset;
+      err = lower_bound(data, &key, &key_out, fs_root, &elemaddr,
+                       &elemsize, &desc, 0);
+      if (err)
+       {
+         free_iterator(&desc);
+         return grub_error(err, "lower_bound caught %d\n", err);
+       }
+
+      if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF)
+       next(data, &desc, &elemaddr, &elemsize, &key_out);
+      free_iterator(&desc);
+    }
+
+  *pathname = p;
+  return 0;
+}
+
 static grub_err_t
 find_path (struct grub_btrfs_data *data,
           const char *path, struct grub_btrfs_key *key,
@@ -2505,6 +2623,293 @@ grub_cmd_btrfs_info (grub_command_t cmd __attribute__ 
((unused)), int argc,
   return GRUB_ERR_NONE;
 }
 
+static grub_err_t
+get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree,
+            grub_uint64_t objectid, grub_uint64_t offset,
+            grub_uint64_t *fs_root, grub_uint64_t *flags)
+{
+  grub_err_t err;
+  struct grub_btrfs_key key_in = {
+    .object_id = grub_cpu_to_le64 (objectid),
+    .type = GRUB_BTRFS_ROOT_ITEM_KEY,
+    .offset = grub_cpu_to_le64 (offset),
+  }, key_out;
+  grub_disk_addr_t elemaddr;
+  grub_size_t elemsize;
+  struct grub_btrfs_root_item ri;
+
+  err = lower_bound(data, &key_in, &key_out, tree,
+                    &elemaddr, &elemsize, NULL, 0);
+  if (err)
+    return err;
+
+  if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM || elemaddr == 0)
+    {
+      return grub_error(GRUB_ERR_FILE_NOT_FOUND,
+                    N_("can't find fs root for subvol %"PRIuGRUB_UINT64_T"\n"),
+                    key_in.object_id);
+    }
+
+  err = grub_btrfs_read_logical (data, elemaddr, &ri, sizeof (ri), 0);
+  if (err)
+    return err;
+
+  *fs_root = ri.tree;
+
+  if (flags)
+    *flags = grub_le_to_cpu64 (ri.flags);
+
+  return GRUB_ERR_NONE;
+}
+
+static const struct grub_arg_option opt_list_subvols[] = {
+  {"output", 'o', 0, N_("Output to a variable instead of the console."),
+   N_("VARNAME"), ARG_TYPE_STRING},
+  {"path-only", 'p', 0, N_("Show only the path of the subvolume."), 0, 0},
+  {"id-only", 'n', 0, N_("Show only the id of the subvolume."), 0, 0},
+  {"read-only", 'r', 0, N_("Show only read-only subvolume."), 0, 0},
+  {0, 0, 0, 0, 0, 0}
+};
+
+static grub_err_t
+grub_cmd_btrfs_list_subvols (struct grub_extcmd_context *ctxt,
+                            int argc, char **argv)
+{
+  struct grub_btrfs_data *data = NULL;
+  grub_device_t dev = NULL;
+  char *devname;
+  grub_uint64_t tree;
+  struct grub_btrfs_key key_in = {
+    .object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_FS_TREE_OBJECTID),
+    .type = GRUB_BTRFS_ROOT_REF_KEY,
+    .offset = 0ULL,
+  }, key_out;
+  struct grub_btrfs_leaf_descriptor desc = {0};
+  grub_disk_addr_t elemaddr;
+  grub_uint64_t fs_root = 0;
+  grub_size_t elemsize;
+  int r = 0;
+  grub_err_t err;
+  int print = 1;
+  int path_only = ctxt->state[1].set;
+  int num_only = ctxt->state[2].set;
+  int read_only = ctxt->state[3].set;
+  char *varname = NULL;
+  char *output = NULL;
+
+  if (ctxt->state[0].set) {
+    varname = ctxt->state[0].arg;
+    print = 0;
+  }
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+
+  devname = grub_file_get_device_name(argv[0]);
+  if (!devname)
+    return grub_errno;
+
+  dev = grub_device_open (devname);
+  grub_free (devname);
+  if (!dev)
+    return grub_errno;
+
+  data = grub_btrfs_mount(dev);
+  if (!data)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "could not open device");
+    }
+
+  tree = data->sblock.root_tree;
+  err = get_fs_root(data, tree, GRUB_BTRFS_FS_TREE_OBJECTID,
+                    0ULL, &fs_root, NULL);
+  if (err)
+    goto out;
+
+  err = lower_bound(data, &key_in, &key_out, tree,
+                    &elemaddr, &elemsize, &desc, 0);
+
+  if (err)
+    goto out;
+
+  do
+    {
+      char *p = NULL;
+      grub_uint64_t id = grub_le_to_cpu64 (key_out.offset);
+      grub_uint64_t flags;
+
+      if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_REF || elemaddr == 0)
+        continue;
+
+      err = get_fs_root (data, tree, id, (grub_uint64_t) -1, &fs_root, &flags);
+      if (err != GRUB_ERR_NONE)
+        {
+          grub_print_error ();
+          continue;
+        }
+
+      if (read_only && !(flags & GRUB_BTRFS_ROOT_SUBVOL_RDONLY))
+        continue;
+
+      if (id == GRUB_BTRFS_ROOT_VOL_OBJECTID)
+        p = grub_strdup ("");
+      else
+        while (id != GRUB_BTRFS_ROOT_VOL_OBJECTID)
+          {
+            grub_uint64_t parent_id;
+            char *path_out;
+
+            err = grub_btrfs_get_parent_subvol_path (data, id, p, &parent_id, 
&path_out);
+            grub_free (p);
+            if (err)
+              {
+                grub_print_error ();
+                goto out;
+              }
+            p = path_out;
+            id = parent_id;
+          }
+
+      if (print)
+        {
+          if (num_only)
+            grub_printf("ID %"PRIuGRUB_UINT64_T"\n", grub_le_to_cpu64 
(key_out.offset));
+          else if (path_only)
+            grub_printf("%s\n", p);
+          else
+            grub_printf("ID %"PRIuGRUB_UINT64_T" path %s\n", grub_le_to_cpu64 
(key_out.offset), p);
+        }
+      else
+       {
+          char *old = output;
+          if (num_only)
+            output = grub_xasprintf("%s%"PRIuGRUB_UINT64_T"\n",
+                                    old ?: "", grub_le_to_cpu64 
(key_out.offset));
+          else if (path_only)
+            output = grub_xasprintf("%s%s\n", old ?: "", p);
+          else
+            output = grub_xasprintf("%sID %"PRIuGRUB_UINT64_T" path %s\n",
+                                    old ?: "", grub_le_to_cpu64 
(key_out.offset), p);
+          if (old)
+            grub_free(old);
+        }
+
+      grub_free (p);
+
+    } while ((r = next(data, &desc, &elemaddr, &elemsize, &key_out)) > 0);
+
+  if (output)
+    grub_env_set(varname, output);
+
+out:
+  grub_free (output);
+  free_iterator(&desc);
+
+  if (data)
+    grub_btrfs_unmount(data);
+
+  if (dev)
+    grub_device_close (dev);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_btrfs_get_parent_subvol_path (struct grub_btrfs_data *data,
+               grub_uint64_t child_id,
+               const char *child_path,
+               grub_uint64_t *parent_id,
+               char **path_out)
+{
+  grub_uint64_t fs_root = 0;
+  struct grub_btrfs_key key_in = {
+    .object_id = grub_cpu_to_le64 (child_id),
+    .type = GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF,
+    .offset = 0ULL,
+  }, key_out;
+  struct grub_btrfs_root_ref *ref;
+  char *buf;
+  struct grub_btrfs_leaf_descriptor desc;
+  grub_size_t elemsize;
+  grub_disk_addr_t elemaddr;
+  grub_err_t err;
+  char *parent_path = NULL;
+  grub_size_t sz;
+
+  *parent_id = 0;
+  *path_out = 0;
+
+  err = lower_bound(data, &key_in, &key_out, data->sblock.root_tree,
+                    &elemaddr, &elemsize, &desc, 0);
+  if (err)
+    return err;
+
+  if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF || elemaddr == 0)
+    next(data, &desc, &elemaddr, &elemsize, &key_out);
+
+  if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF)
+    {
+      free_iterator(&desc);
+      return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("can't find root 
backrefs"));
+    }
+
+  if (grub_add (elemsize, 1, &sz))
+    {
+      free_iterator(&desc);
+      return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+    }
+
+  buf = grub_malloc(sz);
+  if (!buf)
+    {
+      free_iterator(&desc);
+      return grub_errno;
+    }
+
+  err = grub_btrfs_read_logical(data, elemaddr, buf, elemsize, 0);
+  if (err)
+    {
+      grub_free(buf);
+      free_iterator(&desc);
+      return err;
+    }
+
+  buf[elemsize] = 0;
+  ref = (struct grub_btrfs_root_ref *)buf;
+
+  err = get_fs_root(data, data->sblock.root_tree, grub_le_to_cpu64 
(key_out.offset),
+                    (grub_uint64_t) -1, &fs_root, NULL);
+  if (err)
+    {
+      grub_free(buf);
+      free_iterator(&desc);
+      return err;
+    }
+
+  err = find_pathname(data, grub_le_to_cpu64 (ref->dirid), fs_root, ref->name, 
&parent_path);
+  if (err)
+    {
+      grub_free(buf);
+      free_iterator(&desc);
+      return err;
+    }
+
+  if (child_path)
+    {
+      *path_out = grub_xasprintf ("%s/%s", parent_path, child_path);
+      grub_free (parent_path);
+    }
+  else
+    *path_out = parent_path;
+
+  *parent_id = grub_le_to_cpu64 (key_out.offset);
+
+  grub_free(buf);
+  free_iterator(&desc);
+  return GRUB_ERR_NONE;
+}
+
 static struct grub_fs grub_btrfs_fs = {
   .name = "btrfs",
   .fs_dir = grub_btrfs_dir,
@@ -2521,6 +2926,7 @@ static struct grub_fs grub_btrfs_fs = {
 };
 
 static grub_command_t cmd_info;
+static grub_extcmd_t cmd_list_subvols;
 
 GRUB_MOD_INIT (btrfs)
 {
@@ -2530,10 +2936,16 @@ GRUB_MOD_INIT (btrfs)
                                    grub_cmd_btrfs_info,
                                    "DEVICE",
                                    "Print BtrFS info about DEVICE.");
+  cmd_list_subvols = grub_register_extcmd("btrfs-list-subvols",
+                                        grub_cmd_btrfs_list_subvols, 0,
+                                        "[-p|-n] [-r] [-o var] DEVICE",
+                                        "Print list of BtrFS subvolumes on "
+                                        "DEVICE.", opt_list_subvols);
 }
 
 GRUB_MOD_FINI (btrfs)
 {
   grub_fs_unregister (&grub_btrfs_fs);
   grub_unregister_command (cmd_info);
+  grub_unregister_extcmd (cmd_list_subvols);
 }
diff --git a/include/grub/btrfs.h b/include/grub/btrfs.h
index 9aad88754..19de49311 100644
--- a/include/grub/btrfs.h
+++ b/include/grub/btrfs.h
@@ -29,6 +29,7 @@ enum
     GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM = 0x84,
     GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF = 0x90,
     GRUB_BTRFS_ITEM_TYPE_DEVICE = 0xd8,
+    GRUB_BTRFS_ITEM_TYPE_ROOT_REF = 0x9c,
     GRUB_BTRFS_ITEM_TYPE_CHUNK = 0xe4
   };
 
@@ -38,11 +39,14 @@ enum
     GRUB_BTRFS_TREE_ROOT_OBJECTID = 0x100,
   };
 
+#define GRUB_BTRFS_ROOT_SUBVOL_RDONLY  (1ULL << 0)
+
 struct grub_btrfs_root_item
 {
   grub_uint8_t dummy[0xb0];
   grub_uint64_t tree;
-  grub_uint64_t inode;
+  grub_uint8_t dummy2[0x18];
+  grub_uint64_t flags;
 } GRUB_PACKED;
 
 struct grub_btrfs_key
-- 
2.55.0


++++++ 0004-fs-btrfs-add-btrfs-get-default-subvol-command.patch ++++++
>From aead2255d307ee00756c8cc19e9aecd166ca282e Mon Sep 17 00:00:00 2001
From: Michael Chang <[email protected]>
Date: Tue, 16 Jun 2026 15:16:12 +0800
Subject: [PATCH 4/4] fs/btrfs: add btrfs-get-default-subvol command

Add a new Btrfs command, "btrfs-get-default-subvol", to print the
filesystem default subvolume. The command supports printing only the
path with `-p`, printing only the subvolume ID with `-n`, and storing
output in an environment variable with `-o VAR`.

Signed-off-by: Michael Chang <[email protected]>
Reviewed-by: Neal Gompa <[email protected]>
Reviewed-by: Leo Sandoval <[email protected]>
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/160>
---
 grub-core/fs/btrfs.c | 199 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 199 insertions(+)

diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
index 5714642af..1cd842ec0 100644
--- a/grub-core/fs/btrfs.c
+++ b/grub-core/fs/btrfs.c
@@ -2671,6 +2671,14 @@ static const struct grub_arg_option opt_list_subvols[] = 
{
   {0, 0, 0, 0, 0, 0}
 };
 
+static const struct grub_arg_option opt_default_subvol[] = {
+  {"output", 'o', 0, N_("Output to a variable instead of the console."),
+   N_("VARNAME"), ARG_TYPE_STRING},
+  {"path-only", 'p', 0, N_("Show only the path of the subvolume."), 0, 0},
+  {"id-only", 'n', 0, N_("Show only the id of the subvolume."), 0, 0},
+  {0, 0, 0, 0, 0, 0}
+};
+
 static grub_err_t
 grub_cmd_btrfs_list_subvols (struct grub_extcmd_context *ctxt,
                             int argc, char **argv)
@@ -2910,6 +2918,190 @@ grub_btrfs_get_parent_subvol_path (struct 
grub_btrfs_data *data,
   return GRUB_ERR_NONE;
 }
 
+static grub_err_t
+grub_btrfs_get_default_subvolume_id (struct grub_btrfs_data *data, 
grub_uint64_t *id)
+{
+  grub_err_t err;
+  grub_disk_addr_t elemaddr;
+  grub_size_t elemsize;
+  struct grub_btrfs_key key, key_out;
+  struct grub_btrfs_dir_item *direl = NULL;
+  const char *ctoken = "default";
+  grub_size_t ctokenlen = sizeof ("default") - 1;
+  grub_size_t sz;
+
+  *id = 0;
+  key.object_id = data->sblock.root_dir_objectid;
+  key.type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM;
+  key.offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen));
+  err = lower_bound (data, &key, &key_out, data->sblock.root_tree, &elemaddr, 
&elemsize,
+                        NULL, 0);
+  if (err)
+    return err;
+
+  if (key_cmp (&key, &key_out) != 0)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found"));
+
+  struct grub_btrfs_dir_item *cdirel;
+
+  if (grub_add (elemsize, 1, &sz))
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+
+  direl = grub_malloc (sz);
+  if (!direl)
+    return grub_errno;
+
+  err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize, 0);
+  if (err)
+    {
+      grub_free (direl);
+      return err;
+    }
+  for (cdirel = direl;
+       (grub_uint8_t *) cdirel - (grub_uint8_t *) direl
+       < (grub_ssize_t) elemsize;
+       cdirel = (void *) ((grub_uint8_t *) (direl + 1)
+       + grub_le_to_cpu16 (cdirel->n)
+       + grub_le_to_cpu16 (cdirel->m)))
+    {
+      if (ctokenlen == grub_le_to_cpu16 (cdirel->n)
+        && grub_memcmp (cdirel->name, ctoken, ctokenlen) == 0)
+      break;
+    }
+  if ((grub_uint8_t *) cdirel - (grub_uint8_t *) direl
+      >= (grub_ssize_t) elemsize)
+    {
+      grub_free (direl);
+      err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found"));
+      return err;
+    }
+
+  if (cdirel->key.type != GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM)
+    {
+      grub_free (direl);
+      err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found"));
+      return err;
+    }
+
+  *id = grub_le_to_cpu64 (cdirel->key.object_id);
+  grub_free (direl);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_btrfs_get_default_subvol (const char *name, grub_uint64_t *ret_subvolid, 
char **ret_subvol)
+{
+  char *devname;
+  grub_device_t dev;
+  struct grub_btrfs_data *data;
+  grub_err_t err;
+  grub_uint64_t id;
+  char *subvol = NULL;
+  grub_uint64_t subvolid = 0;
+
+  devname = grub_file_get_device_name(name);
+  if (!devname)
+    return grub_errno;
+  dev = grub_device_open (devname);
+  grub_free (devname);
+  if (!dev)
+    return grub_errno;
+
+  data = grub_btrfs_mount(dev);
+  if (!data)
+    {
+      grub_device_close (dev);
+      grub_dprintf ("btrfs", "failed to open fs\n");
+      return grub_errno;
+    }
+
+  err = grub_btrfs_get_default_subvolume_id (data, &subvolid);
+  if (err)
+    {
+      grub_btrfs_unmount (data);
+      grub_device_close (dev);
+      return err;
+    }
+
+  id = subvolid;
+
+  if (id == GRUB_BTRFS_ROOT_VOL_OBJECTID)
+    subvol = grub_strdup ("");
+  else
+    {
+      while (id != GRUB_BTRFS_ROOT_VOL_OBJECTID)
+       {
+         grub_uint64_t parent_id;
+         char *path_out;
+
+         err = grub_btrfs_get_parent_subvol_path (data, id, subvol, 
&parent_id, &path_out);
+         if (err)
+           {
+             grub_btrfs_unmount (data);
+             grub_device_close (dev);
+             return err;
+           }
+
+         grub_free (subvol);
+         subvol = path_out;
+         id = parent_id;
+       }
+    }
+
+  if (ret_subvolid)
+    *ret_subvolid = subvolid;
+  if (ret_subvol)
+    *ret_subvol = subvol;
+
+  grub_btrfs_unmount (data);
+  grub_device_close (dev);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_btrfs_get_default_subvol (struct grub_extcmd_context *ctxt,
+                            int argc, char **argv)
+{
+  grub_err_t err;
+  char *subvol = NULL;
+  grub_uint64_t subvolid = 0;
+  char *varname = NULL;
+  char *output = NULL;
+  int path_only = ctxt->state[1].set;
+  int num_only = ctxt->state[2].set;
+
+  if (ctxt->state[0].set)
+    varname = ctxt->state[0].arg;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+
+  if ((err = grub_btrfs_get_default_subvol (argv[0], &subvolid, &subvol)) != 
GRUB_ERR_NONE)
+    {
+      if (err == GRUB_ERR_BAD_FS)
+       err = grub_errno = GRUB_ERR_NONE;
+      return err;
+    }
+
+  if (num_only && path_only)
+      output = grub_xasprintf ("%"PRIuGRUB_UINT64_T" /%s", subvolid, subvol);
+  else if (num_only)
+      output = grub_xasprintf ("%"PRIuGRUB_UINT64_T, subvolid);
+  else
+      output = grub_xasprintf ("/%s", subvol);
+
+  if (varname)
+    grub_env_set(varname, output);
+  else
+    grub_printf ("%s\n", output);
+
+  grub_free (output);
+  grub_free (subvol);
+
+  return GRUB_ERR_NONE;
+}
+
 static struct grub_fs grub_btrfs_fs = {
   .name = "btrfs",
   .fs_dir = grub_btrfs_dir,
@@ -2927,6 +3119,7 @@ static struct grub_fs grub_btrfs_fs = {
 
 static grub_command_t cmd_info;
 static grub_extcmd_t cmd_list_subvols;
+static grub_extcmd_t cmd_get_default_subvol;
 
 GRUB_MOD_INIT (btrfs)
 {
@@ -2941,6 +3134,11 @@ GRUB_MOD_INIT (btrfs)
                                         "[-p|-n] [-r] [-o var] DEVICE",
                                         "Print list of BtrFS subvolumes on "
                                         "DEVICE.", opt_list_subvols);
+  cmd_get_default_subvol = grub_register_extcmd("btrfs-get-default-subvol",
+                                        grub_cmd_btrfs_get_default_subvol, 0,
+                                        "[-p|-n] [-o var] DEVICE",
+                                        "Print default BtrFS subvolume on "
+                                        "DEVICE.", opt_default_subvol);
 }
 
 GRUB_MOD_FINI (btrfs)
@@ -2948,4 +3146,5 @@ GRUB_MOD_FINI (btrfs)
   grub_fs_unregister (&grub_btrfs_fs);
   grub_unregister_command (cmd_info);
   grub_unregister_extcmd (cmd_list_subvols);
+  grub_unregister_extcmd (cmd_get_default_subvol);
 }
-- 
2.55.0



++++++ grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch ++++++
--- /var/tmp/diff_new_pack.Pb5Vh4/_old  2026-08-31 15:56:36.550785107 +0200
+++ /var/tmp/diff_new_pack.Pb5Vh4/_new  2026-08-31 15:56:36.553785212 +0200
@@ -36,31 +36,7 @@
 
 --- a/grub-core/fs/btrfs.c
 +++ b/grub-core/fs/btrfs.c
-@@ -41,6 +41,9 @@
- #include <grub/crypto.h>
- #include <grub/diskfilter.h>
- #include <grub/safemath.h>
-+#include <grub/command.h>
-+#include <grub/env.h>
-+#include <grub/extcmd.h>
- 
- GRUB_MOD_LICENSE ("GPLv3+");
- 
-@@ -79,9 +82,11 @@
-   grub_uint64_t generation;
-   grub_uint64_t root_tree;
-   grub_uint64_t chunk_tree;
--  grub_uint8_t dummy2[0x20];
-+  grub_uint8_t dummy2[0x18];
-+  grub_uint64_t bytes_used;
-   grub_uint64_t root_dir_objectid;
--  grub_uint8_t dummy3[0x41];
-+  grub_uint64_t num_devices;
-+  grub_uint8_t dummy3[0x39];
-   struct grub_btrfs_device this_device;
-   char label[0x100];
-   grub_uint8_t dummy4[0x100];
-@@ -121,6 +126,7 @@
+@@ -126,6 +126,7 @@
    grub_uint64_t exttree;
    grub_size_t extsize;
    struct grub_btrfs_extent_data *extent;
@@ -68,44 +44,29 @@
  };
  
  struct grub_btrfs_chunk_item
-@@ -191,6 +197,14 @@
-   } *data;
- };
- 
-+struct grub_btrfs_root_ref
-+{
-+  grub_uint64_t dirid;
-+  grub_uint64_t sequence;
-+  grub_uint16_t name_len;
-+  const char name[0];
-+} __attribute__ ((packed));
-+
- struct grub_btrfs_time
- {
-   grub_int64_t sec;
-@@ -236,6 +250,14 @@
+@@ -249,10 +250,14 @@
  
  #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100
  
 +#define GRUB_BTRFS_ROOT_TREE_OBJECTID 1ULL
-+#define GRUB_BTRFS_FS_TREE_OBJECTID 5ULL
-+#define GRUB_BTRFS_ROOT_REF_KEY     156
-+#define GRUB_BTRFS_ROOT_ITEM_KEY     132
-+
+ #define GRUB_BTRFS_FS_TREE_OBJECTID 5ULL
+ #define GRUB_BTRFS_ROOT_REF_KEY     156
+ #define GRUB_BTRFS_ROOT_ITEM_KEY     132
+ 
 +static grub_uint64_t btrfs_default_subvolid = 0;
 +static char *btrfs_default_subvol = NULL;
 +
  static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2,
    256 * 1048576 * 2, 1048576ULL * 1048576ULL * 2
  };
-@@ -1252,6 +1274,62 @@
+@@ -1276,6 +1281,62 @@
    return GRUB_ERR_NONE;
  }
  
 +static grub_err_t
 +get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree,
 +            grub_uint64_t objectid, grub_uint64_t offset,
-+            grub_uint64_t *fs_root);
++            grub_uint64_t *fs_root, grub_uint64_t *flags);
 +
 +static grub_err_t
 +lookup_root_by_id(struct grub_btrfs_data *data, grub_uint64_t id)
@@ -113,7 +74,7 @@
 +  grub_err_t err;
 +  grub_uint64_t tree;
 +
-+  err = get_fs_root(data, data->sblock.root_tree, id, -1, &tree);
++  err = get_fs_root (data, data->sblock.root_tree, id, -1, &tree, NULL);
 +  if (!err)
 +    data->fs_tree = tree;
 +  return err;
@@ -161,7 +122,7 @@
  static struct grub_btrfs_data *
  grub_btrfs_mount (grub_device_t dev)
  {
-@@ -1287,6 +1365,13 @@
+@@ -1311,6 +1372,13 @@
    data->devices_attached[0].dev = dev;
    data->devices_attached[0].id = data->sblock.this_device.device_id;
  
@@ -175,106 +136,7 @@
    return data;
  }
  
-@@ -1788,6 +1873,98 @@
- }
- 
- static grub_err_t
-+find_pathname(struct grub_btrfs_data *data, grub_uint64_t objectid,
-+              grub_uint64_t fs_root, const char *name, char **pathname)
-+{
-+  grub_err_t err;
-+  struct grub_btrfs_key key = {
-+    .object_id = objectid,
-+    .type = GRUB_BTRFS_ITEM_TYPE_INODE_REF,
-+    .offset = 0,
-+  };
-+  struct grub_btrfs_key key_out;
-+  struct grub_btrfs_leaf_descriptor desc;
-+  char *p = grub_strdup (name);
-+  grub_disk_addr_t elemaddr;
-+  grub_size_t elemsize;
-+  grub_size_t alloc = grub_strlen(name) + 1;
-+
-+  err = lower_bound(data, &key, &key_out, fs_root,
-+                    &elemaddr, &elemsize, &desc, 0);
-+  if (err)
-+    return grub_error(err, "lower_bound caught %d\n", err);
-+
-+  if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF)
-+    next(data, &desc, &elemaddr, &elemsize, &key_out);
-+
-+  if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF)
-+    {
-+      return grub_error(GRUB_ERR_FILE_NOT_FOUND,
-+                        "Can't find inode ref for {%"PRIuGRUB_UINT64_T
-+                        ", %u, %"PRIuGRUB_UINT64_T"} %"PRIuGRUB_UINT64_T
-+                        "/%"PRIuGRUB_SIZE"\n",
-+                        key_out.object_id, key_out.type,
-+                        key_out.offset, elemaddr, elemsize);
-+    }
-+
-+
-+  while (key_out.type == GRUB_BTRFS_ITEM_TYPE_INODE_REF &&
-+         key_out.object_id != key_out.offset) {
-+    struct grub_btrfs_inode_ref *inode_ref;
-+    char *new;
-+    grub_size_t sz;
-+
-+    if (grub_add (elemsize, 1, &sz))
-+      return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
-+
-+    inode_ref = grub_malloc(sz);
-+    if (!inode_ref)
-+      return grub_error(GRUB_ERR_OUT_OF_MEMORY,
-+                        "couldn't allocate memory for inode_ref 
(%"PRIuGRUB_SIZE")\n", elemsize);
-+
-+    err = grub_btrfs_read_logical(data, elemaddr, inode_ref, elemsize, 0);
-+    if (err)
-+      return grub_error(err, "read_logical caught %d\n", err);
-+
-+    if (grub_add (grub_le_to_cpu16 (inode_ref->n), 2, &sz) ||
-+      grub_add (alloc, sz, &alloc))
-+      return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
-+
-+    new = grub_malloc(alloc);
-+    if (!new)
-+      return grub_error(GRUB_ERR_OUT_OF_MEMORY,
-+                        "couldn't allocate memory for name 
(%"PRIuGRUB_SIZE")\n", alloc);
-+
-+    grub_memcpy(new, inode_ref->name, grub_le_to_cpu16 (inode_ref->n));
-+    if (p)
-+      {
-+        new[grub_le_to_cpu16 (inode_ref->n)] = '/';
-+        grub_strcpy (new + grub_le_to_cpu16 (inode_ref->n) + 1, p);
-+        grub_free(p);
-+      }
-+    else
-+      new[grub_le_to_cpu16 (inode_ref->n)] = 0;
-+    grub_free(inode_ref);
-+
-+    p = new;
-+
-+    key.object_id = key_out.offset;
-+
-+    err = lower_bound(data, &key, &key_out, fs_root, &elemaddr,
-+                      &elemsize, &desc, 0);
-+    if (err)
-+      return grub_error(err, "lower_bound caught %d\n", err);
-+
-+    if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF)
-+      next(data, &desc, &elemaddr, &elemsize, &key_out);
-+
-+  }
-+
-+  *pathname = p;
-+  return 0;
-+}
-+
-+static grub_err_t
- find_path (struct grub_btrfs_data *data,
-          const char *path, struct grub_btrfs_key *key,
-          grub_uint64_t *tree, grub_uint8_t *type)
-@@ -1806,14 +1983,26 @@
+@@ -1927,14 +1995,26 @@
    unsigned symlinks_max = 32;
    grub_size_t sz;
  
@@ -305,14 +167,18 @@
    while (1)
      {
        while (path[0] == '/')
-@@ -2000,13 +2189,25 @@
+@@ -2121,13 +2201,25 @@
          path = path_alloc = tmp;
          if (path[0] == '/')
            {
 -            err = get_root (data, key, tree, type);
 -            if (err)
 +            if (data->fs_tree)
-+              {
+               {
+-                grub_free (direl);
+-                grub_free (path_alloc);
+-                grub_free (origpath);
+-                return err;
 +                *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY;
 +                *tree = data->fs_tree;
 +                /* This is a tree root, so everything starts at objectid 256 
*/
@@ -321,11 +187,7 @@
 +                key->offset = 0;
 +              }
 +            else
-               {
--                grub_free (direl);
--                grub_free (path_alloc);
--                grub_free (origpath);
--                return err;
++              {
 +                err = get_root (data, key, tree, type);
 +                if (err)
 +                  {
@@ -337,305 +199,10 @@
                }
            }
          continue;
-@@ -2282,6 +2483,20 @@
-                                data->tree, file->offset, buf, len);
- }
- 
-+static char *
-+btrfs_unparse_uuid(struct grub_btrfs_data *data)
-+{
-+  return  grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
-+                        grub_be_to_cpu16 (data->sblock.uuid[0]),
-+                        grub_be_to_cpu16 (data->sblock.uuid[1]),
-+                        grub_be_to_cpu16 (data->sblock.uuid[2]),
-+                        grub_be_to_cpu16 (data->sblock.uuid[3]),
-+                        grub_be_to_cpu16 (data->sblock.uuid[4]),
-+                        grub_be_to_cpu16 (data->sblock.uuid[5]),
-+                        grub_be_to_cpu16 (data->sblock.uuid[6]),
-+                        grub_be_to_cpu16 (data->sblock.uuid[7]));
-+}
-+
- static grub_err_t
- grub_btrfs_uuid (grub_device_t device, char **uuid)
- {
-@@ -2293,15 +2508,7 @@
-   if (!data)
-     return grub_errno;
- 
--  *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
--                        grub_be_to_cpu16 (data->sblock.uuid[0]),
--                        grub_be_to_cpu16 (data->sblock.uuid[1]),
--                        grub_be_to_cpu16 (data->sblock.uuid[2]),
--                        grub_be_to_cpu16 (data->sblock.uuid[3]),
--                        grub_be_to_cpu16 (data->sblock.uuid[4]),
--                        grub_be_to_cpu16 (data->sblock.uuid[5]),
--                        grub_be_to_cpu16 (data->sblock.uuid[6]),
--                        grub_be_to_cpu16 (data->sblock.uuid[7]));
-+  *uuid = btrfs_unparse_uuid(data);
- 
-   grub_btrfs_unmount (data);
- 
-@@ -2431,6 +2638,253 @@
- }
- #endif
- 
-+static grub_err_t
-+grub_cmd_btrfs_info (grub_command_t cmd __attribute__ ((unused)), int argc,
-+                   char **argv)
-+{
-+  grub_device_t dev;
-+  char *devname;
-+  struct grub_btrfs_data *data;
-+  char *uuid;
-+
-+  if (argc < 1)
-+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
-+
-+  devname = grub_file_get_device_name(argv[0]);
-+
-+  if (!devname)
-+    return grub_errno;
-+
-+  dev = grub_device_open (devname);
-+  grub_free (devname);
-+  if (!dev)
-+    return grub_errno;
-+
-+  data = grub_btrfs_mount (dev);
-+  if (!data)
-+    {
-+      grub_device_close(dev);
-+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to open fs");
-+    }
-+
-+  if (*data->sblock.label != '\0')
-+    grub_printf("Label: '%s' ", data->sblock.label);
-+  else
-+    grub_printf("Label: none ");
-+
-+  uuid = btrfs_unparse_uuid(data);
-+
-+  grub_printf(" uuid: %s\n\tTotal devices %" PRIuGRUB_UINT64_T
-+              " FS bytes used %" PRIuGRUB_UINT64_T "\n",
-+            uuid, grub_cpu_to_le64(data->sblock.num_devices),
-+            grub_cpu_to_le64(data->sblock.bytes_used));
-+
-+  grub_btrfs_unmount (data);
-+
-+  return 0;
-+}
-+
-+static grub_err_t
-+get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree,
-+            grub_uint64_t objectid, grub_uint64_t offset,
-+            grub_uint64_t *fs_root)
-+{
-+  grub_err_t err;
-+  struct grub_btrfs_key key_in = {
-+    .object_id = objectid,
-+    .type = GRUB_BTRFS_ROOT_ITEM_KEY,
-+    .offset = offset,
-+  }, key_out;
-+  struct grub_btrfs_leaf_descriptor desc;
-+  grub_disk_addr_t elemaddr;
-+  grub_size_t elemsize;
-+  struct grub_btrfs_root_item ri;
-+
-+  err = lower_bound(data, &key_in, &key_out, tree,
-+                    &elemaddr, &elemsize, &desc, 0);
-+
-+  if (err)
-+    return err;
-+
-+  if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM || elemaddr == 0)
-+    return grub_error(GRUB_ERR_FILE_NOT_FOUND,
-+                    N_("can't find fs root for subvol 
%"PRIuGRUB_UINT64_T"\n"),
-+                    key_in.object_id);
-+
-+  err = grub_btrfs_read_logical (data, elemaddr, &ri, sizeof (ri), 0);
-+  if (err)
-+    return err;
-+
-+  *fs_root = ri.tree;
-+
-+  return GRUB_ERR_NONE;
-+}
-+
-+static const struct grub_arg_option options[] = {
-+  {"output", 'o', 0, N_("Output to a variable instead of the console."),
-+   N_("VARNAME"), ARG_TYPE_STRING},
-+  {"path-only", 'p', 0, N_("Show only the path of the subvolume."), 0, 0},
-+  {"id-only", 'i', 0, N_("Show only the id of the subvolume."), 0, 0},
-+  {0, 0, 0, 0, 0, 0}
-+};
-+
-+static grub_err_t
-+grub_cmd_btrfs_list_subvols (struct grub_extcmd_context *ctxt,
-+                           int argc, char **argv)
-+{
-+  struct grub_btrfs_data *data;
-+  grub_device_t dev;
-+  char *devname;
-+  grub_uint64_t tree;
-+  struct grub_btrfs_key key_in = {
-+    .object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_FS_TREE_OBJECTID),
-+    .type = GRUB_BTRFS_ROOT_REF_KEY,
-+    .offset = 0,
-+  }, key_out;
-+  struct grub_btrfs_leaf_descriptor desc;
-+  grub_disk_addr_t elemaddr;
-+  grub_uint64_t fs_root = 0;
-+  grub_size_t elemsize;
-+  grub_size_t allocated = 0;
-+  int r = 0;
-+  grub_err_t err;
-+  char *buf = NULL;
-+  int print = 1;
-+  int path_only = ctxt->state[1].set;
-+  int num_only = ctxt->state[2].set;
-+  char *varname = NULL;
-+  char *output = NULL;
-+
-+  if (ctxt->state[0].set) {
-+    varname = ctxt->state[0].arg;
-+    print = 0;
-+  }
-+
-+  if (argc < 1)
-+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
-+
-+  devname = grub_file_get_device_name(argv[0]);
-+  if (!devname)
-+    return grub_errno;
-+
-+  dev = grub_device_open (devname);
-+  grub_free (devname);
-+  if (!dev)
-+    return grub_errno;
-+
-+  data = grub_btrfs_mount(dev);
-+  if (!data)
-+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "could not open device");
-+
-+  tree = data->sblock.root_tree;
-+  err = get_fs_root(data, tree, grub_cpu_to_le64_compile_time 
(GRUB_BTRFS_FS_TREE_OBJECTID),
-+                    0, &fs_root);
-+  if (err)
-+    goto out;
-+
-+  err = lower_bound(data, &key_in, &key_out, tree,
-+                    &elemaddr, &elemsize, &desc, 0);
-+
-+  if (err)
-+    {
-+      grub_btrfs_unmount(data);
-+      return err;
-+    }
-+
-+  if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_REF || elemaddr == 0)
-+    {
-+      r = next(data, &desc, &elemaddr, &elemsize, &key_out);
-+    }
-+
-+  if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_REF) {
-+    err = GRUB_ERR_FILE_NOT_FOUND;
-+    grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("can't find root refs"));
-+    goto out;
-+  }
-+
-+  do
-+    {
-+      struct grub_btrfs_root_ref *ref;
-+      char *p = NULL;
-+
-+      if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_REF)
-+        {
-+          r = 0;
-+          break;
-+        }
-+
-+      if (elemsize > allocated)
-+        {
-+        grub_size_t sz;
-+
-+          grub_free(buf);
-+
-+        if (grub_mul (elemsize, 2, &allocated) ||
-+            grub_add (allocated, 1, &sz))
-+          return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is 
detected"));
-+
-+          buf = grub_malloc(sz);
-+          if (!buf)
-+            {
-+              r = -grub_errno;
-+              break;
-+            }
-+        }
-+      ref = (struct grub_btrfs_root_ref *)buf;
-+
-+      err = grub_btrfs_read_logical(data, elemaddr, buf, elemsize, 0);
-+      if (err)
-+        {
-+          r = -err;
-+          break;
-+        }
-+        buf[elemsize] = 0;
-+
-+      err = find_pathname(data, ref->dirid, fs_root, ref->name, &p);
-+      if (err)
-+        {
-+          r = -err;
-+          break;
-+        }
-+
-+      if (print)
-+        {
-+          if (num_only)
-+            grub_printf("ID %"PRIuGRUB_UINT64_T"\n", key_out.offset);
-+          else if (path_only)
-+            grub_printf("%s\n", p);
-+          else
-+            grub_printf("ID %"PRIuGRUB_UINT64_T" path %s\n", key_out.offset, 
p);
-+        } else {
-+          char *old = output;
-+          if (num_only)
-+            output = grub_xasprintf("%s%"PRIuGRUB_UINT64_T"\n",
-+                                    old ?: "", key_out.offset);
-+          else if (path_only)
-+            output = grub_xasprintf("%s%s\n", old ?: "", p);
-+          else
-+            output = grub_xasprintf("%sID %"PRIuGRUB_UINT64_T" path %s\n",
-+                                    old ?: "", key_out.offset, p);
-+
-+          if (old)
-+            grub_free(old);
-+        }
-+
-+      r = next(data, &desc, &elemaddr, &elemsize, &key_out);
-+  } while(r > 0);
-+
-+  if (output)
-+    grub_env_set(varname, output);
-+
-+out:
-+  free_iterator(&desc);
-+  grub_btrfs_unmount(data);
-+
-+  grub_device_close (dev);
-+
-+  return 0;
-+}
-+
- static struct grub_fs grub_btrfs_fs = {
-   .name = "btrfs",
-   .fs_dir = grub_btrfs_dir,
-@@ -2446,13 +2900,89 @@
- #endif
- };
+@@ -3117,6 +3209,61 @@
+ static grub_extcmd_t cmd_list_subvols;
+ static grub_extcmd_t cmd_get_default_subvol;
  
-+static grub_command_t cmd_info;
-+static grub_extcmd_t cmd_list_subvols;
-+
 +static char *
 +subvolid_set_env (struct grub_env_var *var __attribute__ ((unused)),
 +                  const char *val)
@@ -694,15 +261,10 @@
  GRUB_MOD_INIT (btrfs)
  {
    grub_btrfs_fs.mod = mod;
-   grub_fs_register (&grub_btrfs_fs);
-+  cmd_info = grub_register_command("btrfs-info", grub_cmd_btrfs_info,
-+                                 "DEVICE",
-+                                 "Print BtrFS info about DEVICE.");
-+  cmd_list_subvols = grub_register_extcmd("btrfs-list-subvols",
-+                                       grub_cmd_btrfs_list_subvols, 0,
-+                                       "[-p|-n] [-o var] DEVICE",
-+                                       "Print list of BtrFS subvolumes on "
-+                                       "DEVICE.", options);
+@@ -3135,12 +3282,20 @@
+                                        "[-p|-n] [-o var] DEVICE",
+                                        "Print default BtrFS subvolume on "
+                                        "DEVICE.", opt_default_subvol);
 +  grub_register_variable_hook ("btrfs_subvol", subvol_get_env,
 +                               subvol_set_env);
 +  grub_register_variable_hook ("btrfs_subvolid", subvolid_get_env,
@@ -713,20 +275,11 @@
  {
 +  grub_register_variable_hook ("btrfs_subvol", NULL, NULL);
 +  grub_register_variable_hook ("btrfs_subvolid", NULL, NULL);
-+  grub_unregister_command (cmd_info);
-+  grub_unregister_extcmd (cmd_list_subvols);
    grub_fs_unregister (&grub_btrfs_fs);
+   grub_unregister_command (cmd_info);
+   grub_unregister_extcmd (cmd_list_subvols);
+   grub_unregister_extcmd (cmd_get_default_subvol);
  }
 +
 +// vim: si et sw=2:
---- a/include/grub/btrfs.h
-+++ b/include/grub/btrfs.h
-@@ -29,6 +29,7 @@
-     GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM = 0x84,
-     GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF = 0x90,
-     GRUB_BTRFS_ITEM_TYPE_DEVICE = 0xd8,
-+    GRUB_BTRFS_ITEM_TYPE_ROOT_REF = 0x9c,
-     GRUB_BTRFS_ITEM_TYPE_CHUNK = 0xe4
-   };
- 
 

++++++ grub2-btrfs-06-subvol-mount.patch ++++++
--- /var/tmp/diff_new_pack.Pb5Vh4/_old  2026-08-31 15:56:36.582786224 +0200
+++ /var/tmp/diff_new_pack.Pb5Vh4/_new  2026-08-31 15:56:36.585786328 +0200
@@ -33,8 +33,8 @@
 +find_mtab_subvol_tree (const char *path, char **path_in_subvol);
  
  static grub_err_t
- read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb)
-@@ -1302,9 +1309,26 @@
+ grub_btrfs_get_parent_subvol_path (struct grub_btrfs_data *data,
+@@ -1309,9 +1316,26 @@
    grub_err_t err;
    grub_uint64_t tree = 0;
    grub_uint8_t type;
@@ -61,7 +61,7 @@
    if (err)
        return grub_error(GRUB_ERR_FILE_NOT_FOUND, "couldn't locate %s\n", 
path);
  
-@@ -2342,11 +2366,20 @@
+@@ -2354,11 +2378,20 @@
    grub_uint8_t type;
    grub_size_t est_size = 0;
    grub_size_t sz;
@@ -83,7 +83,7 @@
    if (err)
      {
        grub_btrfs_unmount (data);
-@@ -2480,11 +2513,21 @@
+@@ -2492,11 +2525,21 @@
    struct grub_btrfs_inode inode;
    grub_uint8_t type;
    struct grub_btrfs_key key_in;
@@ -106,8 +106,8 @@
    if (err)
      {
        grub_btrfs_unmount (data);
-@@ -2728,6 +2771,150 @@
-   return 0;
+@@ -2759,6 +2802,150 @@
+   return GRUB_ERR_NONE;
  }
  
 +struct grub_btrfs_mtab
@@ -257,24 +257,24 @@
  static grub_err_t
  get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree,
              grub_uint64_t objectid, grub_uint64_t offset,
-@@ -2940,6 +3127,7 @@
+@@ -3250,6 +3437,7 @@
  };
  
  static grub_command_t cmd_info;
 +static grub_command_t cmd_mount_subvol;
  static grub_extcmd_t cmd_list_subvols;
+ static grub_extcmd_t cmd_get_default_subvol;
  
- static char *
-@@ -3004,6 +3192,9 @@
-   cmd_info = grub_register_command("btrfs-info", grub_cmd_btrfs_info,
-                                  "DEVICE",
-                                  "Print BtrFS info about DEVICE.");
+@@ -3316,6 +3504,9 @@
+                                   grub_cmd_btrfs_info,
+                                   "DEVICE",
+                                   "Print BtrFS info about DEVICE.");
 +  cmd_mount_subvol = grub_register_command("btrfs-mount-subvol", 
grub_cmd_btrfs_mount_subvol,
 +                                 "DEVICE DIRECTORY SUBVOL",
 +                                 "Set btrfs DEVICE the DIRECTORY a mountpoint 
of SUBVOL.");
    cmd_list_subvols = grub_register_extcmd("btrfs-list-subvols",
                                         grub_cmd_btrfs_list_subvols, 0,
-                                        "[-p|-n] [-o var] DEVICE",
+                                        "[-p|-n] [-r] [-o var] DEVICE",
 --- a/grub-core/osdep/linux/getroot.c
 +++ b/grub-core/osdep/linux/getroot.c
 @@ -103,6 +103,14 @@
@@ -431,7 +431,7 @@
            }
        }
        else if (!retry && grub_strcmp (entries[i].fstype, "autofs") == 0)
-@@ -1213,6 +1337,24 @@
+@@ -1223,6 +1347,24 @@
  }
  #endif
  

++++++ grub2-btrfs-10-config-directory.patch ++++++
--- /var/tmp/diff_new_pack.Pb5Vh4/_old  2026-08-31 15:56:36.608787131 +0200
+++ /var/tmp/diff_new_pack.Pb5Vh4/_new  2026-08-31 15:56:36.612787270 +0200
@@ -8,110 +8,7 @@
 
 --- a/grub-core/fs/btrfs.c
 +++ b/grub-core/fs/btrfs.c
-@@ -3297,8 +3297,7 @@
- }
- 
- static grub_err_t
--grub_cmd_btrfs_get_default_subvol (struct grub_extcmd_context *ctxt,
--                           int argc, char **argv)
-+grub_btrfs_get_default_subvol (const char *name, grub_uint64_t *ret_subvolid, 
char **ret_subvol)
- {
-   char *devname;
-   grub_device_t dev;
-@@ -3307,21 +3306,8 @@
-   grub_uint64_t id;
-   char *subvol = NULL;
-   grub_uint64_t subvolid = 0;
--  char *varname = NULL;
--  char *output = NULL;
--  int path_only = ctxt->state[1].set;
--  int num_only = ctxt->state[2].set;
--
--  if (ctxt->state[0].set)
--    varname = ctxt->state[0].arg;
--
--  if (argc < 1)
--    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
--
--  devname = grub_file_get_device_name(argv[0]);
--  if (!devname)
--    return grub_errno;
- 
-+  devname = grub_file_get_device_name(name);
-   dev = grub_device_open (devname);
-   grub_free (devname);
-   if (!dev)
-@@ -3332,8 +3318,7 @@
-     {
-       grub_device_close (dev);
-       grub_dprintf ("btrfs", "failed to open fs\n");
--      grub_errno = GRUB_ERR_NONE;
--      return 0;
-+      return grub_errno;
-     }
- 
-   err = grub_btrfs_get_default_subvolume_id (data, &subvolid);
-@@ -3362,12 +3347,47 @@
-         return err;
-       }
- 
--      if (subvol)
--        grub_free (subvol);
-+      grub_free (subvol);
-       subvol = path_out;
-       id = parent_id;
-     }
- 
-+  if (ret_subvolid)
-+    *ret_subvolid = subvolid;
-+  if (ret_subvol)
-+    *ret_subvol = subvol;
-+
-+  grub_btrfs_unmount (data);
-+  grub_device_close (dev);
-+
-+  return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_cmd_btrfs_get_default_subvol (struct grub_extcmd_context *ctxt,
-+                           int argc, char **argv)
-+{
-+  grub_err_t err;
-+  char *subvol = NULL;
-+  grub_uint64_t subvolid = 0;
-+  char *varname = NULL;
-+  char *output = NULL;
-+  int path_only = ctxt->state[1].set;
-+  int num_only = ctxt->state[2].set;
-+
-+  if (ctxt->state[0].set)
-+    varname = ctxt->state[0].arg;
-+
-+  if (argc < 1)
-+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
-+
-+  if ((err = grub_btrfs_get_default_subvol (argv[0], &subvolid, &subvol)) != 
GRUB_ERR_NONE)
-+    {
-+      if (err == GRUB_ERR_BAD_FS)
-+      err = grub_errno = GRUB_ERR_NONE;
-+      return err;
-+    }
-+
-   if (num_only && path_only)
-       output = grub_xasprintf ("%"PRIuGRUB_UINT64_T" /%s", subvolid, subvol);
-   else if (num_only)
-@@ -3383,9 +3403,6 @@
-   grub_free (output);
-   grub_free (subvol);
- 
--  grub_btrfs_unmount (data);
--  grub_device_close (dev);
--
-   return GRUB_ERR_NONE;
- }
- 
-@@ -3464,6 +3481,122 @@
+@@ -3518,6 +3518,122 @@
      return "";
  }
  
@@ -234,7 +131,7 @@
  GRUB_MOD_INIT (btrfs)
  {
    grub_btrfs_fs.mod = mod;
-@@ -3488,6 +3621,8 @@
+@@ -3543,6 +3659,8 @@
                                 subvol_set_env);
    grub_register_variable_hook ("btrfs_subvolid", subvolid_get_env,
                                 subvolid_set_env);
@@ -243,12 +140,12 @@
    grub_env_export ("btrfs_subvol");
    grub_env_export ("btrfs_subvolid");
    grub_env_export ("btrfs_relative_path");
-@@ -3497,6 +3632,7 @@
+@@ -3552,6 +3670,7 @@
  {
    grub_register_variable_hook ("btrfs_subvol", NULL, NULL);
    grub_register_variable_hook ("btrfs_subvolid", NULL, NULL);
 +  grub_register_variable_hook ("btrfs_relative_path", NULL, NULL);
+   grub_fs_unregister (&grub_btrfs_fs);
    grub_unregister_command (cmd_info);
    grub_unregister_extcmd (cmd_list_subvols);
-   grub_fs_unregister (&grub_btrfs_fs);
 

Reply via email to