mufs: add support for path resolution
This commit is contained in:
parent
e18107d2d5
commit
0e9474d377
1 changed files with 103 additions and 24 deletions
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue