summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Borleis <jbe@pengutronix.de>2017-08-15 15:46:31 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2017-09-06 14:01:42 +0200
commit480cde1b22831febacc2a8ab91dfe99d2e5be8e9 (patch)
tree2e4d4cb1298b6ffe9d90000d79f48f25bed87755
parentd79a81736f64eef5d19396ad04ee9391bc384a8e (diff)
downloadbarebox-480cde1b22831febacc2a8ab91dfe99d2e5be8e9.tar.gz
barebox-480cde1b22831febacc2a8ab91dfe99d2e5be8e9.tar.xz
state: keep backward compatibility
Previous 'state' variable set variants do not know and use metadata. The 'direct' storage backend's read function honors this, but not its counterpart the write function. This makes an update of the 'state' variable set impossible. This change makes backward compatibility explicit, else it complains in the read function as well. With some more debug output it helps the developer to do things right. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--common/Kconfig8
-rw-r--r--common/state/backend_bucket_direct.c28
2 files changed, 27 insertions, 9 deletions
diff --git a/common/Kconfig b/common/Kconfig
index bc7cb0fe76..57418cadc6 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -937,6 +937,14 @@ config STATE_CRYPTO
See Documentation/devicetree/bindings/barebox/barebox,state.rst
for more information.
+config STATE_BACKWARD_COMPATIBLE
+ bool "backward compatible 'direct storage backend'"
+ depends on STATE
+ help
+ With this option enabled the 'direct' storage backend keeps backward
+ compatibility with older revisions of the state framework. Newer
+ revisions expect an additional 'meta header' and fail otherwise.
+
config BOOTCHOOSER
bool "bootchooser infrastructure"
depends on !SHELL_NONE
diff --git a/common/state/backend_bucket_direct.c b/common/state/backend_bucket_direct.c
index 4465ed0e41..958696ed94 100644
--- a/common/state/backend_bucket_direct.c
+++ b/common/state/backend_bucket_direct.c
@@ -69,6 +69,11 @@ static int state_backend_bucket_direct_read(struct state_backend_storage_bucket
if (meta.magic == direct_magic) {
read_len = meta.written_length;
} else {
+ if (!IS_ENABLED(CONFIG_STATE_BACKWARD_COMPATIBLE)) {
+ dev_err(direct->dev, "No meta data header found\n");
+ dev_dbg(direct->dev, "Enable backward compatibility or increase stride size\n");
+ return -EINVAL;
+ }
read_len = direct->max_size;
ret = lseek(direct->fd, direct->offset, SEEK_SET);
if (ret < 0) {
@@ -103,21 +108,26 @@ static int state_backend_bucket_direct_write(struct state_backend_storage_bucket
int ret;
struct state_backend_storage_bucket_direct_meta meta;
- if (len > direct->max_size - sizeof(meta))
- return -E2BIG;
-
ret = lseek(direct->fd, direct->offset, SEEK_SET);
if (ret < 0) {
dev_err(direct->dev, "Failed to seek file, %d\n", ret);
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;
+ /* write the meta data only if there is head room */
+ if (len <= direct->max_size - sizeof(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;
+ }
+ } else {
+ if (!IS_ENABLED(CONFIG_STATE_BACKWARD_COMPATIBLE)) {
+ dev_dbg(direct->dev, "Too small stride size: must skip metadata! Increase stride size\n");
+ return -EINVAL;
+ }
}
ret = write_full(direct->fd, buf, len);