mufs: add support for path resolution

This commit is contained in:
S.J.R. van Schaik 2017-06-09 16:29:37 +02:00
parent e18107d2d5
commit 0e9474d377

View file

@ -17,18 +17,7 @@ struct mufs_dir {
uint32_t va;
};
static int resolve(struct mufs *fs, struct mufs_tree *tree, const char *path)
{
if (!path || *path == '\0') {
memcpy(tree, &fs->root, sizeof *tree);
return 0;
}
/* TODO: resolve directories. */
return -1;
}
struct mufs_dir *mufs_opendir(struct mufs *fs, const char *path)
static struct mufs_dir *mufs_opendir2(struct mufs *fs, struct mufs_dirent *entry)
{
struct mufs_dir *dir;
@ -36,13 +25,101 @@ struct mufs_dir *mufs_opendir(struct mufs *fs, const char *path)
return NULL;
dir->fs = fs;
dir->va = 0;
if (entry) {
if (!(dir->tree = malloc(sizeof *dir->tree)))
goto err_free_dir;
memcpy(dir->tree, &entry->tree, sizeof *dir->tree);
} else {
dir->tree = &fs->root;
}
return dir;
err_free_dir:
free(dir);
return NULL;
}
static struct mufs_tree *resolve_path(struct mufs *fs, const char *path)
{
struct mufs_dir *dir;
struct mufs_dirent entry;
struct mufs_tree *tree;
char *s, *p, *end;
int ret;
if (!path || *path == '\0')
return NULL;
while (*path == '/')
++path;
if (*path == '\0')
return &fs->root;
if (!(s = strdup(path)))
return NULL;
if (!(dir = mufs_opendir2(fs, NULL)))
goto err_free_s;
for (p = s; *p != '\0'; p = end) {
end = p + strcspn(p, "/");
while (*end == '/')
*end++ = '\0';
while ((ret = mufs_readdir(dir, &entry)) == 0) {
if (strcmp(entry.path, p) != 0)
continue;
mufs_closedir(dir);
if (!(dir = mufs_opendir2(fs, &entry)))
goto err_free_s;
break;
}
if (ret < 0)
goto err_close_dir;
}
tree = dir->tree;
mufs_closedir(dir);
return tree;
err_close_dir:
mufs_closedir(dir);
err_free_s:
free(s);
return NULL;
}
struct mufs_dir *mufs_opendir(struct mufs *fs, const char *path)
{
struct mufs_dir *dir;
if (!(dir = malloc(sizeof(*dir))))
return NULL;
dir->fs = fs;
if (!(dir->tree = resolve_path(fs, path)))
goto err_free_dir;
/* TODO: resolve path */
(void)path;
memcpy(&dir->tree, &fs->root, sizeof dir->tree);
dir->va = 0;
return dir;
err_free_dir:
free(dir);
return NULL;
}
void mufs_closedir(struct mufs_dir *dir)
@ -87,7 +164,8 @@ static size_t read_dirent(struct mufs *fs, struct mufs_tree *tree,
struct flash_dev *dev = fs->dev;
if (mufs_lookup_page(tree, &dirent->tree.va, base & ~((UINT32_C(1) << dev->log2_block_size) - 1)) < 0)
if (mufs_lookup_page(tree, &dirent->tree.va,
base & ~((UINT32_C(1) << dev->log2_block_size) - 1)) < 0)
return 0;
dirent->tree.fs = fs;
@ -130,8 +208,6 @@ static size_t write_dirent(struct mufs_tree *tree,
dtree.root = tree->root;
dtree.depth = tree->depth;
printf("tree->va=%u\n", tree->va);
if (flash_write(tree->fs->dev, tree->va, &dtree, sizeof dtree) == 0)
return 0;
@ -157,14 +233,13 @@ int mufs_readdir(struct mufs_dir *dir, struct mufs_dirent *dirent)
return 0;
}
printf("return?\n");
return -1;
}
int mufs_mkdir(struct mufs *fs, const char *path)
{
struct mufs_dirent dirent;
struct mufs_tree tree;
struct mufs_tree *tree;
size_t len;
char *s;
char *name;
@ -172,6 +247,10 @@ int mufs_mkdir(struct mufs *fs, const char *path)
if (!path)
return -1;
/* TODO: already exists. */
if (resolve_path(fs, path))
return 0;
if (!(s = strdup(path)))
return -1;
@ -185,7 +264,7 @@ int mufs_mkdir(struct mufs *fs, const char *path)
if (*name == '\0')
return -1;
if (resolve(fs, &tree, s) < 0)
if (!(tree = resolve_path(fs, s)))
return -1;
len = min(strlen(name), sizeof(dirent.path) - 1);
@ -198,11 +277,11 @@ int mufs_mkdir(struct mufs *fs, const char *path)
dirent.tree.root = 0;
dirent.tree.depth = 0;
if (!is_aligned(tree.file_size, fs->dev->log2_block_size) &&
write_dirent(&tree, tree.file_size, &dirent) > 0)
if (!is_aligned(tree->file_size, fs->dev->log2_block_size) &&
write_dirent(tree, tree->file_size, &dirent) > 0)
return 0;
if (write_dirent(&tree, align_up(tree.file_size,
if (write_dirent(tree, align_up(tree->file_size,
fs->dev->log2_block_size), &dirent) > 0)
return 0;