summaryrefslogtreecommitdiffstats
path: root/common/environment.c
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-08-21 21:47:53 +0800
committerJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-09-05 03:22:14 +0800
commitd3cbc615962c8e96f88d9e74645c5afb441431bb (patch)
tree0c8e74d8cf0044a2205841e4d30f1fbfd38fc4e3 /common/environment.c
parentff3058e3bb5644803cdb7836bbfe11e8c5fbc5db (diff)
downloadbarebox-d3cbc615962c8e96f88d9e74645c5afb441431bb.tar.gz
barebox-d3cbc615962c8e96f88d9e74645c5afb441431bb.tar.xz
envfs: add support of variable inode size
Introduce a struct envfs_inode_end with more data. Today this will just containt the file mode to be able to add the symlink support. But this is compatible with the previous envfs version as they will do not care about the extra as the previous version is just reading the filename and then consume the extra data without using them. Increase the envfs version to 1.0 Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'common/environment.c')
-rw-r--r--common/environment.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/common/environment.c b/common/environment.c
index 8efed978f6..fc5c57e884 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -53,6 +53,7 @@ int file_size_action(const char *filename, struct stat *statbuf,
data->writep += sizeof(struct envfs_inode);
data->writep += PAD4(strlen(filename) + 1 - strlen(data->base));
+ data->writep += sizeof(struct envfs_inode_end);
data->writep += PAD4(statbuf->st_size);
return 1;
}
@@ -62,6 +63,7 @@ int file_save_action(const char *filename, struct stat *statbuf,
{
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);
@@ -70,12 +72,16 @@ int file_save_action(const char *filename, struct stat *statbuf,
inode = (struct envfs_inode*)data->writep;
inode->magic = ENVFS_32(ENVFS_INODE_MAGIC);
- inode->namelen = ENVFS_32(namelen);
+ inode->headerlen = ENVFS_32(PAD4(namelen + sizeof(struct envfs_inode_end)));
inode->size = ENVFS_32(statbuf->st_size);
data->writep += sizeof(struct envfs_inode);
strcpy(data->writep, filename + strlen(data->base));
data->writep += PAD4(namelen);
+ inode_end = (struct envfs_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);
fd = open(filename, O_RDONLY);
if (fd < 0) {
@@ -176,8 +182,13 @@ int envfs_load(char *filename, char *dir)
int envfd;
int fd, ret = 0;
char *str, *tmp;
- int namelen_full;
+ int headerlen_full;
unsigned long size;
+ /* for envfs < 1.0 */
+ struct envfs_inode_end inode_end_dummy;
+
+ inode_end_dummy.mode = ENVFS_32(S_IRWXU | S_IRWXG | S_IRWXO);
+ inode_end_dummy.magic = ENVFS_32(ENVFS_INODE_END_MAGIC);
envfd = open(filename, O_RDONLY);
if (envfd < 0) {
@@ -223,11 +234,18 @@ int envfs_load(char *filename, char *dir)
goto out;
}
+ if (super.major < ENVFS_MAJOR)
+ printf("envfs version %d.%d loaded into %d.%d\n",
+ super.major, super.minor,
+ ENVFS_MAJOR, ENVFS_MINOR);
+
while (size) {
struct envfs_inode *inode;
- uint32_t inode_size, inode_namelen;
+ struct envfs_inode_end *inode_end;
+ uint32_t inode_size, inode_headerlen, namelen;
inode = (struct envfs_inode *)buf;
+ buf += sizeof(struct envfs_inode);
if (ENVFS_32(inode->magic) != ENVFS_INODE_MAGIC) {
printf("envfs: wrong magic on %s\n", filename);
@@ -235,16 +253,30 @@ int envfs_load(char *filename, char *dir)
goto out;
}
inode_size = ENVFS_32(inode->size);
- inode_namelen = ENVFS_32(inode->namelen);
+ inode_headerlen = ENVFS_32(inode->headerlen);
+ namelen = strlen(inode->data) + 1;
+ if (super.major < 1)
+ inode_end = &inode_end_dummy;
+ else
+ inode_end = (struct envfs_inode_end *)(buf + PAD4(namelen));
- debug("loading %s size %d namelen %d\n", inode->data,
- inode_size, inode_namelen);
+ debug("loading %s size %d namelen %d headerlen %d\n", inode->data,
+ inode_size, namelen, inode_headerlen);
str = concat_path_file(dir, inode->data);
tmp = strdup(str);
make_directory(dirname(tmp));
free(tmp);
+ headerlen_full = PAD4(inode_headerlen);
+ buf += headerlen_full;
+
+ if (ENVFS_32(inode_end->magic) != ENVFS_INODE_END_MAGIC) {
+ printf("envfs: wrong inode_end_magic on %s\n", filename);
+ ret = -EIO;
+ goto out;
+ }
+
fd = open(str, O_WRONLY | O_CREAT | O_TRUNC, 0644);
free(str);
if (fd < 0) {
@@ -253,9 +285,7 @@ int envfs_load(char *filename, char *dir)
goto out;
}
- namelen_full = PAD4(inode_namelen);
- ret = write(fd, buf + namelen_full + sizeof(struct envfs_inode),
- inode_size);
+ ret = write(fd, buf, inode_size);
if (ret < inode_size) {
perror("write");
ret = -errno;
@@ -264,9 +294,8 @@ int envfs_load(char *filename, char *dir)
}
close(fd);
- buf += PAD4(inode_namelen) + PAD4(inode_size) +
- sizeof(struct envfs_inode);
- size -= PAD4(inode_namelen) + PAD4(inode_size) +
+ buf += PAD4(inode_size);
+ size -= headerlen_full + PAD4(inode_size) +
sizeof(struct envfs_inode);
}