diff --git a/configure.ac b/configure.ac index 777f495..d679fa3 100644 --- a/configure.ac +++ b/configure.ac @@ -18,19 +18,18 @@ AC_PROG_SED AC_PROG_MKDIR_P -AC_ARG_ENABLE([logging], - AS_HELP_STRING([--disable-logging], [disable system logging @<:@default=enabled@:>@]), - [], enable_logging=yes) -AS_IF([test "x$enable_logging" = "xyes"], [ - AC_DEFINE(ENABLE_LOGGING, [1], [System logging.]) +AC_ARG_ENABLE([state-backward-compatibility], + AS_HELP_STRING([--enable-state-backward-compatibility], [keep the 'direct' storage backend backward compatible @<:@default=disabled@:>@]), + [], [enable_state_backward_compatibility=no]) +AS_IF([test "x${enable_state_backward_compatibility}" = "xyes"], [ + AC_DEFINE(CONFIG_STATE_BACKWARD_COMPATIBLE, [1], ['direct' storage backend backward compatibility.]) +], [ + AC_DEFINE(CONFIG_STATE_BACKWARD_COMPATIBLE, [0]) ]) -AC_ARG_ENABLE([debug], - AS_HELP_STRING([--enable-debug], [enable debug messages @<:@default=disabled@:>@]), - [], [enable_debug=no]) -AS_IF([test "x$enable_debug" = "xyes"], [ - AC_DEFINE(DEBUG, [1], [Debug messages.]) -]) +AC_DEFINE(CONFIG_MTD, [1], [Statically define to be enabled to harmonize barebox' & dt-utils' code base.]) + +AC_DEFINE(CONFIG_STATE, [1], [Statically define to be enabled to harmonize barebox' & dt-utils' code base.]) AC_CHECK_FUNCS([__secure_getenv secure_getenv]) @@ -53,15 +52,14 @@ $PACKAGE $VERSION ===== - prefix: ${prefix} - sysconfdir: ${sysconfdir} - libdir: ${libdir} - includedir: ${includedir} + prefix: ${prefix} + sysconfdir: ${sysconfdir} + libdir: ${libdir} + includedir: ${includedir} - compiler: ${CC} - cflags: ${CFLAGS} - ldflags: ${LDFLAGS} + compiler: ${CC} + cflags: ${CFLAGS} + ldflags: ${LDFLAGS} - logging: ${enable_logging} - debug: ${enable_debug} + state-backward-compatibility: ${enable_state_backward_compatibility} ]) diff --git a/src/barebox-state.c b/src/barebox-state.c index 946a8db..6b166bf 100644 --- a/src/barebox-state.c +++ b/src/barebox-state.c @@ -439,6 +439,8 @@ exit(0); case OPT_VERSION: printf(PACKAGE_STRING "\n"); + printf("Configured with build-time option '--%s-state-backward-compatibility'.\n", + (CONFIG_STATE_BACKWARD_COMPATIBLE) ? "enable" : "disable"); exit(0); case 'g': sg = xzalloc(sizeof(*sg)); diff --git a/src/barebox-state/backend_bucket_circular.c b/src/barebox-state/backend_bucket_circular.c index f665c3b..735510e 100644 --- a/src/barebox-state/backend_bucket_circular.c +++ b/src/barebox-state/backend_bucket_circular.c @@ -95,6 +95,7 @@ if (ret == -EBADMSG) { ret = mtd_peb_torture(circ->mtd, circ->eraseblock); if (ret == -EIO) { + mtd_peb_mark_bad(circ->mtd, circ->eraseblock); dev_err(circ->dev, "Tortured eraseblock failed and is marked bad now, PEB %u\n", circ->eraseblock); return -EIO; @@ -132,6 +133,7 @@ if (ret == -EBADMSG) { ret = mtd_peb_torture(circ->mtd, circ->eraseblock); if (ret == -EIO) { + mtd_peb_mark_bad(circ->mtd, circ->eraseblock); dev_err(circ->dev, "Tortured eraseblock failed and is marked bad now, PEB %u\n", circ->eraseblock); return -EIO; @@ -162,11 +164,10 @@ offset += (off_t)circ->eraseblock * circ->mtd->erasesize; - ret = lseek(circ->fd, offset, SEEK_SET); - if (ret < 0) { + if (lseek(circ->fd, offset, SEEK_SET) != offset) { dev_err(circ->dev, "Failed to set circular read position to %lld, %d\n", - (long long) offset, ret); - return ret; + (long long) offset, -errno); + return -errno; } dev_dbg(circ->dev, "Read state from %lld length %d\n", (long long) offset, @@ -191,11 +192,10 @@ offset += circ->eraseblock * circ->mtd->erasesize; - ret = lseek(circ->fd, offset, SEEK_SET); - if (ret < 0) { + if (lseek(circ->fd, offset, SEEK_SET) != offset) { dev_err(circ->dev, "Failed to set position for circular write %lld, %d\n", - (long long) offset, ret); - return ret; + (long long) offset, -errno); + return -errno; } ret = write_full(circ->fd, buf, len); diff --git a/src/barebox-state/backend_bucket_direct.c b/src/barebox-state/backend_bucket_direct.c index dc00de0..4522f01 100644 --- a/src/barebox-state/backend_bucket_direct.c +++ b/src/barebox-state/backend_bucket_direct.c @@ -52,14 +52,13 @@ struct state_backend_storage_bucket_direct *direct = get_bucket_direct(bucket); struct state_backend_storage_bucket_direct_meta meta; - ssize_t read_len; + uint32_t read_len; void *buf; int ret; - ret = lseek(direct->fd, direct->offset, SEEK_SET); - if (ret < 0) { - dev_err(direct->dev, "Failed to seek file, %d\n", ret); - return ret; + if (lseek(direct->fd, direct->offset, SEEK_SET) != direct->offset) { + dev_err(direct->dev, "Failed to seek file, %d\n", -errno); + return -errno; } ret = read_full(direct->fd, &meta, sizeof(meta)); if (ret < 0) { @@ -68,14 +67,25 @@ } if (meta.magic == direct_magic) { read_len = meta.written_length; + if (read_len > direct->max_size) { + dev_err(direct->dev, "Wrong length in meta data\n"); + return -EINVAL; + + } } else { if (meta.magic != ~0 && !!meta.magic) bucket->wrong_magic = 1; + 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) { - dev_err(direct->dev, "Failed to seek file, %d\n", ret); - return ret; + if (lseek(direct->fd, direct->offset, SEEK_SET) != + direct->offset) { + dev_err(direct->dev, "Failed to seek file, %d\n", + -errno); + return -errno; } } @@ -105,21 +115,25 @@ 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; + if (lseek(direct->fd, direct->offset, SEEK_SET) != direct->offset) { + dev_err(direct->dev, "Failed to seek file, %d\n", -errno); + return -errno; } - 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); diff --git a/src/barebox-state/backend_storage.c b/src/barebox-state/backend_storage.c index 3879a8d..509427f 100644 --- a/src/barebox-state/backend_storage.c +++ b/src/barebox-state/backend_storage.c @@ -369,7 +369,7 @@ const char *storagetype) { struct state_backend_storage *storage = &state->storage; - int ret; + int ret = -ENODEV; struct mtd_info_user meminfo; INIT_LIST_HEAD(&storage->buckets); @@ -380,7 +380,9 @@ storage->max_size = max_size; storage->path = xstrdup(path); - ret = mtd_get_meminfo(path, &meminfo); + if (IS_ENABLED(CONFIG_MTD)) + ret = mtd_get_meminfo(path, &meminfo); + if (!ret && !(meminfo.flags & MTD_NO_ERASE)) { bool circular; if (!storagetype || !strcmp(storagetype, "circular")) { diff --git a/src/barebox-state/state.c b/src/barebox-state/state.c index e95f91e..f528b3e 100644 --- a/src/barebox-state/state.c +++ b/src/barebox-state/state.c @@ -713,13 +713,6 @@ return NULL; } -int state_get_name(const struct state *state, char const **name) -{ - *name = xstrdup(state->name); - - return 0; -} - int state_read_mac(struct state *state, const char *name, u8 *buf) { struct state_variable *svar; diff --git a/src/state.h b/src/state.h index 132c0c3..d98b781 100644 --- a/src/state.h +++ b/src/state.h @@ -5,23 +5,54 @@ struct state; -int state_backend_dtb_file(struct state *state, const char *of_path, - const char *path); -int state_backend_raw_file(struct state *state, const char *of_path, - const char *path, off_t offset, size_t size); +#if IS_ENABLED(CONFIG_STATE) struct state *state_new_from_node(struct device_node *node, bool readonly); void state_release(struct state *state); struct state *state_by_name(const char *name); struct state *state_by_node(const struct device_node *node); -int state_get_name(const struct state *state, char const **name); -int state_load(struct state *state); int state_load_no_auth(struct state *state); +int state_load(struct state *state); int state_save(struct state *state); void state_info(void); int state_read_mac(struct state *state, const char *name, u8 *buf); +#else /* #if IS_ENABLED(CONFIG_STATE) */ + +static inline struct state *state_new_from_node(struct device_node *node, + bool readonly) +{ + return ERR_PTR(-ENOSYS); +} + +static inline struct state *state_by_name(const char *name) +{ + return NULL; +} + +static inline struct state *state_by_node(const struct device_node *node) +{ + return NULL; +}; + +static inline int state_load(struct state *state) +{ + return -ENOSYS; +} + +static inline int state_save(struct state *state) +{ + return -ENOSYS; +} + +static inline int state_read_mac(struct state *state, const char *name, u8 *buf) +{ + return -ENOSYS; +} + +#endif /* #if IS_ENABLED(CONFIG_STATE) / #else */ + #endif /* __STATE_H */