From: Sascha Hauer <s.hauer@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH 03/11] environment: refactor saveenv
Date: Thu, 6 Nov 2014 13:59:30 +0100 [thread overview]
Message-ID: <1415278778-20826-4-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1415278778-20826-1-git-send-email-s.hauer@pengutronix.de>
Collect all files in a list first and iterate over the list
when creating the actual environment image. Makes the next
patches easier.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
common/environment.c | 143 +++++++++++++++++++++++++++------------------------
1 file changed, 75 insertions(+), 68 deletions(-)
diff --git a/common/environment.c b/common/environment.c
index a6cafb0..985adc1 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -41,9 +41,18 @@
#define EXPORT_SYMBOL(x)
#endif
+struct envfs_entry {
+ char *name;
+ void *buf;
+ int size;
+ struct envfs_entry *next;
+ mode_t mode;
+};
+
struct action_data {
const char *base;
void *writep;
+ struct envfs_entry *env;
};
#define PAD4(x) ((x + 3) & ~3)
@@ -71,95 +80,77 @@ static inline int erase(int fd, size_t count, unsigned long offset)
}
#endif
-static int file_size_action(const char *filename, struct stat *statbuf,
+static int file_action(const char *filename, struct stat *statbuf,
void *userdata, int depth)
{
struct action_data *data = userdata;
+ struct envfs_entry *env;
+ int fd, ret;
- data->writep += sizeof(struct envfs_inode);
- data->writep += PAD4(strlen(filename) + 1 - strlen(data->base));
- data->writep += sizeof(struct envfs_inode_end);
- if (S_ISLNK(statbuf->st_mode)) {
- char path[PATH_MAX];
+ env = xzalloc(sizeof(*env));
+ env->name = strdup(filename + strlen(data->base));
+ env->size = statbuf->st_size;
+
+ env->buf = calloc(env->size + 1, 1);
+ if (!env->buf)
+ goto out;
- memset(path, 0, PATH_MAX);
+ env->mode = S_IRWXU | S_IRWXG | S_IRWXO;
- if (readlink(filename, path, PATH_MAX - 1) < 0) {
+ if (S_ISLNK(statbuf->st_mode)) {
+ env->size++;
+
+ ret = readlink(filename, env->buf, env->size);
+ if (ret < 0) {
perror("read");
- return 0;
+ goto out;
}
- data->writep += PAD4(strlen(path) + 1);
+
+ env->mode |= S_IFLNK;
} else {
- data->writep += PAD4(statbuf->st_size);
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return fd;
+
+ ret = read(fd, env->buf, env->size);
+
+ close(fd);
+
+ if (ret < env->size) {
+ perror("read");
+ goto out;
+ }
}
+ env->next = data->env;
+ data->env = env;
+out:
return 1;
}
-static int file_save_action(const char *filename, struct stat *statbuf,
- void *userdata, int depth)
+static void envfs_save_inode(struct action_data *data, struct envfs_entry *env)
{
- struct action_data *data = userdata;
struct envfs_inode *inode;
struct envfs_inode_end *inode_end;
- int fd;
- int namelen = strlen(filename) + 1 - strlen(data->base);
+ int namelen = strlen(env->name) + 1;
inode = data->writep;
inode->magic = ENVFS_32(ENVFS_INODE_MAGIC);
- inode->headerlen = ENVFS_32(PAD4(namelen + sizeof(struct envfs_inode_end)));
+ inode->headerlen = ENVFS_32(PAD4(namelen) + sizeof(struct envfs_inode_end));
+ inode->size = ENVFS_32(env->size);
+
data->writep += sizeof(struct envfs_inode);
- strcpy(data->writep, filename + strlen(data->base));
+ strcpy(data->writep, env->name);
data->writep += PAD4(namelen);
+
inode_end = data->writep;
- data->writep += sizeof(struct envfs_inode_end);
inode_end->magic = ENVFS_32(ENVFS_INODE_END_MAGIC);
- inode_end->mode = ENVFS_32(S_IRWXU | S_IRWXG | S_IRWXO);
-
- if (S_ISLNK(statbuf->st_mode)) {
- char path[PATH_MAX];
- int len;
-
- memset(path, 0, PATH_MAX);
-
- if (readlink(filename, path, PATH_MAX - 1) < 0) {
- perror("read");
- goto out;
- }
- len = strlen(path) + 1;
-
- inode_end->mode |= ENVFS_32(S_IFLNK);
-
- memcpy(data->writep, path, len);
- inode->size = ENVFS_32(len);
- data->writep += PAD4(len);
- debug("handling symlink %s size %d namelen %d headerlen %d\n",
- filename + strlen(data->base),
- len, namelen, ENVFS_32(inode->headerlen));
- } else {
- debug("handling file %s size %lld namelen %d headerlen %d\n",
- filename + strlen(data->base),
- statbuf->st_size, namelen, ENVFS_32(inode->headerlen));
-
- inode->size = ENVFS_32(statbuf->st_size);
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- printf("Open %s %s\n", filename, errno_str());
- goto out;
- }
-
- if (read(fd, data->writep, statbuf->st_size) < statbuf->st_size) {
- perror("read");
- goto out;
- }
- close(fd);
-
- data->writep += PAD4(statbuf->st_size);
- }
+ inode_end->mode = ENVFS_32(env->mode);
+ data->writep += sizeof(struct envfs_inode_end);
-out:
- return 1;
+ memcpy(data->writep, env->buf, env->size);
+ data->writep += PAD4(env->size);
}
/**
@@ -176,8 +167,9 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags)
{
struct envfs_super *super;
int envfd, size, ret;
- struct action_data data;
+ struct action_data data = {};
void *buf = NULL, *wbuf;
+ struct envfs_entry *env;
data.writep = NULL;
data.base = dirname;
@@ -186,10 +178,16 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags)
size = 0; /* force no content */
} else {
/* first pass: calculate size */
- recursive_action(dirname, ACTION_RECURSE, file_size_action,
+ recursive_action(dirname, ACTION_RECURSE, file_action,
NULL, &data, 0);
+ size = 0;
- size = (unsigned long)data.writep;
+ for (env = data.env; env; env = env->next) {
+ size += PAD4(env->size);
+ size += sizeof(struct envfs_inode);
+ size += PAD4(strlen(env->name) + 1);
+ size += sizeof(struct envfs_inode_end);
+ }
}
buf = xzalloc(size + sizeof(struct envfs_super));
@@ -204,8 +202,17 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags)
if (!(flags & ENVFS_FLAGS_FORCE_BUILT_IN)) {
/* second pass: copy files to buffer */
- recursive_action(dirname, ACTION_RECURSE, file_save_action,
- NULL, &data, 0);
+ env = data.env;
+ while (env) {
+ struct envfs_entry *next = env->next;
+
+ envfs_save_inode(&data, env);
+
+ free(env->buf);
+ free(env->name);
+ free(env);
+ env = next;
+ }
}
super->crc = ENVFS_32(crc32(0, buf + sizeof(struct envfs_super), size));
--
2.1.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2014-11-06 13:00 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-06 12:59 non volatile variables and incremental envrironment Sascha Hauer
2014-11-06 12:59 ` [PATCH 01/11] environment: drop unnecessary casts Sascha Hauer
2014-11-06 12:59 ` [PATCH 02/11] environment: remove unused variable Sascha Hauer
2014-11-06 12:59 ` Sascha Hauer [this message]
2014-11-06 12:59 ` [PATCH 04/11] environment: Only save changes to the defaultenv Sascha Hauer
2014-11-06 12:59 ` [PATCH 05/11] magicvar: Add support for dynamically added magicvars Sascha Hauer
2014-11-06 12:59 ` [PATCH 06/11] Add support for non volatile variables Sascha Hauer
2014-11-06 12:59 ` [PATCH 07/11] libfile: Add copy_recursive Sascha Hauer
2014-11-06 12:59 ` [PATCH 08/11] cp: Add recursive copy Sascha Hauer
2014-11-06 12:59 ` [PATCH 09/11] Add defaultenv command Sascha Hauer
2014-11-06 12:59 ` [PATCH 10/11] globalvar: Add support for printing all global variables Sascha Hauer
2014-11-06 12:59 ` [PATCH 11/11] defaultenv-2: Make use of nonvolatile variables Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1415278778-20826-4-git-send-email-s.hauer@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox