Support opening, reading and stating files from userlevel
This commit is contained in:
parent
0e44a1a696
commit
39562233bf
@ -8,6 +8,7 @@
|
|||||||
#define EFAULT 0xBAD4
|
#define EFAULT 0xBAD4
|
||||||
#define ENOMEM 0xBAD5
|
#define ENOMEM 0xBAD5
|
||||||
#define ENOENT 0xBAD6
|
#define ENOENT 0xBAD6
|
||||||
|
#define ENOTDIR 0xBAD7
|
||||||
|
|
||||||
#endif /* __ERRNO_H__ */
|
#endif /* __ERRNO_H__ */
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#ifndef __SYSCALL_H__
|
#ifndef __SYSCALL_H__
|
||||||
#define __SYSCALL_H__
|
#define __SYSCALL_H__
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
uint64_t SystemTime();
|
uint64_t SystemTime();
|
||||||
void SystemExit(int status);
|
void SystemExit(int status);
|
||||||
uint64_t SystemGetPID();
|
uint64_t SystemGetPID();
|
||||||
@ -19,6 +21,10 @@ int SystemFlush(uint64_t fd);
|
|||||||
uint64_t SystemOpen(const char *path, uint64_t flags);
|
uint64_t SystemOpen(const char *path, uint64_t flags);
|
||||||
int SystemClose(uint64_t fd);
|
int SystemClose(uint64_t fd);
|
||||||
|
|
||||||
|
// Directory
|
||||||
|
int SystemStat(const char *path, struct stat *sb);
|
||||||
|
int SystemReadDir(uint64_t fd, char *buf, size_t length, uint64_t *offset);
|
||||||
|
|
||||||
// Threads
|
// Threads
|
||||||
int SystemThreadSleep(uint64_t time);
|
int SystemThreadSleep(uint64_t time);
|
||||||
|
|
||||||
|
@ -79,6 +79,18 @@ SystemClose(uint64_t fd)
|
|||||||
return syscall(SYSCALL_CLOSE, fd);
|
return syscall(SYSCALL_CLOSE, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SystemStat(const char *path, struct stat *sb)
|
||||||
|
{
|
||||||
|
return syscall(SYSCALL_STAT, path, sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SystemReadDir(uint64_t fd, char *buf, size_t length, uint64_t *offset)
|
||||||
|
{
|
||||||
|
return syscall(SYSCALL_READDIR, fd, buf, length, offset);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SystemThreadSleep(uint64_t time)
|
SystemThreadSleep(uint64_t time)
|
||||||
{
|
{
|
||||||
|
@ -54,6 +54,7 @@ src_common = [
|
|||||||
"kern/sysctl.c",
|
"kern/sysctl.c",
|
||||||
"kern/thread.c",
|
"kern/thread.c",
|
||||||
"kern/vfs.c",
|
"kern/vfs.c",
|
||||||
|
"kern/vfsuio.c",
|
||||||
"dev/ahci.c",
|
"dev/ahci.c",
|
||||||
"dev/console.c",
|
"dev/console.c",
|
||||||
"dev/pci.c",
|
"dev/pci.c",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <sys/kassert.h>
|
#include <sys/kassert.h>
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
@ -18,7 +19,10 @@ int O2FS_GetRoot(VFS *fs, VNode **dn);
|
|||||||
int O2FS_Lookup(VNode *dn, VNode **fn, const char *name);
|
int O2FS_Lookup(VNode *dn, VNode **fn, const char *name);
|
||||||
int O2FS_Open(VNode *fn);
|
int O2FS_Open(VNode *fn);
|
||||||
int O2FS_Close(VNode *fn);
|
int O2FS_Close(VNode *fn);
|
||||||
|
int O2FS_Stat(VNode *fn, struct stat *statinfo);
|
||||||
int O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len);
|
int O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len);
|
||||||
|
int O2FS_Write(VNode *fn, void *buf, uint64_t off, uint64_t len);
|
||||||
|
int O2FS_ReadDir(VNode *fn, void *buf, uint64_t len, uint64_t *off);
|
||||||
|
|
||||||
static VFSOp O2FSOperations = {
|
static VFSOp O2FSOperations = {
|
||||||
.unmount = O2FS_Unmount,
|
.unmount = O2FS_Unmount,
|
||||||
@ -26,7 +30,10 @@ static VFSOp O2FSOperations = {
|
|||||||
.lookup = O2FS_Lookup,
|
.lookup = O2FS_Lookup,
|
||||||
.open = O2FS_Open,
|
.open = O2FS_Open,
|
||||||
.close = O2FS_Close,
|
.close = O2FS_Close,
|
||||||
|
.stat = O2FS_Stat,
|
||||||
.read = O2FS_Read,
|
.read = O2FS_Read,
|
||||||
|
.write = O2FS_Write,
|
||||||
|
.readdir = O2FS_ReadDir,
|
||||||
};
|
};
|
||||||
|
|
||||||
VFS *
|
VFS *
|
||||||
@ -257,6 +264,23 @@ O2FS_Close(VNode *fn)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
O2FS_Stat(VNode *fn, struct stat *statinfo)
|
||||||
|
{
|
||||||
|
VFS *vfs = fn->vfs;
|
||||||
|
DiskCacheEntry *sbEntry = (DiskCacheEntry *)vfs->fsptr;
|
||||||
|
SuperBlock *sb = sbEntry->buffer;
|
||||||
|
DiskCacheEntry *fileEntry = (DiskCacheEntry *)fn->fsptr;
|
||||||
|
BNode *fileBN = fileEntry->buffer;
|
||||||
|
|
||||||
|
statinfo->st_size = fileBN->size;
|
||||||
|
// XXX: support other fields
|
||||||
|
statinfo->st_blocks = (fileBN->size + sb->blockSize - 1) / sb->blockSize;
|
||||||
|
statinfo->st_blksize = sb->blockSize;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
|
O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
|
||||||
{
|
{
|
||||||
@ -310,3 +334,16 @@ O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
|
|||||||
return readBytes;
|
return readBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
O2FS_Write(VNode *fn, void *buf, uint64_t off, uint64_t len)
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
O2FS_ReadDir(VNode *fn, void *buf, uint64_t len, uint64_t *off)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ typedef struct SuperBlock
|
|||||||
uint64_t blockCount;
|
uint64_t blockCount;
|
||||||
uint64_t blockSize;
|
uint64_t blockSize;
|
||||||
|
|
||||||
|
uint64_t version; /* Snapshot version */
|
||||||
ObjID root; /* Root Tree */
|
ObjID root; /* Root Tree */
|
||||||
|
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
|
18
sys/include/dirent.h
Normal file
18
sys/include/dirent.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
#ifndef __SYS_DIRENT_H__
|
||||||
|
#define __SYS_DIRENT_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define NAME_MAX 256
|
||||||
|
|
||||||
|
struct dirent {
|
||||||
|
ino_t d_ino;
|
||||||
|
uint16_t d_reclen;
|
||||||
|
uint8_t d_type;
|
||||||
|
uint8_t d_namlen;
|
||||||
|
char d_name[NAME_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __SYS_DIRENT_H__ */
|
||||||
|
|
@ -3,6 +3,8 @@
|
|||||||
#define __SYS_HANDLE_H__
|
#define __SYS_HANDLE_H__
|
||||||
|
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
#include <sys/disk.h>
|
||||||
|
#include <sys/vfs.h>
|
||||||
|
|
||||||
struct Handle;
|
struct Handle;
|
||||||
typedef struct Handle Handle;
|
typedef struct Handle Handle;
|
||||||
@ -14,6 +16,7 @@ typedef struct Handle {
|
|||||||
uint64_t fd; // FD Number
|
uint64_t fd; // FD Number
|
||||||
uint64_t type; // Type
|
uint64_t type; // Type
|
||||||
uint64_t threadId; // Thread ID
|
uint64_t threadId; // Thread ID
|
||||||
|
VNode *vnode; // File VNode
|
||||||
TAILQ_ENTRY(Handle) handleList; // Hash table
|
TAILQ_ENTRY(Handle) handleList; // Hash table
|
||||||
int (*read)(Handle *, void *, uint64_t, uint64_t); // Read
|
int (*read)(Handle *, void *, uint64_t, uint64_t); // Read
|
||||||
int (*write)(Handle *, void *, uint64_t, uint64_t); // Write
|
int (*write)(Handle *, void *, uint64_t, uint64_t); // Write
|
||||||
|
17
sys/include/stat.h
Normal file
17
sys/include/stat.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
#ifndef __SYS_STAT_H__
|
||||||
|
#define __SYS_STAT_H__
|
||||||
|
|
||||||
|
struct stat {
|
||||||
|
ino_t st_ino;
|
||||||
|
// mode
|
||||||
|
// uid
|
||||||
|
// gid
|
||||||
|
// timespec st_atim, st_mtim, st_ctim
|
||||||
|
off_t st_size;
|
||||||
|
size_t st_blocks;
|
||||||
|
size_t st_blksize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __SYS_STAT_H__ */
|
||||||
|
|
@ -24,6 +24,8 @@
|
|||||||
#define SYSCALL_MOVE 0x1A
|
#define SYSCALL_MOVE 0x1A
|
||||||
#define SYSCALL_DELETE 0x1B
|
#define SYSCALL_DELETE 0x1B
|
||||||
#define SYSCALL_SETLENGTH 0x1C
|
#define SYSCALL_SETLENGTH 0x1C
|
||||||
|
#define SYSCALL_STAT 0x1D
|
||||||
|
#define SYSCALL_READDIR 0x1E
|
||||||
|
|
||||||
// Threading
|
// Threading
|
||||||
#define SYSCALL_THREADCREATE 0x30
|
#define SYSCALL_THREADCREATE 0x30
|
||||||
|
@ -20,6 +20,8 @@ typedef int64_t ssize_t;
|
|||||||
typedef int64_t off_t;
|
typedef int64_t off_t;
|
||||||
typedef int64_t fpos_t;
|
typedef int64_t fpos_t;
|
||||||
|
|
||||||
|
typedef uint64_t ino_t;
|
||||||
|
|
||||||
#define NULL ((void *)0)
|
#define NULL ((void *)0)
|
||||||
|
|
||||||
#endif /* __SYS_TYPES_H__ */
|
#endif /* __SYS_TYPES_H__ */
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#define __SYS_VFS_H__
|
#define __SYS_VFS_H__
|
||||||
|
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
typedef struct VFSOp VFSOp;
|
typedef struct VFSOp VFSOp;
|
||||||
typedef struct VNode VNode;
|
typedef struct VNode VNode;
|
||||||
@ -40,15 +41,20 @@ typedef struct VFSOp {
|
|||||||
int (*lookup)(VNode *dn, VNode **fn, const char *name);
|
int (*lookup)(VNode *dn, VNode **fn, const char *name);
|
||||||
int (*open)(VNode *fn);
|
int (*open)(VNode *fn);
|
||||||
int (*close)(VNode *fn);
|
int (*close)(VNode *fn);
|
||||||
|
int (*stat)(VNode *fn, struct stat *sb);
|
||||||
int (*read)(VNode *fn, void *buf, uint64_t off, uint64_t len);
|
int (*read)(VNode *fn, void *buf, uint64_t off, uint64_t len);
|
||||||
|
int (*write)(VNode *fn, void *buf, uint64_t off, uint64_t len);
|
||||||
|
int (*readdir)(VNode *fn, void *buf, uint64_t len, uint64_t *off);
|
||||||
} VFSOp;
|
} VFSOp;
|
||||||
|
|
||||||
int VFS_MountRoot(Disk *root);
|
int VFS_MountRoot(Disk *root);
|
||||||
VNode *VFS_Lookup(const char *path);
|
VNode *VFS_Lookup(const char *path);
|
||||||
|
// XXX: Release/Retain
|
||||||
|
int VFS_Stat(const char *path, struct stat *sb);
|
||||||
int VFS_Open(VNode *fn);
|
int VFS_Open(VNode *fn);
|
||||||
int VFS_Close(VNode *fn);
|
int VFS_Close(VNode *fn);
|
||||||
int VFS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len);
|
int VFS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len);
|
||||||
|
int VFS_ReadDir(VNode *fn, void *buf, uint64_t len, uint64_t *off);
|
||||||
|
|
||||||
#endif /* __SYS_VFS_H__ */
|
#endif /* __SYS_VFS_H__ */
|
||||||
|
|
||||||
|
10
sys/include/vfsuio.h
Normal file
10
sys/include/vfsuio.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
#ifndef __SYS_VFSUIO_H__
|
||||||
|
#define __SYS_VFSUIO_H__
|
||||||
|
|
||||||
|
#include <sys/handle.h>
|
||||||
|
|
||||||
|
int VFSUIO_Open(const char *path, Handle **handle);
|
||||||
|
|
||||||
|
#endif /* __SYS_VFSUIO_H__ */
|
||||||
|
|
@ -12,6 +12,7 @@
|
|||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/disk.h>
|
#include <sys/disk.h>
|
||||||
#include <sys/vfs.h>
|
#include <sys/vfs.h>
|
||||||
|
#include <sys/vfsuio.h>
|
||||||
|
|
||||||
Handle *Console_OpenHandle();
|
Handle *Console_OpenHandle();
|
||||||
|
|
||||||
@ -198,10 +199,16 @@ Syscall_Open(uint64_t user_path, uint64_t flags)
|
|||||||
Handle *handle = Console_OpenHandle();
|
Handle *handle = Console_OpenHandle();
|
||||||
return Handle_Add(cur, handle);
|
return Handle_Add(cur, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
NOT_IMPLEMENTED();
|
Handle *handle;
|
||||||
return 0;
|
status = VFSUIO_Open(path, &handle);
|
||||||
|
if (status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return Handle_Add(cur, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
@ -216,6 +223,61 @@ Syscall_Close(uint64_t fd)
|
|||||||
return (handle->close)(handle);
|
return (handle->close)(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
Syscall_Stat(uint64_t user_path, uint64_t user_stat)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
char path[512];
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
|
// XXX: Use CopyInStr
|
||||||
|
status = CopyIn(user_path, &path, sizeof(path));
|
||||||
|
if (status != 0) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VFS_Stat
|
||||||
|
status = VFS_Stat(path, &sb);
|
||||||
|
if (status != 0) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = CopyOut(&sb, user_stat, sizeof(struct stat));
|
||||||
|
if (status != 0) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
Thread *cur = Thread_Current();
|
||||||
|
Handle *handle = Handle_Lookup(cur, fd);
|
||||||
|
uint64_t offset;
|
||||||
|
|
||||||
|
if (handle == NULL)
|
||||||
|
return -EBADF;
|
||||||
|
|
||||||
|
status = CopyIn(user_off, &offset, sizeof(offset));
|
||||||
|
if (status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (handle->type != HANDLE_TYPE_FILE)
|
||||||
|
return -ENOTDIR;
|
||||||
|
status = VFS_ReadDir(handle->vnode, user_buf, len, &offset);
|
||||||
|
if (status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = CopyOut(&offset, user_off, sizeof(offset));
|
||||||
|
if (status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
Syscall_ThreadSleep(uint64_t time)
|
Syscall_ThreadSleep(uint64_t time)
|
||||||
{
|
{
|
||||||
@ -258,6 +320,10 @@ Syscall_Entry(uint64_t syscall, uint64_t a1, uint64_t a2,
|
|||||||
return Syscall_Open(a1, a2);
|
return Syscall_Open(a1, a2);
|
||||||
case SYSCALL_CLOSE:
|
case SYSCALL_CLOSE:
|
||||||
return Syscall_Close(a1);
|
return Syscall_Close(a1);
|
||||||
|
case SYSCALL_STAT:
|
||||||
|
return Syscall_Stat(a1, a2);
|
||||||
|
case SYSCALL_READDIR:
|
||||||
|
return Syscall_ReadDir(a1, a2, a3, a4);
|
||||||
case SYSCALL_THREADSLEEP:
|
case SYSCALL_THREADSLEEP:
|
||||||
return Syscall_ThreadSleep(a1);
|
return Syscall_ThreadSleep(a1);
|
||||||
default:
|
default:
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <sys/kassert.h>
|
#include <sys/kassert.h>
|
||||||
#include <sys/kdebug.h>
|
#include <sys/kdebug.h>
|
||||||
#include <sys/spinlock.h>
|
#include <sys/spinlock.h>
|
||||||
#include <sys/disk.h>
|
#include <sys/disk.h>
|
||||||
#include <sys/vfs.h>
|
#include <sys/vfs.h>
|
||||||
|
#include <sys/handle.h>
|
||||||
|
|
||||||
extern VFS *O2FS_Mount(Disk *root);
|
extern VFS *O2FS_Mount(Disk *root);
|
||||||
|
|
||||||
@ -92,6 +94,18 @@ VFS_Lookup(const char *path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
VFS_Stat(const char *path, struct stat *sb)
|
||||||
|
{
|
||||||
|
VNode *vn = VFS_Lookup(path);
|
||||||
|
if (vn == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
vn->op->stat(vn, sb);
|
||||||
|
|
||||||
|
// Release
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
VFS_Open(VNode *fn)
|
VFS_Open(VNode *fn)
|
||||||
{
|
{
|
||||||
@ -110,3 +124,15 @@ VFS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
|
|||||||
return fn->op->read(fn, buf, off, len);
|
return fn->op->read(fn, buf, off, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
VFS_Write(VNode *fn, void *buf, uint64_t off, uint64_t len)
|
||||||
|
{
|
||||||
|
return fn->op->write(fn, buf, off, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
VFS_ReadDir(VNode *fn, void *buf, uint64_t len, uint64_t *off)
|
||||||
|
{
|
||||||
|
return fn->op->readdir(fn, buf, len, off);
|
||||||
|
}
|
||||||
|
|
||||||
|
85
sys/kern/vfsuio.c
Normal file
85
sys/kern/vfsuio.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/kassert.h>
|
||||||
|
#include <sys/kdebug.h>
|
||||||
|
#include <sys/spinlock.h>
|
||||||
|
#include <sys/disk.h>
|
||||||
|
#include <sys/vfs.h>
|
||||||
|
#include <sys/handle.h>
|
||||||
|
#include <sys/vfsuio.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
VFSUIO_Read(Handle *handle, void *buf, uint64_t len, uint64_t off)
|
||||||
|
{
|
||||||
|
ASSERT(handle->type == HANDLE_TYPE_FILE);
|
||||||
|
|
||||||
|
// XXX: Need to pin memory
|
||||||
|
|
||||||
|
return VFS_Read(handle->vnode, buf, len, off);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
VFSUIO_Write(Handle *handle, void *buf, uint64_t len, uint64_t off)
|
||||||
|
{
|
||||||
|
ASSERT(handle->type == HANDLE_TYPE_FILE);
|
||||||
|
|
||||||
|
// XXX: Need to pin memory
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
VFSUIO_Flush(Handle *handle)
|
||||||
|
{
|
||||||
|
ASSERT(handle->type == HANDLE_TYPE_FILE);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
VFSUIO_Close(Handle *handle)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
ASSERT(handle->type == HANDLE_TYPE_FILE);
|
||||||
|
|
||||||
|
status = VFS_Close(handle->vnode);
|
||||||
|
Handle_Free(handle);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
VFSUIO_Open(const char *path, Handle **handle)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
Handle *hdl = Handle_Alloc();
|
||||||
|
if (!hdl) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
VNode *vn = VFS_Lookup(path);
|
||||||
|
status = VFS_Open(vn);
|
||||||
|
if (status != 0) {
|
||||||
|
// XXX: Release VNode
|
||||||
|
Handle_Free(hdl);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdl->vnode = vn;
|
||||||
|
hdl->type = HANDLE_TYPE_FILE;
|
||||||
|
hdl->read = VFSUIO_Read;
|
||||||
|
hdl->write = VFSUIO_Write;
|
||||||
|
hdl->flush = VFSUIO_Flush;
|
||||||
|
hdl->close = VFSUIO_Close;
|
||||||
|
|
||||||
|
*handle = hdl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user