mufs: add support for reading and writing files

tags/0.1.0
S.J.R. van Schaik 7 years ago
parent 845aba61ed
commit 1c736c3324
  1. 1
      Makefile
  2. 7
      include/fs/mufs.h
  3. 143
      source/fs/mufs/file.c

@ -25,6 +25,7 @@ obj-y += source/core/flash.o
obj-y += source/fs/mufs/block.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/tree.o

@ -3,6 +3,7 @@
struct flash_dev;
struct mufs;
struct mufs_dir;
struct mufs_file;
struct mufs_tree {
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);
int mufs_readdir(struct mufs_dir *dir, struct mufs_dirent *dirent);
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);

@ -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…
Cancel
Save