You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
5.7 KiB
196 lines
5.7 KiB
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
|
From: Michael Chang <mchang@suse.com> |
|
Date: Thu, 21 Aug 2014 03:39:11 +0000 |
|
Subject: [PATCH] grub2-btrfs-03-follow_default |
|
|
|
--- |
|
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 ad1b56b716d..113c1f746c9 100644 |
|
--- a/grub-core/fs/btrfs.c |
|
+++ b/grub-core/fs/btrfs.c |
|
@@ -1256,6 +1256,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) |
|
{ |
|
@@ -1286,11 +1287,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; |
|
@@ -1855,24 +1859,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 |
|
{ |
|
@@ -1883,15 +1902,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) |
|
{ |
|
@@ -1902,7 +1929,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] == '.') |
|
@@ -1933,8 +1962,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; |
|
} |
|
|
|
@@ -2003,7 +2033,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; |
|
@@ -2053,14 +2085,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 |
|
{ |
|
@@ -2716,6 +2760,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)
|
|
|