mufs: return tree as an argument in resolve_path() and free tree objects where necessary

This commit is contained in:
S.J.R. van Schaik 2017-06-14 12:47:25 +02:00
parent 4ed40e75c6
commit 59a71a4608
4 changed files with 79 additions and 53 deletions

View file

@ -19,15 +19,16 @@ int mufs_mkpath(struct mufs *fs, const char *path, struct mufs_tree *subtree,
struct mufs_stat stat;
struct mufs_dirent dirent;
struct mufs_tree *tree;
size_t len;
char *s;
char *name;
size_t len;
int ret;
if (!(s = mufs_abspath(path)))
return -1;
/* TODO: already exists. */
if (resolve_path(fs, s, NULL)) {
if (resolve_path(fs, s, NULL, NULL) == 0) {
free(s);
return 0;
}
@ -41,7 +42,7 @@ int mufs_mkpath(struct mufs *fs, const char *path, struct mufs_tree *subtree,
if (*name == '\0')
return -1;
if (!(tree = resolve_path(fs, s, &stat)) || stat.type != MUFS_DIR)
if (resolve_path(fs, s, &tree, &stat) < 0 || stat.type != MUFS_DIR)
return -1;
memset(&dirent, 0, sizeof dirent);
@ -62,14 +63,16 @@ int mufs_mkpath(struct mufs *fs, const char *path, struct mufs_tree *subtree,
tree->file_size = find_dirent_size(fs, tree, tree->file_size);
if (!is_aligned(tree->file_size, fs->dev->log2_block_size) &&
write_dirent(tree, tree->file_size, &dirent) > 0)
write_dirent(tree, tree->file_size, &dirent) > 0) {
mufs_del_tree(tree);
return 0;
}
if (write_dirent(tree, align_up(tree->file_size,
fs->dev->log2_block_size), &dirent) > 0)
return 0;
ret = write_dirent(tree, align_up(tree->file_size,
fs->dev->log2_block_size), &dirent);
mufs_del_tree(tree);
return -1;
return ret;
}
static int remove_page(struct mufs_tree *tree, uint32_t va)
@ -113,11 +116,11 @@ int mufs_rmpath(struct mufs *fs, const char *path)
name = strrchr(s, '/');
*name++ = '\0';
if (!(tree = resolve_path(fs, s, NULL)))
if (resolve_path(fs, s, &tree, NULL) < 0)
goto err_free_s;
if (!(dir = mufs_opendir(fs, s)))
goto err_free_s;
goto err_del_tree;
for (va = dir->va; (ret = mufs_readdir(dir, &ent)) == 0; va = dir->va) {
if (strcmp(ent.path, name) == 0)
@ -127,31 +130,39 @@ int mufs_rmpath(struct mufs *fs, const char *path)
mufs_closedir(dir);
if (ret < 0)
goto err_free_s;
goto err_del_tree;
offset = va & ((UINT32_C(1) << dev->log2_block_size) - 1);
va = align(va, dev->log2_block_size);
if (mufs_tree_read(tree, data, va, 1 << dev->log2_block_size) == 0)
return -1;
goto err_del_tree;
entry = (struct mufs_dentry *)(data + offset);
len = sizeof *entry + entry->path_len;
next = (struct mufs_dentry *)(data + offset + len);
if (!offset && (len == (UINT32_C(1) << dev->log2_block_size) ||
!next->type))
return remove_page(tree, va);
!next->type)) {
ret = remove_page(tree, va);
mufs_del_tree(tree);
free(s);
return ret;
}
memmove(data + offset, data + offset + len,
(UINT32_C(1) << dev->log2_block_size) - offset - len);
if (mufs_tree_write(tree, data, va, 1 << dev->log2_block_size) == 0)
return -1;
goto err_del_tree;
mufs_del_tree(tree);
free(s);
return 0;
err_del_tree:
mufs_del_tree(tree);
err_free_s:
free(s);
return -1;
@ -159,10 +170,7 @@ err_free_s:
int mufs_stat(struct mufs *fs, const char *path, struct mufs_stat *stat)
{
if (!resolve_path(fs, path, stat))
return -1;
return 0;
return resolve_path(fs, path, NULL, stat);
}
int mufs_rename(struct mufs *fs, const char *old, const char *new)
@ -171,25 +179,28 @@ int mufs_rename(struct mufs *fs, const char *old, const char *new)
struct mufs_tree *subtree;
char *path;
unsigned type;
int ret;
if (!(path = mufs_abspath(old)))
return -1;
if (!(subtree = resolve_path(fs, path, &stat)))
goto err_free_path;
type = stat.type;
ret = resolve_path(fs, path, &subtree, &stat);
free(path);
if (ret < 0)
return -1;
type = stat.type;
if (mufs_mkpath(fs, new, subtree, type) < 0)
goto err_free_path;
goto err_del_subtree;
if (mufs_rmpath(fs, old) < 0)
return -1;
goto err_del_subtree;
return 0;
err_free_path:
free(path);
err_del_subtree:
mufs_del_tree(subtree);
return -1;
}