mufs: add support for reading and writing files
This commit is contained in:
parent
845aba61ed
commit
1c736c3324
3 changed files with 151 additions and 0 deletions
1
Makefile
1
Makefile
|
@ -25,6 +25,7 @@ obj-y += source/core/flash.o
|
||||||
|
|
||||||
obj-y += source/fs/mufs/block.o
|
obj-y += source/fs/mufs/block.o
|
||||||
obj-y += source/fs/mufs/dir.o
|
obj-y += source/fs/mufs/dir.o
|
||||||
|
obj-y += source/fs/mufs/file.o
|
||||||
obj-y += source/fs/mufs/super.o
|
obj-y += source/fs/mufs/super.o
|
||||||
obj-y += source/fs/mufs/tree.o
|
obj-y += source/fs/mufs/tree.o
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
struct flash_dev;
|
struct flash_dev;
|
||||||
struct mufs;
|
struct mufs;
|
||||||
struct mufs_dir;
|
struct mufs_dir;
|
||||||
|
struct mufs_file;
|
||||||
|
|
||||||
struct mufs_tree {
|
struct mufs_tree {
|
||||||
struct mufs *fs;
|
struct mufs *fs;
|
||||||
|
@ -33,3 +34,9 @@ struct mufs_dir *mufs_opendir(struct mufs *fs, const char *path);
|
||||||
void mufs_closedir(struct mufs_dir *dir);
|
void mufs_closedir(struct mufs_dir *dir);
|
||||||
int mufs_readdir(struct mufs_dir *dir, struct mufs_dirent *dirent);
|
int mufs_readdir(struct mufs_dir *dir, struct mufs_dirent *dirent);
|
||||||
int mufs_mkdir(struct mufs *fs, const char *path);
|
int mufs_mkdir(struct mufs *fs, const char *path);
|
||||||
|
|
||||||
|
int mufs_create(struct mufs *fs, const char *path);
|
||||||
|
struct mufs_file *mufs_open(struct mufs *fs, const char *path);
|
||||||
|
void mufs_close(struct mufs_file *file);
|
||||||
|
size_t mufs_read(struct mufs_file *file, void *data, size_t len);
|
||||||
|
size_t mufs_write(struct mufs_file *file, const void *data, size_t len);
|
||||||
|
|
143
source/fs/mufs/file.c
Normal file
143
source/fs/mufs/file.c
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
#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_file {
|
||||||
|
struct mufs *fs;
|
||||||
|
struct mufs_tree *tree;
|
||||||
|
uint32_t va;
|
||||||
|
};
|
||||||
|
|
||||||
|
int mufs_create(struct mufs *fs, const char *path)
|
||||||
|
{
|
||||||
|
struct mufs_dirent dirent;
|
||||||
|
struct mufs_tree *tree;
|
||||||
|
size_t len;
|
||||||
|
char *s;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
if (!path || *path == '\0')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!(s = mufs_abspath(path)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* TODO: already exists. */
|
||||||
|
if (resolve_path(fs, s)) {
|
||||||
|
free(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(name = strrchr(s, '/'))) {
|
||||||
|
name = s;
|
||||||
|
s = "/";
|
||||||
|
} else {
|
||||||
|
*name++ = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*name == '\0')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!(tree = resolve_path(fs, s)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
len = min(strlen(name), sizeof(dirent.path) - 1);
|
||||||
|
memcpy(dirent.path, name, len);
|
||||||
|
dirent.path[len] = '\0';
|
||||||
|
dirent.type = MUFS_FILE;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mufs_file *mufs_open(struct mufs *fs, const char *path)
|
||||||
|
{
|
||||||
|
struct mufs_file *file;
|
||||||
|
|
||||||
|
if (!(file = malloc(sizeof(*file))))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
file->fs = fs;
|
||||||
|
|
||||||
|
if (!(file->tree = resolve_path(fs, path)))
|
||||||
|
goto err_free_file;
|
||||||
|
|
||||||
|
file->va = 0;
|
||||||
|
|
||||||
|
return file;
|
||||||
|
|
||||||
|
err_free_file:
|
||||||
|
free(file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mufs_close(struct mufs_file *file)
|
||||||
|
{
|
||||||
|
if (!file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
free(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mufs_read(struct mufs_file *file, void *data, size_t len)
|
||||||
|
{
|
||||||
|
size_t ret;
|
||||||
|
|
||||||
|
if (!file || !data || !len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(ret = mufs_tree_read(file->tree, data, file->va, len)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
file->va += ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mufs_write(struct mufs_file *file, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
size_t ret;
|
||||||
|
|
||||||
|
if (!file || !data || !len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(ret = mufs_tree_write(file->tree, (void *)data, file->va, len)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
file->va += ret;
|
||||||
|
|
||||||
|
if (file->tree->file_size <= file->va) {
|
||||||
|
struct mufs_dtree dtree;
|
||||||
|
|
||||||
|
dtree.file_size = file->tree->file_size;
|
||||||
|
dtree.root = file->tree->root;
|
||||||
|
dtree.depth = file->tree->depth;
|
||||||
|
|
||||||
|
if (flash_write(file->fs->dev, file->tree->va, &dtree,
|
||||||
|
sizeof dtree) == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue