#include #include #include "fs/littlefs/lfs.h" #include "vfs/vfs.h" #include "errors.h" #include "kprintf.h" #include "dlmalloc/malloc.h" #define CHECK(err) \ do { \ int ok = (err); \ kprintf("ok = %d\n", ok); \ if (ok < 0) goto bad; \ } while(0) int32_t littlefs_read(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off) { spinlock_acquire(&vmp->spinlock); LittleFs *fs = &vmp->fs.littlefs; lfs_file_t file; CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_RDONLY)); CHECK(lfs_file_seek(&fs->instance, &file, off, LFS_SEEK_SET)); CHECK(lfs_file_read(&fs->instance, &file, buffer + off, n)); CHECK(lfs_file_close(&fs->instance, &file)); spinlock_release(&vmp->spinlock); return E_OK; bad: spinlock_release(&vmp->spinlock); return E_GENERIC_ERROR; } int32_t littlefs_write(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off) { spinlock_acquire(&vmp->spinlock); LittleFs *fs = &vmp->fs.littlefs; lfs_file_t file; CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_WRONLY)); CHECK(lfs_file_seek(&fs->instance, &file, off, LFS_SEEK_SET)); CHECK(lfs_file_write(&fs->instance, &file, buffer, n)); CHECK(lfs_file_close(&fs->instance, &file)); spinlock_release(&vmp->spinlock); return E_OK; bad: spinlock_release(&vmp->spinlock); return E_GENERIC_ERROR; } int32_t littlefs_remove(struct VfsMountPoint *vmp, const char *path) { spinlock_acquire(&vmp->spinlock); LittleFs *fs = &vmp->fs.littlefs; CHECK(lfs_remove(&fs->instance, path)); spinlock_release(&vmp->spinlock); return E_OK; bad: spinlock_release(&vmp->spinlock); return E_GENERIC_ERROR; } int32_t littlefs_cleanup(struct VfsMountPoint *vmp) { dlfree(vmp->fs.littlefs.instance.cfg); int32_t err = vmp->backingsd->cleanup(vmp->backingsd); if (err != E_OK) { return err; } err = lfs_unmount(&vmp->fs.littlefs.instance); if (err < 0) { return E_GENERIC_ERROR; } return E_OK; } int32_t littlefs_create(struct VfsMountPoint *vmp, const char *path, int32_t type) { spinlock_acquire(&vmp->spinlock); LittleFs *fs = &vmp->fs.littlefs; switch (type) { case VFS_CREATE_DIR: CHECK(lfs_mkdir(&fs->instance, path)); break; case VFS_CREATE_FILE: { lfs_file_t file; CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_CREAT | LFS_O_WRONLY)); CHECK(lfs_file_close(&fs->instance, &file)); } break; } spinlock_release(&vmp->spinlock); return E_OK; bad: spinlock_release(&vmp->spinlock); return E_GENERIC_ERROR; } bool littlefs_check(void) { return true; } int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { VfsMountPoint *vmp = c->context; vmp->backingsd->read(vmp->backingsd, buffer, size, block * LITTLEFS_BLOCK_SIZE + off); return 0; } int portlfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { VfsMountPoint *vmp = c->context; vmp->backingsd->write(vmp->backingsd, buffer, size, block * LITTLEFS_BLOCK_SIZE + off); return 0; } int portlfs_erase(const struct lfs_config *c, lfs_block_t block) { (void)c; (void)block; return 0; } int portlfs_sync(const struct lfs_config *c) { (void)c; return 0; }