diff options
Diffstat (limited to 'common/file-list.c')
-rw-r--r-- | common/file-list.c | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/common/file-list.c b/common/file-list.c index 407b312833..7ecc8d00bb 100644 --- a/common/file-list.c +++ b/common/file-list.c @@ -9,6 +9,7 @@ #include <stringlist.h> #include <linux/err.h> #include <driver.h> +#include <block.h> #define PARSE_DEVICE 0 #define PARSE_NAME 1 @@ -26,8 +27,8 @@ struct file_list_entry *file_list_entry_by_name(struct file_list *files, const c return NULL; } -int file_list_add_entry(struct file_list *files, const char *name, const char *filename, - unsigned long flags) +static int __file_list_add_entry(struct file_list *files, char *name, char *filename, + unsigned long flags) { struct file_list_entry *entry; @@ -37,8 +38,8 @@ int file_list_add_entry(struct file_list *files, const char *name, const char *f entry = xzalloc(sizeof(*entry)); - entry->name = xstrdup(name); - entry->filename = xstrdup(filename); + entry->name = name; + entry->filename = filename; entry->flags = flags; list_add_tail(&entry->list, &files->list); @@ -46,12 +47,41 @@ int file_list_add_entry(struct file_list *files, const char *name, const char *f return 0; } +int file_list_add_entry(struct file_list *files, const char *name, const char *filename, + unsigned long flags) +{ + return __file_list_add_entry(files, xstrdup(name), xstrdup(filename), flags); +} + +int file_list_add_cdev_entry(struct file_list *files, struct cdev *cdev, + unsigned long flags) +{ + return __file_list_add_entry(files, xstrdup(cdev->name), + xasprintf("/dev/%s", cdev->name), flags); +} + +static bool file_list_handle_spec(struct file_list *files, const char *spec) +{ + unsigned count = 0; + bool autoadd; + + autoadd = !strcmp(spec, "auto"); + if (autoadd || !strcmp(spec, "block")) + count += file_list_add_blockdevs(files); + else + return false; + + pr_debug("'%s' spcifier resulted in %u entries\n", spec, count); + return true; +} + static int file_list_parse_one(struct file_list *files, const char *partstr, const char **endstr) { int i = 0, state = PARSE_DEVICE; char filename[PATH_MAX]; char name[PATH_MAX]; unsigned long flags = 0; + bool special = false; memset(filename, 0, sizeof(filename)); memset(name, 0, sizeof(name)); @@ -88,6 +118,9 @@ static int file_list_parse_one(struct file_list *files, const char *partstr, con case 'u': flags |= FILE_LIST_FLAG_UBI; break; + case 'o': + flags |= FILE_LIST_FLAG_OPTIONAL; + break; default: pr_err("Unknown flag '%c'\n", *partstr); return -EINVAL; @@ -99,7 +132,10 @@ static int file_list_parse_one(struct file_list *files, const char *partstr, con partstr++; } - if (state != PARSE_FLAGS) { + if (state == PARSE_DEVICE) + special = file_list_handle_spec(files, filename); + + if (!special && state != PARSE_FLAGS) { pr_err("Missing ')'\n"); return -EINVAL; } @@ -108,12 +144,12 @@ static int file_list_parse_one(struct file_list *files, const char *partstr, con partstr++; *endstr = partstr; - return file_list_add_entry(files, name, filename, flags); + return special ? 0 : file_list_add_entry(files, name, filename, flags); } static const char *flags_to_str(int flags) { - static char str[sizeof "srcu"]; + static char str[sizeof "srcuo"]; char *s = str;; if (flags & FILE_LIST_FLAG_SAFE) @@ -124,22 +160,33 @@ static const char *flags_to_str(int flags) *s++ = 'c'; if (flags & FILE_LIST_FLAG_UBI) *s++ = 'u'; + if (flags & FILE_LIST_FLAG_OPTIONAL) + *s++ = 'o'; *s = '\0'; return str; } -struct file_list *file_list_parse(const char *str) +struct file_list *file_list_new(void) { struct file_list *files; - int ret; - const char *endptr; files = xzalloc(sizeof(*files)); INIT_LIST_HEAD(&files->list); + return files; +} + +struct file_list *file_list_parse(const char *str) +{ + struct file_list *files; + int ret; + const char *endptr; + + files = file_list_new(); + while (*str) { ret = file_list_parse_one(files, str, &endptr); if (ret) { @@ -195,9 +242,7 @@ struct file_list *file_list_dup(struct file_list *old) struct file_list_entry *old_entry; struct file_list *new; - new = xzalloc(sizeof(*new)); - - INIT_LIST_HEAD(&new->list); + new = file_list_new(); list_for_each_entry(old_entry, &old->list, list) { (void)file_list_add_entry(new, old_entry->name, old_entry->filename, |