Source code for the Trusted Boot Module.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
tbm-mcu/source/fs/mufs/dir.c

210 lines
4.0 KiB

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <flash.h>
#include <macros.h>
#include <fs/mufs.h>
#include "dir.h"
#include "tree.h"
struct mufs_dir {
struct mufs *fs;
struct mufs_tree *tree;
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)
{
struct mufs_dir *dir;
if (!(dir = malloc(sizeof *dir)))
return NULL;
dir->fs = fs;
/* TODO: resolve path */
(void)path;
memcpy(&dir->tree, &fs->root, sizeof dir->tree);
dir->va = 0;
return dir;
}
void mufs_closedir(struct mufs_dir *dir)
{
if (!dir)
return;
free(dir);
}
static size_t read_dirent(struct mufs *fs, struct mufs_tree *tree,
struct mufs_dirent *dirent, uint32_t va)
{
struct mufs_dentry entry;
size_t ret = 0;
size_t len;
uint32_t base = va;
if (va + sizeof(entry) > tree->file_size)
return 0;
if (mufs_read(tree, &entry, va, sizeof entry) == 0)
return 0;
if (!entry.type)
return 0;
ret += sizeof entry;
va += sizeof entry;
len = min(entry.path_len, sizeof(dirent->path - 1));
if (va + len > tree->file_size)
return 0;
if (mufs_read(tree, dirent->path, va, len) == 0)
return 0;
dirent->path[len] = '\0';
ret += len;
dirent->type = entry.type;
struct flash_dev *dev = fs->dev;
if (mufs_lookup_page(tree, &dirent->tree.va, base & ~((UINT32_C(1) << dev->log2_block_size) - 1)) < 0)
return 0;
dirent->tree.fs = fs;
dirent->tree.va |= base & ((UINT32_C(1) << dev->log2_block_size) - 1);
dirent->tree.file_size = entry.file_size;
dirent->tree.root = entry.root;
dirent->tree.depth = entry.depth;
return ret;
}
struct mufs_dtree {
uint32_t file_size;
uint32_t root;
uint8_t depth;
} __attribute__((packed));
static size_t write_dirent(struct mufs_tree *tree,
uint32_t va, struct mufs_dirent *dirent)
{
struct mufs_dtree dtree;
struct mufs_dentry entry;
entry.type = dirent->type;
entry.file_size = dirent->tree.file_size;
entry.root = dirent->tree.root;
entry.depth = dirent->tree.depth;
entry.path_len = strlen(dirent->path);
if (mufs_write(tree, dirent->path, va + sizeof entry,
entry.path_len) == 0)
return 0;
if (mufs_write(tree, &entry, va, sizeof entry) == 0)
return 0;
tree->file_size = max(tree->file_size, va + sizeof entry + entry.path_len);
dtree.file_size = tree->file_size;
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;
return entry.path_len + sizeof entry;
}
int mufs_readdir(struct mufs_dir *dir, struct mufs_dirent *dirent)
{
size_t ret;
if (!dir || !dirent || dir->va >= dir->tree->file_size)
return -1;
if ((ret = read_dirent(dir->fs, dir->tree, dirent, dir->va)) > 0) {
dir->va += ret;
return 0;
}
dir->va = align_up(dir->va + 1, dir->fs->dev->log2_block_size);
if ((ret = read_dirent(dir->fs, dir->tree, dirent, dir->va)) > 0) {
dir->va += ret;
return 0;
}
printf("return?\n");
return -1;
}
int mufs_mkdir(struct mufs *fs, const char *path)
{
struct mufs_dirent dirent;
struct mufs_tree tree;
size_t len;
char *s;
char *name;
if (!path)
return -1;
if (!(s = strdup(path)))
return -1;
if (!(name = strrchr(s, '/'))) {
name = s;
s = NULL;
} else {
*name++ = '\0';
}
if (*name == '\0')
return -1;
if (resolve(fs, &tree, s) < 0)
return -1;
len = min(strlen(name), sizeof(dirent.path) - 1);
memcpy(dirent.path, name, len);
dirent.path[len] = '\0';
dirent.type = MUFS_DIR;
dirent.tree.fs = fs;
dirent.tree.file_size = 0;
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)
return 0;
if (write_dirent(&tree, align_up(tree.file_size,
fs->dev->log2_block_size), &dirent) > 0)
return 0;
return -1;
}