diff options
Diffstat (limited to 'common/state')
-rw-r--r-- | common/state/backend_bucket_circular.c | 4 | ||||
-rw-r--r-- | common/state/backend_bucket_direct.c | 22 | ||||
-rw-r--r-- | common/state/backend_format_dtb.c | 4 | ||||
-rw-r--r-- | common/state/backend_format_raw.c | 4 | ||||
-rw-r--r-- | common/state/backend_storage.c | 2 | ||||
-rw-r--r-- | common/state/state.c | 73 | ||||
-rw-r--r-- | common/state/state.h | 16 | ||||
-rw-r--r-- | common/state/state_variables.c | 11 |
8 files changed, 92 insertions, 44 deletions
diff --git a/common/state/backend_bucket_circular.c b/common/state/backend_bucket_circular.c index 735510e0d3..2ac5bf6a82 100644 --- a/common/state/backend_bucket_circular.c +++ b/common/state/backend_bucket_circular.c @@ -62,7 +62,7 @@ struct state_backend_storage_bucket_circular { #endif /* For outputs */ - struct device_d *dev; + struct device *dev; }; /* @@ -456,7 +456,7 @@ static int bucket_circular_is_block_bad(struct state_backend_storage_bucket_circ } #endif -int state_backend_bucket_circular_create(struct device_d *dev, const char *path, +int state_backend_bucket_circular_create(struct device *dev, const char *path, struct state_backend_storage_bucket **bucket, unsigned int eraseblock, ssize_t writesize, diff --git a/common/state/backend_bucket_direct.c b/common/state/backend_bucket_direct.c index 117cdfb46c..03c752d6fe 100644 --- a/common/state/backend_bucket_direct.c +++ b/common/state/backend_bucket_direct.c @@ -29,7 +29,7 @@ struct state_backend_storage_bucket_direct { int fd; - struct device_d *dev; + struct device *dev; }; struct __attribute__((__packed__)) state_backend_storage_bucket_direct_meta { @@ -52,7 +52,7 @@ static int state_backend_bucket_direct_read(struct state_backend_storage_bucket struct state_backend_storage_bucket_direct *direct = get_bucket_direct(bucket); struct state_backend_storage_bucket_direct_meta meta; - uint32_t read_len; + uint32_t read_len, header_len = 0; void *buf; int ret; @@ -72,6 +72,8 @@ static int state_backend_bucket_direct_read(struct state_backend_storage_bucket return -EINVAL; } + + header_len = sizeof(meta); } else { if (meta.magic != ~0 && !!meta.magic) bucket->wrong_magic = 1; @@ -87,12 +89,16 @@ static int state_backend_bucket_direct_read(struct state_backend_storage_bucket -errno); return -errno; } + } buf = xmalloc(read_len); if (!buf) return -ENOMEM; + dev_dbg(direct->dev, "Read state from %lld length %d\n", (long long) direct->offset, + header_len + read_len); + ret = read_full(direct->fd, buf, read_len); if (ret < 0) { dev_err(direct->dev, "Failed to read from file, %d\n", ret); @@ -112,6 +118,7 @@ static int state_backend_bucket_direct_write(struct state_backend_storage_bucket { struct state_backend_storage_bucket_direct *direct = get_bucket_direct(bucket); + size_t header_len = 0; int ret; struct state_backend_storage_bucket_direct_meta meta; @@ -129,6 +136,8 @@ static int state_backend_bucket_direct_write(struct state_backend_storage_bucket dev_err(direct->dev, "Failed to write metadata to file, %d\n", ret); return ret; } + + header_len = sizeof(meta); } else { if (!IS_ENABLED(CONFIG_STATE_BACKWARD_COMPATIBLE)) { dev_dbg(direct->dev, "Too small stride size: must skip metadata! Increase stride size\n"); @@ -148,6 +157,9 @@ static int state_backend_bucket_direct_write(struct state_backend_storage_bucket return ret; } + dev_dbg(direct->dev, "Written state to offset %lld length %zu data length %zu\n", + (long long)direct->offset, len + header_len, len); + return 0; } @@ -162,14 +174,14 @@ static void state_backend_bucket_direct_free(struct free(direct); } -int state_backend_bucket_direct_create(struct device_d *dev, const char *path, +int state_backend_bucket_direct_create(struct device *dev, const char *path, struct state_backend_storage_bucket **bucket, - off_t offset, ssize_t max_size) + off_t offset, ssize_t max_size, bool readonly) { int fd; struct state_backend_storage_bucket_direct *direct; - fd = open(path, O_RDWR); + fd = open(path, readonly ? O_RDONLY : O_RDWR); if (fd < 0) { dev_err(dev, "Failed to open file '%s', %d\n", path, -errno); return -errno; diff --git a/common/state/backend_format_dtb.c b/common/state/backend_format_dtb.c index d0fc948859..b41b896aac 100644 --- a/common/state/backend_format_dtb.c +++ b/common/state/backend_format_dtb.c @@ -28,7 +28,7 @@ struct state_backend_format_dtb { struct device_node *root; /* For outputs */ - struct device_d *dev; + struct device *dev; }; static inline struct state_backend_format_dtb *get_format_dtb(struct @@ -131,7 +131,7 @@ static void state_backend_format_dtb_free(struct state_backend_format *format) } int backend_format_dtb_create(struct state_backend_format **format, - struct device_d *dev) + struct device *dev) { struct state_backend_format_dtb *dtb; diff --git a/common/state/backend_format_raw.c b/common/state/backend_format_raw.c index 7835f977c9..105f7dd444 100644 --- a/common/state/backend_format_raw.c +++ b/common/state/backend_format_raw.c @@ -32,7 +32,7 @@ struct state_backend_format_raw { unsigned int digest_length; /* For outputs */ - struct device_d *dev; + struct device *dev; char *secret_name; int needs_secret; @@ -299,7 +299,7 @@ static int backend_format_raw_init_digest(struct state_backend_format_raw *raw, int backend_format_raw_create(struct state_backend_format **format, struct device_node *node, const char *secret_name, - struct device_d *dev) + struct device *dev) { struct state_backend_format_raw *raw; int ret; diff --git a/common/state/backend_storage.c b/common/state/backend_storage.c index c55d22e37f..df81902bf7 100644 --- a/common/state/backend_storage.c +++ b/common/state/backend_storage.c @@ -332,7 +332,7 @@ static int state_storage_file_buckets_init(struct state_backend_storage *storage offset = storage->offset + n * stridesize; ret = state_backend_bucket_direct_create(storage->dev, storage->path, &bucket, offset, - stridesize); + stridesize, storage->readonly); if (ret) { dev_warn(storage->dev, "Failed to create direct bucket at '%s' offset %lld\n", storage->path, (long long) offset); diff --git a/common/state/state.c b/common/state/state.c index a614c849c7..219309d715 100644 --- a/common/state/state.c +++ b/common/state/state.c @@ -21,8 +21,10 @@ #include <fs.h> #include <crc.h> #include <init.h> +#include <block.h> #include <linux/err.h> #include <linux/list.h> +#include <linux/uuid.h> #include <linux/mtd/mtd-abi.h> #include <malloc.h> @@ -333,8 +335,10 @@ static int state_convert_node_variable(struct state *state, goto out; return 0; - out_free:free(name); - out: return ret; +out_free: + free(name); +out: + return ret; } struct device_node *state_to_node(struct state *state, @@ -361,7 +365,8 @@ struct device_node *state_to_node(struct state *state, } return root; - out: of_delete_node(root); +out: + of_delete_node(root); return ERR_PTR(ret); } @@ -556,12 +561,12 @@ static int of_state_fixup(struct device_node *root, void *ctx) goto out; /* delete existing node */ - if (node) - of_delete_node(node); + of_delete_node(node); return 0; - out: of_delete_node(new_node); +out: + of_delete_node(new_node); return ret; } @@ -578,6 +583,22 @@ void state_release(struct state *state) free(state); } +#ifdef __BAREBOX__ +static char *cdev_to_devpath(struct cdev *cdev, off_t *offset, size_t *size) +{ + /* + * We only accept partitions exactly mapping the barebox-state, + * but dt-utils may need to set non-zero values here + */ + *offset = 0; + *size = 0; + + return basprintf("/dev/%s", cdev->name); +} +#endif + +static guid_t barebox_state_partition_guid = BAREBOX_STATE_PARTITION_GUID; + /* * state_new_from_node - create a new state instance from a device_node * @@ -594,12 +615,13 @@ struct state *state_new_from_node(struct device_node *node, bool readonly) const char *alias; uint32_t stridesize; struct device_node *partition_node; - off_t offset = 0; - size_t size = 0; + struct cdev *cdev; + off_t offset; + size_t size; alias = of_alias_get(node); if (!alias) { - pr_err("State node %s does not have an alias in the /aliases/ node\n", node->full_name); + pr_err("State node %pOF does not have an alias in the /aliases/ node\n", node); return ERR_PTR(-EINVAL); } @@ -614,15 +636,8 @@ struct state *state_new_from_node(struct device_node *node, bool readonly) goto out_release_state; } -#ifdef __BAREBOX__ - 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); -#else - ret = of_get_devicepath(partition_node, &state->backend_path, &offset, &size); -#endif + cdev = of_cdev_find(partition_node); + ret = PTR_ERR_OR_ZERO(cdev); if (ret) { if (ret != -EPROBE_DEFER) dev_err(&state->dev, "state failed to parse path to backend: %s\n", @@ -630,6 +645,22 @@ struct state *state_new_from_node(struct device_node *node, bool readonly) goto out_release_state; } + /* Is the backend referencing an on-disk partitionable block device? */ + if (cdev_is_block_disk(cdev)) { + cdev = cdev_find_child_by_gpt_typeuuid(cdev, &barebox_state_partition_guid); + if (IS_ERR(cdev)) { + ret = -EINVAL; + goto out_release_state; + } + + pr_debug("%pOF: backend GPT partition looked up via PartitionTypeGUID\n", + node); + } + + state->backend_path = cdev_to_devpath(cdev, &offset, &size); + + pr_debug("%pOF: backend resolved to %s\n", node, state->backend_path); + state->backend_reproducible_name = of_get_reproducible_name(partition_node); ret = of_property_read_string(node, "backend-type", &backend_type); @@ -653,14 +684,14 @@ struct state *state_new_from_node(struct device_node *node, bool readonly) if (ret) goto out_release_state; + if (readonly) + state_backend_set_readonly(state); + ret = state_storage_init(state, state->backend_path, offset, size, stridesize, storage_type); if (ret) goto out_release_state; - if (readonly) - state_backend_set_readonly(state); - ret = state_from_node(state, node, 1); if (ret) { goto out_release_state; diff --git a/common/state/state.h b/common/state/state.h index 0545cf6ac1..f0c5b1de41 100644 --- a/common/state/state.h +++ b/common/state/state.h @@ -90,7 +90,7 @@ struct state_backend_storage { struct list_head buckets; /* For outputs */ - struct device_d *dev; + struct device *dev; const char *name; @@ -105,7 +105,7 @@ struct state_backend_storage { struct state { struct list_head list; /* Entry to enqueue on list of states */ - struct device_d dev; + struct device dev; char *of_path; const char *name; uint32_t magic; @@ -202,21 +202,21 @@ struct device_node *state_to_node(struct state *state, enum state_convert conv); int backend_format_raw_create(struct state_backend_format **format, struct device_node *node, const char *secret_name, - struct device_d *dev); + struct device *dev); int backend_format_dtb_create(struct state_backend_format **format, - struct device_d *dev); + struct device *dev); int state_storage_init(struct state *state, const char *path, off_t offset, size_t max_size, uint32_t stridesize, const char *storagetype); void state_storage_set_readonly(struct state_backend_storage *storage); void state_add_var(struct state *state, struct state_variable *var); struct variable_type *state_find_type_by_name(const char *name); -int state_backend_bucket_circular_create(struct device_d *dev, const char *path, +int state_backend_bucket_circular_create(struct device *dev, const char *path, struct state_backend_storage_bucket **bucket, unsigned int eraseblock, ssize_t writesize, struct mtd_info_user *mtd_uinfo); -int state_backend_bucket_cached_create(struct device_d *dev, +int state_backend_bucket_cached_create(struct device *dev, struct state_backend_storage_bucket *raw, struct state_backend_storage_bucket **out); struct state_variable *state_find_var(struct state *state, const char *name); @@ -224,9 +224,9 @@ struct digest *state_backend_format_raw_get_digest(struct state_backend_format *format); void state_backend_set_readonly(struct state *state); void state_storage_free(struct state_backend_storage *storage); -int state_backend_bucket_direct_create(struct device_d *dev, const char *path, +int state_backend_bucket_direct_create(struct device *dev, const char *path, struct state_backend_storage_bucket **bucket, - off_t offset, ssize_t max_size); + off_t offset, ssize_t max_size, bool readonly); int state_storage_write(struct state_backend_storage *storage, const void * buf, ssize_t len); int state_storage_read(struct state_backend_storage *storage, diff --git a/common/state/state_variables.c b/common/state/state_variables.c index f112c60bf6..77946206cd 100644 --- a/common/state/state_variables.c +++ b/common/state/state_variables.c @@ -180,6 +180,8 @@ static int state_enum32_export(struct state_variable *var, str += sprintf(str, "%s", enum32->names[i]) + 1; ret = of_set_property(node, "names", prop, len, 1); + if (ret) + return ret; free(prop); @@ -261,7 +263,8 @@ static struct state_variable *state_enum32_create(struct state *state, } return &enum32->var; - out: for (i--; i >= 0; i--) +out: + for (i--; i >= 0; i--) free((char *)enum32->names[i]); free(enum32->names); free(enum32); @@ -327,7 +330,8 @@ static struct state_variable *state_mac_create(struct state *state, } return &mac->var; - out: free(mac); +out: + free(mac); return ERR_PTR(ret); } @@ -442,7 +446,8 @@ static struct state_variable *state_string_create(struct state *state, } return &string->var; - out: free(string); +out: + free(string); return ERR_PTR(ret); } |