diff --git a/kernel/fs/portlfs/portlfs.c b/kernel/fs/portlfs/portlfs.c index 521f427..fe32166 100644 --- a/kernel/fs/portlfs/portlfs.c +++ b/kernel/fs/portlfs/portlfs.c @@ -107,6 +107,16 @@ int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, IoctlStat *st return E_OK; } +int32_t littlefs_mkdir(struct VfsMountPoint *vmp, const char *path) { + spinlock_acquire(&vmp->spinlock); + int ok = lfs_mkdir(&vmp->fs.littlefs.instance, path); + spinlock_release(&vmp->spinlock); + if (ok < 0) { + return E_BADIO; + } + return E_OK; +} + struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags) { VfsObj *vobj = dlmalloc(sizeof(*vobj)); if (vobj == NULL) { diff --git a/kernel/fs/portlfs/portlfs.h b/kernel/fs/portlfs/portlfs.h index 888318d..10de2ec 100644 --- a/kernel/fs/portlfs/portlfs.h +++ b/kernel/fs/portlfs/portlfs.h @@ -19,6 +19,7 @@ int32_t littlefs_cleanup(struct VfsMountPoint *vmp); struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags); int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, IoctlStat *statbuf); int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, IoctlDirent *direntbuf, size_t idx); +int32_t littlefs_mkdir(struct VfsMountPoint *vmp, const char *path); 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); diff --git a/kernel/syscall/ioctl.c b/kernel/syscall/ioctl.c index 2cd1a50..a474c1c 100644 --- a/kernel/syscall/ioctl.c +++ b/kernel/syscall/ioctl.c @@ -177,6 +177,23 @@ int32_t SYSCALL5(sys_ioctl, ioh1, cmd1, arg1, arg2, arg3) { ret = vfs_fetchdirent(mp, path, direntbuf, idx); } break; + case IOCTL_MKDIR: { + const char *opath = (const char *)arg1; + + if (opath == 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_mkdir(mp, path); + } break; default: { ret = E_INVALIDARGUMENT; goto done; diff --git a/kernel/vfs/vfs.c b/kernel/vfs/vfs.c index 54c4b08..efee9b0 100644 --- a/kernel/vfs/vfs.c +++ b/kernel/vfs/vfs.c @@ -48,6 +48,7 @@ void vfs_init_littlefs(VfsMountPoint *mp, bool format) { mp->open = &littlefs_open; mp->stat = &littlefs_stat; mp->fetchdirent = &littlefs_fetchdirent; + mp->mkdir = &littlefs_mkdir; } int32_t vfs_stat(char *mountpoint, const char *path, IoctlStat *stat) { @@ -64,6 +65,20 @@ int32_t vfs_stat(char *mountpoint, const char *path, IoctlStat *stat) { return mp->stat(mp, path, stat); } +int32_t vfs_mkdir(char *mountpoint, const char *path) { + VfsMountPoint *mp = NULL; + + spinlock_acquire(&VFS_TABLE.spinlock); + HSHTB_GET(VFS_TABLE.mountpoints, label, mountpoint, mp); + spinlock_release(&VFS_TABLE.spinlock); + + if (mp == NULL) { + return E_NOENTRY; + } + + return mp->mkdir(mp, path); +} + int32_t vfs_fetchdirent(char *mountpoint, const char *path, IoctlDirent *direntbuf, size_t idx) { VfsMountPoint *mp = NULL; diff --git a/kernel/vfs/vfs.h b/kernel/vfs/vfs.h index 0ecf271..f58625a 100644 --- a/kernel/vfs/vfs.h +++ b/kernel/vfs/vfs.h @@ -52,6 +52,7 @@ typedef struct VfsMountPoint { int32_t (*cleanup)(struct VfsMountPoint *vmp); int32_t (*stat)(struct VfsMountPoint *vmp, const char *path, IoctlStat *statbuf); int32_t (*fetchdirent)(struct VfsMountPoint *vmp, const char *path, IoctlDirent *direntbuf, size_t idx); + int32_t (*mkdir)(struct VfsMountPoint *vmp, const char *path); union { LittleFs littlefs; @@ -73,5 +74,6 @@ void vfs_close(VfsObj *vobj); VfsObj *vfs_open(char *mountpoint, const char *path, uint32_t flags); int32_t vfs_stat(char *mountpoint, const char *path, IoctlStat *stat); int32_t vfs_fetchdirent(char *mountpoint, const char *path, IoctlDirent *direntbuf, size_t idx); +int32_t vfs_mkdir(char *mountpoint, const char *path); #endif // VFS_VFS_H_ diff --git a/share/sysdefs/ioctl.h b/share/sysdefs/ioctl.h index eba827a..d42d203 100644 --- a/share/sysdefs/ioctl.h +++ b/share/sysdefs/ioctl.h @@ -9,6 +9,7 @@ #define IOCTL_STAT 3 #define IOCTL_WRITE 4 #define IOCTL_FETCHDIRENT 5 +#define IOCTL_MKDIR 6 #define IOCTL_F_READ (1<<0) #define IOCTL_F_WRITE (1<<1)