mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/2] state: add support for pre-mainline state format
@ 2017-09-26 20:58 Uwe Kleine-König
  2017-09-26 20:58 ` [PATCH 1/2] state: new backend format "rawcompat" Uwe Kleine-König
  2017-09-26 20:58 ` [PATCH 2/2] state: storage: direct: skip writing meta data if this makes data fit Uwe Kleine-König
  0 siblings, 2 replies; 3+ messages in thread
From: Uwe Kleine-König @ 2017-09-26 20:58 UTC (permalink / raw)
  To: barebox

Hello,

when the state framework was developed the underlying raw format was
simpler (only one checksum and no length) and no meta data for direct
buckets.

To be able to keep the binary representation with the current state
framework this patch series introduces the old "raw" format as
"rawcompat" and teaches the direct bucket backend to skip writing meta
data in some cases.

Best regards
Uwe

Uwe Kleine-König (2):
  state: new backend format "rawcompat"
  state: storage: direct: skip writing meta data if this makes data fit

 common/state/Makefile                   |   1 +
 common/state/backend_bucket_direct.c    |  23 +++--
 common/state/backend_format_rawcompat.c | 145 ++++++++++++++++++++++++++++++++
 common/state/state.c                    |   3 +
 common/state/state.h                    |   2 +
 5 files changed, 167 insertions(+), 7 deletions(-)
 create mode 100644 common/state/backend_format_rawcompat.c

-- 
2.11.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] state: new backend format "rawcompat"
  2017-09-26 20:58 [PATCH 0/2] state: add support for pre-mainline state format Uwe Kleine-König
@ 2017-09-26 20:58 ` Uwe Kleine-König
  2017-09-26 20:58 ` [PATCH 2/2] state: storage: direct: skip writing meta data if this makes data fit Uwe Kleine-König
  1 sibling, 0 replies; 3+ messages in thread
From: Uwe Kleine-König @ 2017-09-26 20:58 UTC (permalink / raw)
  To: barebox

This is the format that was initially used during development of the
state framework. Some early adopters still stick to this one.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 common/state/Makefile                   |   1 +
 common/state/backend_format_rawcompat.c | 145 ++++++++++++++++++++++++++++++++
 common/state/state.c                    |   3 +
 common/state/state.h                    |   2 +
 4 files changed, 151 insertions(+)
 create mode 100644 common/state/backend_format_rawcompat.c

diff --git a/common/state/Makefile b/common/state/Makefile
index fcf9add52cbe..e4357e9c209a 100644
--- a/common/state/Makefile
+++ b/common/state/Makefile
@@ -2,6 +2,7 @@ obj-y += state.o
 obj-y += state_variables.o
 obj-y += backend_format_dtb.o
 obj-y += backend_format_raw.o
+obj-y += backend_format_rawcompat.o
 obj-y += backend_storage.o
 obj-y += backend_bucket_direct.o
 obj-$(CONFIG_MTD) += backend_bucket_circular.o
diff --git a/common/state/backend_format_rawcompat.c b/common/state/backend_format_rawcompat.c
new file mode 100644
index 000000000000..ffc9b4b0554a
--- /dev/null
+++ b/common/state/backend_format_rawcompat.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2017 Pengutronix, Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <linux/kernel.h>
+#include <malloc.h>
+#include <crc.h>
+#include <asm/unaligned.h>
+
+#include "state.h"
+
+struct state_backend_format_rawcompat {
+	struct state_backend_format format;
+
+	/* For outputs */
+	struct device_d *dev;
+};
+
+static inline struct state_backend_format_rawcompat *get_format_rawcompat(
+		struct state_backend_format *format)
+{
+	return container_of(format, struct state_backend_format_rawcompat, format);
+}
+
+static int backend_format_rawcompat_verify(struct state_backend_format *format,
+					   uint32_t magic, const void *buf,
+					   ssize_t *lenp, enum state_flags flags)
+{
+	uint32_t crc;
+	uint32_t tmp;
+	struct state_backend_format_rawcompat *backend = get_format_rawcompat(format);
+
+	tmp = get_unaligned((uint32_t *)buf);
+	if (magic && magic != tmp) {
+		dev_err(backend->dev,
+			"Error, found invalid magic 0x%08x, should be 0x%08x\n",
+			tmp, magic);
+		return -EINVAL;
+	}
+
+	tmp = get_unaligned((uint32_t *)(buf + *lenp - sizeof(uint32_t)));
+	crc = crc32(0, buf, *lenp - sizeof(uint32_t));
+	if (crc != tmp) {
+		dev_err(backend->dev,
+			"Error, invalid header crc in rawcompat format, calculated 0x%08x, found 0x%08x\n",
+			crc, tmp);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int backend_format_rawcompat_unpack(struct state_backend_format *format,
+					   struct state *state, const void *buf,
+					   ssize_t len)
+{
+	struct state_variable *sv;
+	const void *data;
+	struct state_backend_format_rawcompat *backend = get_format_rawcompat(format);
+
+	data = buf + sizeof(uint32_t);
+
+	list_for_each_entry(sv, &state->variables, list) {
+		if (sv->start + sv->size > len - 8) {
+			dev_err(backend->dev, "State variable ends behind valid data, %s\n",
+				sv->name);
+			continue;
+		}
+		memcpy(sv->raw, data + sv->start, sv->size);
+	}
+
+	return 0;
+}
+
+static int backend_format_rawcompat_pack(struct state_backend_format *format,
+					 struct state *state, void **buf_out,
+					 ssize_t *len_out)
+{
+	struct state_backend_format_rawcompat *backend = get_format_rawcompat(format);
+	void *buf, *data;
+	struct state_variable *sv;
+	uint32_t crc;
+
+	*len_out = 0;
+	list_for_each_entry(sv, &state->variables, list) {
+		if (*len_out < sv->start + sv->size)
+			*len_out = sv->start + sv->size;
+	}
+
+	/* for header and crc */
+	*len_out += 2 * sizeof(uint32_t);
+
+	buf = xzalloc(*len_out);
+
+	put_unaligned_le32(state->magic, buf);
+
+	data = buf + sizeof(uint32_t);
+
+	list_for_each_entry(sv, &state->variables, list) {
+		memcpy(data + sv->start, sv->raw, sv->size);
+	}
+
+	crc = crc32(0, buf, *len_out - sizeof(uint32_t));
+	put_unaligned_le32(crc, buf + *len_out - sizeof(uint32_t));
+
+	*buf_out = buf;
+
+	return 0;
+}
+
+static void backend_format_rawcompat_free(struct state_backend_format *format)
+{
+	struct state_backend_format_rawcompat *backend = get_format_rawcompat(format);
+
+	free(backend);
+}
+
+int backend_format_rawcompat_create(struct state_backend_format **format,
+				    struct device_node *node, struct device_d *dev)
+{
+	struct state_backend_format_rawcompat *rawcompat;
+
+	rawcompat = xzalloc(sizeof(*rawcompat));
+
+	rawcompat->dev = dev;
+
+	rawcompat->format.pack = backend_format_rawcompat_pack;
+	rawcompat->format.unpack = backend_format_rawcompat_unpack;
+	rawcompat->format.verify = backend_format_rawcompat_verify;
+	rawcompat->format.free = backend_format_rawcompat_free;
+	rawcompat->format.name = "rawcompat";
+	*format = &rawcompat->format;
+
+	return 0;
+}
diff --git a/common/state/state.c b/common/state/state.c
index 121ba0c6d34a..c383c529e973 100644
--- a/common/state/state.c
+++ b/common/state/state.c
@@ -124,6 +124,9 @@ static int state_format_init(struct state *state, const char *backend_format,
 	if (!backend_format || !strcmp(backend_format, "raw")) {
 		ret = backend_format_raw_create(&state->format, node,
 						state_name, &state->dev);
+	} else if (!strcmp(backend_format, "rawcompat")) {
+		ret = backend_format_rawcompat_create(&state->format, node,
+						      &state->dev);
 	} else if (!strcmp(backend_format, "dtb")) {
 		ret = backend_format_dtb_create(&state->format, &state->dev);
 	} else {
diff --git a/common/state/state.h b/common/state/state.h
index 81aaec23b62b..587bc11e4501 100644
--- a/common/state/state.h
+++ b/common/state/state.h
@@ -188,6 +188,8 @@ struct device_node *state_to_node(struct state *state,
 int backend_format_raw_create(struct state_backend_format **format,
 			      struct device_node *node, const char *secret_name,
 			      struct device_d *dev);
+int backend_format_rawcompat_create(struct state_backend_format **format,
+				    struct device_node *node, struct device_d *dev);
 int backend_format_dtb_create(struct state_backend_format **format,
 			      struct device_d *dev);
 int state_storage_init(struct state *state, const char *path,
-- 
2.11.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/2] state: storage: direct: skip writing meta data if this makes data fit
  2017-09-26 20:58 [PATCH 0/2] state: add support for pre-mainline state format Uwe Kleine-König
  2017-09-26 20:58 ` [PATCH 1/2] state: new backend format "rawcompat" Uwe Kleine-König
@ 2017-09-26 20:58 ` Uwe Kleine-König
  1 sibling, 0 replies; 3+ messages in thread
From: Uwe Kleine-König @ 2017-09-26 20:58 UTC (permalink / raw)
  To: barebox

When a direct bucket is read it handles missing meta data just fine for
compatibility reasons. This allows to skip writing meta data if that
makes the data small enough to fit in the bucket to be written.

The motivation for this change is that the storage format in
pre-mainline state didn't use meta data and some machines still have to
stick to this format. For these the stride size exactly fits the data
size such that there is no place for additional meta data and so the
data is written in the old format.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 common/state/backend_bucket_direct.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/common/state/backend_bucket_direct.c b/common/state/backend_bucket_direct.c
index 4465ed0e4115..8bf9a945643c 100644
--- a/common/state/backend_bucket_direct.c
+++ b/common/state/backend_bucket_direct.c
@@ -102,8 +102,14 @@ static int state_backend_bucket_direct_write(struct state_backend_storage_bucket
 	    get_bucket_direct(bucket);
 	int ret;
 	struct state_backend_storage_bucket_direct_meta meta;
+	int write_meta = 1;
 
-	if (len > direct->max_size - sizeof(meta))
+	if (len > direct->max_size - sizeof(meta)) {
+		dev_info(direct->dev, "skip writing metadata because of size constraints\n");
+		write_meta = 0;
+	}
+
+	if (len > direct->max_size)
 		return -E2BIG;
 
 	ret = lseek(direct->fd, direct->offset, SEEK_SET);
@@ -112,12 +118,15 @@ static int state_backend_bucket_direct_write(struct state_backend_storage_bucket
 		return ret;
 	}
 
-	meta.magic = direct_magic;
-	meta.written_length = len;
-	ret = write_full(direct->fd, &meta, sizeof(meta));
-	if (ret < 0) {
-		dev_err(direct->dev, "Failed to write metadata to file, %d\n", ret);
-		return ret;
+	if (write_meta) {
+		meta.magic = direct_magic;
+		meta.written_length = len;
+		ret = write_full(direct->fd, &meta, sizeof(meta));
+		if (ret < 0) {
+			dev_err(direct->dev,
+				"Failed to write metadata to file, %d\n", ret);
+			return ret;
+		}
 	}
 
 	ret = write_full(direct->fd, buf, len);
-- 
2.11.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-09-26 20:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-26 20:58 [PATCH 0/2] state: add support for pre-mainline state format Uwe Kleine-König
2017-09-26 20:58 ` [PATCH 1/2] state: new backend format "rawcompat" Uwe Kleine-König
2017-09-26 20:58 ` [PATCH 2/2] state: storage: direct: skip writing meta data if this makes data fit Uwe Kleine-König

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox