vfs Rewrite IOCTL_STAT so that it doesnt require an already open handle
This commit is contained in:
@ -72,25 +72,38 @@ int32_t littlefs_vobj_write(struct VfsObj *vobj, const uint8_t *const buffer, si
|
|||||||
return E_OK;
|
return E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t littlefs_vobj_stat(struct VfsObj *vobj, struct VfsStat *stat) {
|
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, struct VfsStat *statbuf) {
|
||||||
struct lfs_info statbuf;
|
struct lfs_info info;
|
||||||
|
|
||||||
spinlock_acquire(&vobj->spinlock);
|
spinlock_acquire(&vmp->spinlock);
|
||||||
|
|
||||||
int ok = lfs_stat(&vobj->vmp->fs.littlefs.instance, vobj->path, &statbuf);
|
int ok = lfs_stat(&vmp->fs.littlefs.instance, path, &info);
|
||||||
if (ok < 0) {
|
if (ok < 0) {
|
||||||
spinlock_release(&vobj->spinlock);
|
spinlock_release(&vmp->spinlock);
|
||||||
return E_BADIO;
|
return E_BADIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statbuf.type == LFS_TYPE_REG) {
|
if (info.type == LFS_TYPE_REG) {
|
||||||
stat->type = VFS_TYPE_FILE;
|
statbuf->type = VFS_TYPE_FILE;
|
||||||
} else if (statbuf.type == LFS_TYPE_DIR) {
|
statbuf->size = info.size;
|
||||||
stat->type = VFS_TYPE_DIR;
|
} else if (info.type == LFS_TYPE_DIR) {
|
||||||
|
statbuf->type = VFS_TYPE_DIR;
|
||||||
|
statbuf->size = 0;
|
||||||
|
// TODO: find a better way than this... !!!
|
||||||
|
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 info2;
|
||||||
|
while (lfs_dir_read(&vmp->fs.littlefs.instance, &dir, &info2) > 0) {
|
||||||
|
statbuf->size++;
|
||||||
|
}
|
||||||
|
lfs_dir_close(&vmp->fs.littlefs.instance, &dir);
|
||||||
}
|
}
|
||||||
stat->size = statbuf.size;
|
|
||||||
|
|
||||||
spinlock_release(&vobj->spinlock);
|
spinlock_release(&vmp->spinlock);
|
||||||
return E_OK;
|
return E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +153,6 @@ struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32
|
|||||||
vobj->vmp = vmp;
|
vobj->vmp = vmp;
|
||||||
vobj->cleanup = &littlefs_vobj_cleanup;
|
vobj->cleanup = &littlefs_vobj_cleanup;
|
||||||
vobj->read = &littlefs_vobj_read;
|
vobj->read = &littlefs_vobj_read;
|
||||||
vobj->stat = &littlefs_vobj_stat;
|
|
||||||
vobj->write = &littlefs_vobj_write;
|
vobj->write = &littlefs_vobj_write;
|
||||||
hal_strcpy(vobj->path, path);
|
hal_strcpy(vobj->path, path);
|
||||||
|
|
||||||
@ -170,3 +182,4 @@ int portlfs_sync(const struct lfs_config *c) {
|
|||||||
(void)c;
|
(void)c;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,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);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -74,19 +74,17 @@ ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Proc *proc_spawnuser(char *mountpoint, char *path) {
|
Proc *proc_spawnuser(char *mountpoint, char *path) {
|
||||||
VfsObj *vobj = vfs_open(mountpoint, path, VFS_FLAG_READ);
|
|
||||||
if (vobj == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
VfsStat stat;
|
VfsStat stat;
|
||||||
if (vobj->stat(vobj, &stat) != E_OK) {
|
if (vfs_stat(mountpoint, path, &stat) != E_OK) {
|
||||||
vfs_close(vobj);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat.type != VFS_TYPE_FILE) {
|
if (stat.type != VFS_TYPE_FILE) {
|
||||||
vfs_close(vobj);
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VfsObj *vobj = vfs_open(mountpoint, path, VFS_FLAG_READ);
|
||||||
|
if (vobj == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,25 +141,20 @@ int32_t SYSCALL5(sys_ioctl, ioh1, cmd1, arg1, arg2, arg3) {
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IoctlStat *iostat = (IoctlStat *)arg1;
|
||||||
|
if (iostat == NULL) {
|
||||||
|
ret = E_INVALIDARGUMENT;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
char mp[IOCTL_MP_MAX];
|
char mp[IOCTL_MP_MAX];
|
||||||
char path[IOCTL_PATH_MAX];
|
char path[IOCTL_PATH_MAX];
|
||||||
|
|
||||||
path_parse(opath, mp, path);
|
path_parse(opath, mp, path);
|
||||||
|
|
||||||
VfsObj *vobj = vfs_open(mp, path, IOCTL_F_READ);
|
|
||||||
if (vobj == NULL) {
|
|
||||||
ret = E_NOENTRY;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
VfsStat stat1;
|
VfsStat stat1;
|
||||||
ret = vobj->stat(vobj, &stat1);
|
ret = vfs_stat(mp, path, &stat1);
|
||||||
|
if (ret != E_OK) {
|
||||||
vfs_close(vobj);
|
|
||||||
|
|
||||||
IoctlStat *iostat = (IoctlStat *)arg1;
|
|
||||||
if (iostat == NULL) {
|
|
||||||
ret = E_INVALIDARGUMENT;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,21 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t vfs_stat(char *mountpoint, const char *path, VfsStat *stat) {
|
||||||
|
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->stat(mp, path, stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -45,7 +45,6 @@ typedef struct VfsObj {
|
|||||||
char path[VFS_PATH_MAX];
|
char path[VFS_PATH_MAX];
|
||||||
int32_t flags;
|
int32_t flags;
|
||||||
int32_t (*read)(struct VfsObj *vobj, uint8_t *const buffer, size_t n, size_t off);
|
int32_t (*read)(struct VfsObj *vobj, uint8_t *const buffer, size_t n, size_t off);
|
||||||
int32_t (*stat)(struct VfsObj *vobj, struct VfsStat *stat);
|
|
||||||
int32_t (*write)(struct VfsObj *vobj, const uint8_t *const buffer, size_t n, size_t off);
|
int32_t (*write)(struct VfsObj *vobj, const uint8_t *const buffer, size_t n, size_t off);
|
||||||
void (*cleanup)(struct VfsObj *vobj);
|
void (*cleanup)(struct VfsObj *vobj);
|
||||||
} VfsObj;
|
} VfsObj;
|
||||||
@ -58,6 +57,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);
|
||||||
|
|
||||||
union {
|
union {
|
||||||
LittleFs littlefs;
|
LittleFs littlefs;
|
||||||
@ -77,5 +77,6 @@ int32_t vfs_unmount(char *mountpoint);
|
|||||||
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);
|
||||||
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);
|
||||||
|
|
||||||
#endif // VFS_VFS_H_
|
#endif // VFS_VFS_H_
|
||||||
|
@ -10,29 +10,33 @@ void fs_fetch(void) {
|
|||||||
|
|
||||||
char *path = *(args()+1);
|
char *path = *(args()+1);
|
||||||
|
|
||||||
|
IoctlStat statbuf; ZERO(&statbuf);
|
||||||
|
if (ioctl(IOCTL_NOHANDLE, IOCTL_STAT, (uint64_t)&statbuf, (uint64_t)path, 0) != E_OK) {
|
||||||
|
uprintf("fs: could not stat %s\n", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statbuf.type == IOCTLSTAT_FILE) {
|
||||||
IOH ioh = ioctl(IOCTL_NOHANDLE, IOCTL_OPENF, (uint64_t)path, IOCTL_F_READ, 0);
|
IOH ioh = ioctl(IOCTL_NOHANDLE, IOCTL_OPENF, (uint64_t)path, IOCTL_F_READ, 0);
|
||||||
if (ioh < 0) {
|
if (ioh < 0) {
|
||||||
uprintf("fs: could not open %s\n", path);
|
uprintf("fs: could not open %s\n", path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IoctlStat statbuf; ZERO(&statbuf);
|
|
||||||
|
|
||||||
ioctl(ioh, IOCTL_STAT, (uint64_t)&statbuf, (uint64_t)path, 0);
|
|
||||||
if (statbuf.type == IOCTLSTAT_FILE) {
|
|
||||||
uint8_t *buf = umalloc(statbuf.size+1);
|
uint8_t *buf = umalloc(statbuf.size+1);
|
||||||
string_memset(buf, 0, statbuf.size+1);
|
string_memset(buf, 0, statbuf.size+1);
|
||||||
|
|
||||||
if (ioctl(ioh, IOCTL_READ, (uint64_t)buf, statbuf.size, 0) < 0) {
|
if (ioctl(ioh, IOCTL_READ, (uint64_t)buf, statbuf.size, 0) < 0) {
|
||||||
uprintf("fs: coult not read %s\n", path);
|
uprintf("fs: coult not read %s\n", path);
|
||||||
ufree(buf);
|
goto donefile;
|
||||||
ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uprintf("%s", buf);
|
uprintf("%s", buf);
|
||||||
|
donefile:
|
||||||
ufree(buf);
|
ufree(buf);
|
||||||
}
|
|
||||||
|
|
||||||
ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0);
|
ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0);
|
||||||
|
} else if (statbuf.type == IOCTLSTAT_DIR) {
|
||||||
|
uprintf("entries = %zu\n", statbuf.size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user