On Fri, Oct 11, 2024 at 6:40 PM Leo Sandoval <lsand...@redhat.com> wrote: > > From: Michael Chang <mch...@suse.com> > > Signed-off-by: Michael Chang <mch...@suse.com> > Signed-off-by: Robbie Harwood <rharw...@redhat.com>
This needs a real commit message describing what this does. Please work with Michael to come up with one. :) > --- > grub-core/fs/btrfs.c | 107 ++++++++++++++++++++++++++++++------------- > 1 file changed, 76 insertions(+), 31 deletions(-) > > diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c > index 14e38a4df..d47f9ab03 100644 > --- a/grub-core/fs/btrfs.c > +++ b/grub-core/fs/btrfs.c > @@ -1335,6 +1335,7 @@ grub_btrfs_mount (grub_device_t dev) > { > struct grub_btrfs_data *data; > grub_err_t err; > + const char *relpath = grub_env_get ("btrfs_relative_path"); > > if (!dev->disk) > { > @@ -1365,11 +1366,14 @@ grub_btrfs_mount (grub_device_t dev) > data->devices_attached[0].dev = dev; > data->devices_attached[0].id = data->sblock.this_device.device_id; > > - err = btrfs_handle_subvol (data); > - if (err) > + if (relpath && (relpath[0] == '1' || relpath[0] == 'y')) > { > - grub_free (data); > - return NULL; > + err = btrfs_handle_subvol (data); > + if (err) > + { > + grub_free (data); > + return NULL; > + } > } > > return data; > @@ -1966,24 +1970,39 @@ find_path (struct grub_btrfs_data *data, > grub_size_t allocated = 0; > struct grub_btrfs_dir_item *direl = NULL; > struct grub_btrfs_key key_out; > + int follow_default; > const char *ctoken; > grub_size_t ctokenlen; > char *path_alloc = NULL; > char *origpath = NULL; > unsigned symlinks_max = 32; > + const char *relpath = grub_env_get ("btrfs_relative_path"); > > + follow_default = 0; > origpath = grub_strdup (path); > if (!origpath) > return grub_errno; > > - if (data->fs_tree) > + if (relpath && (relpath[0] == '1' || relpath[0] == 'y')) > { > - *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; > - *tree = data->fs_tree; > - /* This is a tree root, so everything starts at objectid 256 */ > - key->object_id = grub_cpu_to_le64_compile_time > (GRUB_BTRFS_OBJECT_ID_CHUNK); > - key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; > - key->offset = 0; > + if (data->fs_tree) > + { > + *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; > + *tree = data->fs_tree; > + /* This is a tree root, so everything starts at objectid 256 */ > + key->object_id = grub_cpu_to_le64_compile_time > (GRUB_BTRFS_OBJECT_ID_CHUNK); > + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; > + key->offset = 0; > + } > + else > + { > + *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; > + *tree = data->sblock.root_tree; > + key->object_id = data->sblock.root_dir_objectid; > + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; > + key->offset = 0; > + follow_default = 1; > + } > } > else > { > @@ -1994,15 +2013,23 @@ find_path (struct grub_btrfs_data *data, > > while (1) > { > - while (path[0] == '/') > - path++; > - if (!path[0]) > - break; > - slash = grub_strchr (path, '/'); > - if (!slash) > - slash = path + grub_strlen (path); > - ctoken = path; > - ctokenlen = slash - path; > + if (!follow_default) > + { > + while (path[0] == '/') > + path++; > + if (!path[0]) > + break; > + slash = grub_strchr (path, '/'); > + if (!slash) > + slash = path + grub_strlen (path); > + ctoken = path; > + ctokenlen = slash - path; > + } > + else > + { > + ctoken = "default"; > + ctokenlen = sizeof ("default") - 1; > + } > > if (*type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) > { > @@ -2013,7 +2040,9 @@ find_path (struct grub_btrfs_data *data, > > if (ctokenlen == 1 && ctoken[0] == '.') > { > - path = slash; > + if (!follow_default) > + path = slash; > + follow_default = 0; > continue; > } > if (ctokenlen == 2 && ctoken[0] == '.' && ctoken[1] == '.') > @@ -2044,8 +2073,9 @@ find_path (struct grub_btrfs_data *data, > *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; > key->object_id = key_out.offset; > > - path = slash; > - > + if (!follow_default) > + path = slash; > + follow_default = 0; > continue; > } > > @@ -2114,7 +2144,9 @@ find_path (struct grub_btrfs_data *data, > return err; > } > > - path = slash; > + if (!follow_default) > + path = slash; > + follow_default = 0; > if (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK) > { > struct grub_btrfs_inode inode; > @@ -2164,14 +2196,26 @@ find_path (struct grub_btrfs_data *data, > path = path_alloc = tmp; > if (path[0] == '/') > { > - if (data->fs_tree) > + if (relpath && (relpath[0] == '1' || relpath[0] == 'y')) > { > - *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; > - *tree = data->fs_tree; > - /* This is a tree root, so everything starts at objectid > 256 */ > - key->object_id = grub_cpu_to_le64_compile_time > (GRUB_BTRFS_OBJECT_ID_CHUNK); > - key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; > - key->offset = 0; > + if (data->fs_tree) > + { > + *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; > + *tree = data->fs_tree; > + /* This is a tree root, so everything starts at > objectid 256 */ > + key->object_id = grub_cpu_to_le64_compile_time > (GRUB_BTRFS_OBJECT_ID_CHUNK); > + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; > + key->offset = 0; > + } > + else > + { > + *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; > + *tree = data->sblock.root_tree; > + key->object_id = data->sblock.root_dir_objectid; > + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; > + key->offset = 0; > + follow_default = 1; > + } > } > else > { > @@ -2922,6 +2966,7 @@ GRUB_MOD_INIT (btrfs) > subvolid_set_env); > grub_env_export ("btrfs_subvol"); > grub_env_export ("btrfs_subvolid"); > + grub_env_export ("btrfs_relative_path"); > } > > GRUB_MOD_FINI (btrfs) > -- > 2.46.2 > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel -- 真実はいつも一つ!/ Always, there's only one truth! _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel