Fetching directory entries
This commit is contained in:
@ -160,6 +160,52 @@ struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32
|
|||||||
return vobj;
|
return vobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, IoctlDirent *direntbuf, size_t idx) {
|
||||||
|
size_t i = 0;
|
||||||
|
struct lfs_info statinfo;
|
||||||
|
int ok;
|
||||||
|
|
||||||
|
spinlock_acquire(&vmp->spinlock);
|
||||||
|
|
||||||
|
ok = lfs_stat(&vmp->fs.littlefs.instance, path, &statinfo);
|
||||||
|
if (ok < 0) {
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statinfo.type != LFS_TYPE_DIR) {
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
lfs_dir_t dir;
|
||||||
|
ok = lfs_dir_open(&vmp->fs.littlefs.instance, &dir, path);
|
||||||
|
if (ok < 0) {
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lfs_info entinfo;
|
||||||
|
while (lfs_dir_read(&vmp->fs.littlefs.instance, &dir, &entinfo) > 0) {
|
||||||
|
if (i == idx) {
|
||||||
|
if (entinfo.type == LFS_TYPE_REG) {
|
||||||
|
direntbuf->stat.type = IOCTLSTAT_FILE;
|
||||||
|
direntbuf->stat.size = entinfo.size;
|
||||||
|
} else if (entinfo.type == LFS_TYPE_DIR) {
|
||||||
|
direntbuf->stat.type = IOCTLSTAT_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
hal_memcpy(direntbuf->name, entinfo.name, sizeof(direntbuf->name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lfs_dir_close(&vmp->fs.littlefs.instance, &dir);
|
||||||
|
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
}
|
||||||
|
|
||||||
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {
|
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;
|
VfsMountPoint *vmp = c->context;
|
||||||
vmp->backingsd->read(vmp->backingsd, buffer, size, block * LITTLEFS_BLOCK_SIZE + off);
|
vmp->backingsd->read(vmp->backingsd, buffer, size, block * LITTLEFS_BLOCK_SIZE + off);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "fs/littlefs/lfs.h"
|
#include "fs/littlefs/lfs.h"
|
||||||
|
#include "sysdefs/ioctl.h"
|
||||||
|
|
||||||
#define LITTLEFS_BLOCK_SIZE 4096
|
#define LITTLEFS_BLOCK_SIZE 4096
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ typedef struct {
|
|||||||
int32_t littlefs_cleanup(struct VfsMountPoint *vmp);
|
int32_t littlefs_cleanup(struct VfsMountPoint *vmp);
|
||||||
struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
|
struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
|
||||||
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, struct VfsStat *statbuf);
|
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, struct VfsStat *statbuf);
|
||||||
|
int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, IoctlDirent *direntbuf, size_t idx);
|
||||||
|
|
||||||
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);
|
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);
|
||||||
int portlfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size);
|
int portlfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size);
|
||||||
|
@ -161,6 +161,29 @@ int32_t SYSCALL5(sys_ioctl, ioh1, cmd1, arg1, arg2, arg3) {
|
|||||||
iostat->size = stat1.size;
|
iostat->size = stat1.size;
|
||||||
iostat->type = stat1.type;
|
iostat->type = stat1.type;
|
||||||
} break;
|
} break;
|
||||||
|
case IOCTL_FETCHDIRENT: {
|
||||||
|
const char *opath = (const char *)arg1;
|
||||||
|
|
||||||
|
if (opath == NULL) {
|
||||||
|
ret = E_INVALIDARGUMENT;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
IoctlDirent *direntbuf = (IoctlDirent *)arg2;
|
||||||
|
if (direntbuf == NULL) {
|
||||||
|
ret = E_INVALIDARGUMENT;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = (size_t)arg3;
|
||||||
|
|
||||||
|
char mp[IOCTL_MP_MAX];
|
||||||
|
char path[IOCTL_PATH_MAX];
|
||||||
|
|
||||||
|
path_parse(opath, mp, path);
|
||||||
|
|
||||||
|
ret = vfs_fetchdirent(mp, path, direntbuf, idx);
|
||||||
|
} break;
|
||||||
default: {
|
default: {
|
||||||
ret = E_INVALIDARGUMENT;
|
ret = E_INVALIDARGUMENT;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -47,6 +47,7 @@ void vfs_init_littlefs(VfsMountPoint *mp, bool format) {
|
|||||||
mp->cleanup = &littlefs_cleanup;
|
mp->cleanup = &littlefs_cleanup;
|
||||||
mp->open = &littlefs_open;
|
mp->open = &littlefs_open;
|
||||||
mp->stat = &littlefs_stat;
|
mp->stat = &littlefs_stat;
|
||||||
|
mp->fetchdirent = &littlefs_fetchdirent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t vfs_stat(char *mountpoint, const char *path, VfsStat *stat) {
|
int32_t vfs_stat(char *mountpoint, const char *path, VfsStat *stat) {
|
||||||
@ -63,6 +64,20 @@ int32_t vfs_stat(char *mountpoint, const char *path, VfsStat *stat) {
|
|||||||
return mp->stat(mp, path, stat);
|
return mp->stat(mp, path, stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t vfs_fetchdirent(char *mountpoint, const char *path, IoctlDirent *direntbuf, size_t idx) {
|
||||||
|
VfsMountPoint *mp = NULL;
|
||||||
|
|
||||||
|
spinlock_acquire(&VFS_TABLE.spinlock);
|
||||||
|
HSHTB_GET(&VFS_TABLE, mountpoints, mountpoint, label, mp);
|
||||||
|
spinlock_release(&VFS_TABLE.spinlock);
|
||||||
|
|
||||||
|
if (mp == NULL) {
|
||||||
|
return E_NOENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mp->fetchdirent(mp, path, direntbuf, idx);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t vfs_mount(char *mountpoint, int32_t fstype, StoreDev *backingsd, bool format) {
|
int32_t vfs_mount(char *mountpoint, int32_t fstype, StoreDev *backingsd, bool format) {
|
||||||
VfsMountPoint *mp = NULL;
|
VfsMountPoint *mp = NULL;
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "spinlock/spinlock.h"
|
#include "spinlock/spinlock.h"
|
||||||
#include "fs/portlfs/portlfs.h"
|
#include "fs/portlfs/portlfs.h"
|
||||||
#include "storedev/storedev.h"
|
#include "storedev/storedev.h"
|
||||||
|
#include "sysdefs/ioctl.h"
|
||||||
|
|
||||||
#define VFS_MOUNTPOINT_LABEL_MAX 128
|
#define VFS_MOUNTPOINT_LABEL_MAX 128
|
||||||
#define VFS_MOUNTPOINTS_MAX 30
|
#define VFS_MOUNTPOINTS_MAX 30
|
||||||
@ -58,6 +59,7 @@ typedef struct VfsMountPoint {
|
|||||||
VfsObj *(*open)(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
|
VfsObj *(*open)(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
|
||||||
int32_t (*cleanup)(struct VfsMountPoint *vmp);
|
int32_t (*cleanup)(struct VfsMountPoint *vmp);
|
||||||
int32_t (*stat)(struct VfsMountPoint *vmp, const char *path, struct VfsStat *statbuf);
|
int32_t (*stat)(struct VfsMountPoint *vmp, const char *path, struct VfsStat *statbuf);
|
||||||
|
int32_t (*fetchdirent)(struct VfsMountPoint *vmp, const char *path, IoctlDirent *direntbuf, size_t idx);
|
||||||
|
|
||||||
union {
|
union {
|
||||||
LittleFs littlefs;
|
LittleFs littlefs;
|
||||||
@ -78,5 +80,6 @@ int32_t vfs_mount(char *mountpoint, int32_t fstype, StoreDev *backingsd, bool fo
|
|||||||
void vfs_close(VfsObj *vobj);
|
void vfs_close(VfsObj *vobj);
|
||||||
VfsObj *vfs_open(char *mountpoint, const char *path, uint32_t flags);
|
VfsObj *vfs_open(char *mountpoint, const char *path, uint32_t flags);
|
||||||
int32_t vfs_stat(char *mountpoint, const char *path, VfsStat *stat);
|
int32_t vfs_stat(char *mountpoint, const char *path, VfsStat *stat);
|
||||||
|
int32_t vfs_fetchdirent(char *mountpoint, const char *path, IoctlDirent *direntbuf, size_t idx);
|
||||||
|
|
||||||
#endif // VFS_VFS_H_
|
#endif // VFS_VFS_H_
|
||||||
|
@ -37,6 +37,23 @@ void fs_fetch(void) {
|
|||||||
ufree(buf);
|
ufree(buf);
|
||||||
ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0);
|
ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0);
|
||||||
} else if (statbuf.type == IOCTLSTAT_DIR) {
|
} else if (statbuf.type == IOCTLSTAT_DIR) {
|
||||||
uprintf("entries = %zu\n", statbuf.size);
|
IoctlDirent *dirents = (IoctlDirent *)umalloc(statbuf.size * sizeof(*dirents));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < statbuf.size; i++) {
|
||||||
|
ioctl(IOCTL_NOHANDLE, IOCTL_FETCHDIRENT, (uint64_t)path, (uint64_t)&dirents[i], i);
|
||||||
|
|
||||||
|
IoctlDirent *dirent = &dirents[i];
|
||||||
|
|
||||||
|
char membuf[20];
|
||||||
|
|
||||||
|
uprintf("%-30s %-15s %-1s",
|
||||||
|
dirent->name,
|
||||||
|
dirent->stat.type == IOCTLSTAT_FILE ? human_size(dirent->stat.size, membuf, 20) : "-",
|
||||||
|
dirent->stat.type == IOCTLSTAT_FILE ? "F" : "D"
|
||||||
|
);
|
||||||
|
uprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ufree(dirents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user