|
|
|
@ -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; |
|
|
|
|
ret = resolve_path(fs, path, &subtree, &stat); |
|
|
|
|
free(path); |
|
|
|
|
|
|
|
|
|
if (ret < 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
type = stat.type; |
|
|
|
|
free(path); |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|