[PATCH 3/3] state: support backend-diskuuid / backend-offset

Michael Olbrich m.olbrich at pengutronix.de
Mon Jan 24 02:04:58 PST 2022


On some platforms (e.g. EFI on x86_64) the state backend can only be
selected by a partiton UUID. On existing devices with a DOS partition
table, there may be no spare partition available for state.

This makes it possible to select the disk via UUID. The exact position is
defined by an explicitly specified offset.

Signed-off-by: Michael Olbrich <m.olbrich at pengutronix.de>
---

I wasn't sure where to add the helper function. Is include/fs.h ok or
should I put it somewhere else?

I'll implement the same helper for dt-utils, so we can avoid additional
#ifdef here.

 common/state/state.c | 55 +++++++++++++++++++++++++++++---------------
 include/fs.h         | 12 ++++++++++
 2 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/common/state/state.c b/common/state/state.c
index 8c34ae83e52b..2a8b12d20c5a 100644
--- a/common/state/state.c
+++ b/common/state/state.c
@@ -592,6 +592,7 @@ struct state *state_new_from_node(struct device_node *node, bool readonly)
 	const char *backend_type;
 	const char *storage_type = NULL;
 	const char *alias;
+	const char *diskuuid;
 	uint32_t stridesize;
 	struct device_node *partition_node;
 	off_t offset = 0;
@@ -607,30 +608,48 @@ struct state *state_new_from_node(struct device_node *node, bool readonly)
 	if (IS_ERR(state))
 		return state;
 
-	partition_node = of_parse_phandle(node, "backend", 0);
-	if (!partition_node) {
-		dev_err(&state->dev, "Cannot resolve \"backend\" phandle\n");
-		ret = -EINVAL;
-		goto out_release_state;
-	}
+	ret = of_property_read_string(node, "backend-diskuuid", &diskuuid);
+	if (ret == 0) {
+		u64 off;
+
+		ret = devpath_from_diskuuid(diskuuid, &state->backend_path);
+		if (ret) {
+			dev_err(&state->dev, "state failed find backend device for diskuuid='%s'\n",
+				diskuuid);
+			goto out_release_state;
+		}
+		ret = of_property_read_u64(node, "backend-offset", &off);
+		if (ret) {
+			dev_err(&state->dev, "'backend-offset' property undefined\n");
+			goto out_release_state;
+		}
+		offset = off;
+	} else {
+		partition_node = of_parse_phandle(node, "backend", 0);
+		if (!partition_node) {
+			dev_err(&state->dev, "Cannot resolve \"backend\" phandle\n");
+			ret = -EINVAL;
+			goto out_release_state;
+		}
 
 #ifdef __BAREBOX__
-	ret = of_partition_ensure_probed(partition_node);
-	if (ret)
-		goto out_release_state;
+		ret = of_partition_ensure_probed(partition_node);
+		if (ret)
+			goto out_release_state;
 
-	ret = of_find_path_by_node(partition_node, &state->backend_path, 0);
+		ret = of_find_path_by_node(partition_node, &state->backend_path, 0);
 #else
-	ret = of_get_devicepath(partition_node, &state->backend_path, &offset, &size);
+		ret = of_get_devicepath(partition_node, &state->backend_path, &offset, &size);
 #endif
-	if (ret) {
-		if (ret != -EPROBE_DEFER)
-			dev_err(&state->dev, "state failed to parse path to backend: %s\n",
-			       strerror(-ret));
-		goto out_release_state;
-	}
+		if (ret) {
+			if (ret != -EPROBE_DEFER)
+				dev_err(&state->dev, "state failed to parse path to backend: %s\n",
+				       strerror(-ret));
+			goto out_release_state;
+		}
 
-	state->backend_reproducible_name = of_get_reproducible_name(partition_node);
+		state->backend_reproducible_name = of_get_reproducible_name(partition_node);
+	}
 
 	ret = of_property_read_string(node, "backend-type", &backend_type);
 	if (ret) {
diff --git a/include/fs.h b/include/fs.h
index cd5eb571e08e..1a2f9c7f8e16 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -177,4 +177,16 @@ static inline const char *devpath_to_name(const char *devpath)
 	return devpath;
 }
 
+static inline int devpath_from_diskuuid(const char *diskuuid, char **devpath)
+{
+	struct cdev *cdev;
+
+	cdev = cdev_by_diskuuid(diskuuid);
+	if (!cdev)
+		return -EINVAL;
+
+	*devpath = xasprintf("/dev/%s", cdev->name);
+	return 0;
+}
+
 #endif /* __FS_H */
-- 
2.30.2




More information about the barebox mailing list