summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/fs/devfs.c2
-rw-r--r--src/sys/fs/tmpfs.c363
-rw-r--r--src/sys/include/compat/unix/syscall.h8
-rw-r--r--src/sys/include/os/filedesc.h10
-rw-r--r--src/sys/include/os/kalloc.h8
-rw-r--r--src/sys/include/os/vnode.h45
-rw-r--r--src/sys/include/sys/fcntl.h1
-rw-r--r--src/sys/include/sys/mount.h5
-rw-r--r--src/sys/include/sys/namei.h2
-rw-r--r--src/sys/include/sys/seek.h37
-rw-r--r--src/sys/include/sys/syscall.h1
-rw-r--r--src/sys/os/os_filedes.c66
-rw-r--r--src/sys/os/os_kalloc.c11
-rw-r--r--src/sys/os/vfs_init.c3
-rw-r--r--src/sys/os/vfs_namei.c72
-rw-r--r--src/sys/os/vfs_subr.c42
16 files changed, 654 insertions, 22 deletions
diff --git a/src/sys/fs/devfs.c b/src/sys/fs/devfs.c
index 7553003..729449a 100644
--- a/src/sys/fs/devfs.c
+++ b/src/sys/fs/devfs.c
@@ -160,7 +160,7 @@ static struct vop devfs_vops = {
.lookup = devfs_lookup
};
-struct vfsops g_devfs_vfops = {
+struct vfsops g_devfs_vfsops = {
.init = devfs_init,
.mount = devfs_mount
};
diff --git a/src/sys/fs/tmpfs.c b/src/sys/fs/tmpfs.c
new file mode 100644
index 0000000..af1537f
--- /dev/null
+++ b/src/sys/fs/tmpfs.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2025 Ian Marco Moffett and L5 engineers
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/syslog.h>
+#include <sys/errno.h>
+#include <sys/queue.h>
+#include <sys/param.h>
+#include <os/vnode.h>
+#include <os/kalloc.h>
+#include <string.h>
+
+#define TMPFS_NAMEMAX 128
+#define TMPFS_INIT_SIZE 8
+
+/*
+ * Represents a single tmpfs node
+ */
+struct tmpfs_node {
+ char name[TMPFS_NAMEMAX];
+ char *data;
+ size_t len;
+ size_t real_len;
+ int ref;
+ TAILQ_ENTRY(tmpfs_node) link;
+};
+
+#define tmpfs_ref(TMP_NODEP) \
+ atomic_inc_int(&(TMP_NODEP)->ref)
+
+static TAILQ_HEAD(, tmpfs_node) tmpfs;
+static struct vop tmpfs_vops;
+
+/*
+ * Create a new tmpfs node
+ *
+ * @name: Name of node to create
+ * @np_res: Result pointer is written here
+ *
+ * Returns zero on success, otherwise a less than
+ * zero value on failure
+ */
+static int
+tmpfs_new(const char *name, struct tmpfs_node **np_res)
+{
+ struct tmpfs_node *np;
+ size_t name_len;
+
+ if (name == NULL) {
+ return -EINVAL;
+ }
+
+ name_len = strlen(name);
+ if (name_len > sizeof(np->name) - 1) {
+ return -ENAMETOOLONG;
+ }
+
+ np = kalloc(sizeof(*np));
+ if (np == NULL) {
+ return -ENOMEM;
+ }
+
+ memset(np, 0, sizeof(*np));
+ np->data = kalloc(TMPFS_INIT_SIZE);
+ if (np->data == NULL) {
+ kfree(np);
+ return -ENOMEM;
+ }
+
+ np->real_len = 0;
+ np->len = TMPFS_INIT_SIZE;
+ np->ref = 1;
+ memset(np->data, 0, TMPFS_INIT_SIZE);
+ memcpy(np->name, name, name_len);
+
+ if (np_res != NULL) {
+ *np_res = np;
+ }
+
+ TAILQ_INSERT_TAIL(&tmpfs, np, link);
+ return 0;
+}
+
+/*
+ * Lookup a tmpfs node by name
+ *
+ * @name: Name to lookup
+ * @np_res: Result is written here
+ */
+static int
+tmpfs_byname(const char *name, struct tmpfs_node **np_res)
+{
+ struct tmpfs_node *npcur;
+ int retval = -ENOENT;
+
+ if (name == NULL || np_res == NULL) {
+ return -EINVAL;
+ }
+
+ TAILQ_FOREACH(npcur, &tmpfs, link) {
+ if (npcur == NULL) {
+ continue;
+ }
+
+ if (strcmp(npcur->name, name) == 0) {
+ retval = 0;
+ *np_res = npcur;
+ break;
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * VFS tmpfs lookup callback
+ */
+static int
+tmpfs_lookup(struct vop_lookup_args *args)
+{
+ struct tmpfs_node *np;
+ struct vnode *vp;
+ int error;
+
+ /* Sanity checks */
+ if (args == NULL)
+ return -EINVAL;
+ if (args->name == NULL)
+ return -EINVAL;
+ if (args->vpp == NULL)
+ return -EINVAL;
+
+ error = tmpfs_byname(args->name, &np);
+ if (error < 0) {
+ return error;
+ }
+
+ error = vfs_valloc(&vp, VTYPE_FILE, 0);
+ if (error < 0) {
+ return error;
+ }
+
+ /* Ref that node and give it */
+ tmpfs_ref(np);
+ vp->data = np;
+ vp->vops = &tmpfs_vops;
+ *args->vpp = vp;
+ return 0;
+}
+
+/*
+ * Create a tmpfs node
+ */
+static int
+tmpfs_create(struct vop_create_args *args)
+{
+ struct nameidata *ndp;
+ struct tmpfs_node *np = NULL;
+
+ if (args == NULL) {
+ return -EINVAL;
+ }
+
+ if ((ndp = args->ndp) == NULL) {
+ return -EINVAL;
+ }
+
+ /* Does it already exist? */
+ if (tmpfs_byname(ndp->path, &np) == 0) {
+ return -EEXIST;
+ }
+
+ return tmpfs_new(ndp->path, NULL);
+}
+
+/*
+ * Initialize the temporary filesystem
+ */
+static int
+tmpfs_init(struct fs_info *fip)
+{
+ TAILQ_INIT(&tmpfs);
+ return 0;
+}
+
+/*
+ * Mount the filesystem
+ */
+static int
+tmpfs_mount(struct fs_info *fip, struct mount_args *margs)
+{
+ int error;
+ struct vnode *vp;
+
+ if (fip == NULL || margs == NULL) {
+ return -1;
+ }
+
+ /* Allocate a vnode for this mountpoint */
+ error = vfs_valloc(&margs->vp_res, VTYPE_DIR, 0);
+ if (error < 0) {
+ return error;
+ }
+
+ vp = margs->vp_res;
+ vp->vops = &tmpfs_vops;
+ return 0;
+}
+
+/*
+ * Write to the filesystem
+ */
+static ssize_t
+tmpfs_write(struct vop_rw_data *data)
+{
+ struct vnode *vp;
+ struct tmpfs_node *np;
+ char *dest;
+ void *p;
+ size_t node_len, len;
+ size_t overflow_window;
+
+ if (data == NULL) {
+ return -EINVAL;
+ }
+
+ if ((vp = data->vp) == NULL) {
+ return -EIO;
+ }
+
+ /* We need the vnode for lengths */
+ if ((np = vp->data) == NULL) {
+ return -EIO;
+ }
+
+ /*
+ * Check if there is going to be any overflows
+ * and if so, get the overflow window and expand
+ * the buffer by it.
+ */
+ len = data->len;
+ if ((len + data->off) > np->len) {
+ overflow_window = (len + data->off) - np->len;
+ np->len += overflow_window + 1;
+
+ p = np->data;
+ np->data = krealloc(np->data, np->len);
+ if (np->data == NULL) {
+ np->data = p;
+ return -ENOMEM;
+ }
+ }
+
+ np->real_len += len;
+ node_len = np->len;
+ dest = np->data + data->off;
+ memcpy(dest, data->data, len);
+ return len;
+}
+
+static ssize_t
+tmpfs_read(struct vop_rw_data *data)
+{
+ struct vnode *vp;
+ struct tmpfs_node *np;
+ size_t len;
+ char *dest, *src;
+
+ if (data == NULL) {
+ return -1;
+ }
+
+ if ((vp = data->vp) == NULL) {
+ return -EIO;
+ }
+
+ if ((np = vp->data) == NULL) {
+ return -EIO;
+ }
+
+ /* Return EOF if the offset is too far */
+ len = data->len;
+ if (data->off >= np->real_len) {
+ return 0; /* EOF */
+ }
+
+ /* Is there any data to read? */
+ if ((len + data->off) > np->len) {
+ len = np->len;
+ }
+ if (len == 0) {
+ return 0;
+ }
+
+ dest = data->data;
+ src = np->data + data->off;
+ memcpy(dest, src, len);
+ return len;
+}
+
+static int
+tmpfs_getattr(struct vnode *vp, struct vattr *res)
+{
+ struct tmpfs_node *np;
+
+ if (vp == NULL || res == NULL) {
+ return -EINVAL;
+ }
+
+ if ((np = vp->data) == NULL) {
+ return -EIO;
+ }
+
+ res->size = np->real_len;
+ return 0;
+}
+
+static int
+tmpfs_reclaim(struct vnode *vp, int flags)
+{
+ return 0;
+}
+
+static struct vop tmpfs_vops = {
+ .lookup = tmpfs_lookup,
+ .create = tmpfs_create,
+ .reclaim = tmpfs_reclaim,
+ .write = tmpfs_write,
+ .read = tmpfs_read,
+ .getattr = tmpfs_getattr
+};
+
+struct vfsops g_tmpfs_vfsops = {
+ .init = tmpfs_init,
+ .mount = tmpfs_mount,
+};
diff --git a/src/sys/include/compat/unix/syscall.h b/src/sys/include/compat/unix/syscall.h
index a031872..42dc4c0 100644
--- a/src/sys/include/compat/unix/syscall.h
+++ b/src/sys/include/compat/unix/syscall.h
@@ -73,6 +73,11 @@ scret_t sys_read(struct syscall_args *scargs);
*/
scret_t sys_close(struct syscall_args *scargs);
+/*
+ * Seek a file descriptor
+ */
+scret_t sys_lseek(struct syscall_args *scargs);
+
#ifdef _NEED_UNIX_SCTAB
scret_t(*g_unix_sctab[])(struct syscall_args *) = {
[SYS_none] = NULL,
@@ -89,7 +94,8 @@ scret_t(*g_unix_sctab[])(struct syscall_args *) = {
[SYS_waitpid] = sys_waitpid,
[SYS_dmsio] = sys_dmsio,
[SYS_read] = sys_read,
- [SYS_close] = sys_close
+ [SYS_close] = sys_close,
+ [SYS_lseek] = sys_lseek
};
#endif /* !_NEED_UNIX_SCTAB */
diff --git a/src/sys/include/os/filedesc.h b/src/sys/include/os/filedesc.h
index a6a2ac5..b773de9 100644
--- a/src/sys/include/os/filedesc.h
+++ b/src/sys/include/os/filedesc.h
@@ -30,6 +30,7 @@
#ifndef _OS_FILEDESC_H_
#define _OS_FILEDESC_H_ 1
+#include <sys/seek.h>
#include <sys/types.h>
#include <os/vnode.h>
@@ -117,4 +118,13 @@ ssize_t write(int fd, const void *buf, size_t count);
*/
ssize_t read(int fd, void *buf, size_t count);
+/*
+ * Reposition the file offset of a file
+ *
+ * @fd: File descriptor to reposition
+ * @offset: Offset to move `fd' to
+ * @whence: How it should be repositioned
+ */
+off_t lseek(int fd, off_t offset, int whence);
+
#endif /* !_OS_FILEDESC_H_ */
diff --git a/src/sys/include/os/kalloc.h b/src/sys/include/os/kalloc.h
index 143c4f9..aaaaa74 100644
--- a/src/sys/include/os/kalloc.h
+++ b/src/sys/include/os/kalloc.h
@@ -48,6 +48,14 @@
void *kalloc(size_t sz);
/*
+ * Reallocates memory pool created by `dynalloc()'
+ *
+ * @old_ptr: Pointer to old pool.
+ * @newsize: Size of new pool.
+ */
+void *krealloc(void *old_ptr, size_t newsize);
+
+/*
* Free a chunk of memory given to by
* `ptr'
*
diff --git a/src/sys/include/os/vnode.h b/src/sys/include/os/vnode.h
index 1bef1e2..77cadb2 100644
--- a/src/sys/include/os/vnode.h
+++ b/src/sys/include/os/vnode.h
@@ -32,6 +32,7 @@
#include <sys/types.h>
#include <sys/atomic.h>
+#include <sys/namei.h>
/* Forward declarations */
struct vnode;
@@ -83,12 +84,33 @@ struct vop_rw_data {
};
/*
+ * Arguments to create an entry within a
+ * filesystem
+ *
+ * @ndp: Path component to create
+ */
+struct vop_create_args {
+ struct nameidata *ndp;
+};
+
+/*
+ * Represents attributes of a vnode
+ *
+ * @size: File size in bytes
+ */
+struct vattr {
+ size_t size;
+};
+
+/*
* Represents operations that can be performed on
* a specific vnode. These are implemented as callbacks
*/
struct vop {
+ int(*getattr)(struct vnode *vp, struct vattr *res);
int(*lookup)(struct vop_lookup_args *args);
int(*reclaim)(struct vnode *vp, int flags);
+ int(*create)(struct vop_create_args *args);
ssize_t(*write)(struct vop_rw_data *data);
ssize_t(*read)(struct vop_rw_data *data);
};
@@ -176,4 +198,27 @@ ssize_t vop_read(struct vnode *vp, char *data, off_t off, size_t len);
*/
int vop_reclaim(struct vnode *vp, int flags);
+/*
+ * Create a node within a specific filesystem or
+ * directory
+ *
+ * @vp: Vnode of parent directory
+ * @ndp: Namei descriptor of path component
+ *
+ * Returns zero on success, otherwise a less than zero
+ * value on failure.
+ */
+int vop_create(struct vnode *vp, struct nameidata *ndp);
+
+/*
+ * Get the attributes of a file
+ *
+ * @vp: Vnode of file to get attributes of
+ * @res: Result of file to get attr of
+ *
+ * Returns zero on success, otherwise a less than
+ * zero value on failure
+ */
+int vop_getattr(struct vnode *vp, struct vattr *res);
+
#endif /* !_OS_VNODE_H_ */
diff --git a/src/sys/include/sys/fcntl.h b/src/sys/include/sys/fcntl.h
index 30d2ec4..1ab3e71 100644
--- a/src/sys/include/sys/fcntl.h
+++ b/src/sys/include/sys/fcntl.h
@@ -43,6 +43,7 @@
#define O_RDONLY 0x00
#define O_RDWR BIT(1)
#define O_WRONLY BIT(2)
+#define O_CREAT BIT(3)
/* File access mode flags */
#define O_ACCMODE (O_RDWR | O_WRONLY)
diff --git a/src/sys/include/sys/mount.h b/src/sys/include/sys/mount.h
index 6d041ee..5f6fa6b 100644
--- a/src/sys/include/sys/mount.h
+++ b/src/sys/include/sys/mount.h
@@ -42,6 +42,7 @@
*/
#define MOUNT_INITRD "initrd" /* Initial ramdisk */
#define MOUNT_DEVFS "devfs" /* Device filesystem */
+#define MOUNT_TMPFS "tmpfs" /* Temporary filesystem */
/*
* The mount system call
@@ -65,7 +66,8 @@ struct mount;
/* Filesystem vfsops */
extern struct vfsops g_omar_vfsops;
-extern struct vfsops g_devfs_vfops;
+extern struct vfsops g_devfs_vfsops;
+extern struct vfsops g_tmpfs_vfsops;
/*
* Represents a mountpoint
@@ -133,7 +135,6 @@ struct fs_info {
*/
#define FS_ATTR_IMAGE BIT(0) /* Is an image kind e.g., OSMORA OMAR */
-
/*
* VFS operations vector
*
diff --git a/src/sys/include/sys/namei.h b/src/sys/include/sys/namei.h
index 58307b1..9e78a4c 100644
--- a/src/sys/include/sys/namei.h
+++ b/src/sys/include/sys/namei.h
@@ -32,6 +32,8 @@
#include <os/vnode.h>
+#define NAMEI_CREATE BIT(0) /* Create as we go */
+
/*
* Represents namei data that can be used for
* looking up files
diff --git a/src/sys/include/sys/seek.h b/src/sys/include/sys/seek.h
new file mode 100644
index 0000000..1edc50b
--- /dev/null
+++ b/src/sys/include/sys/seek.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2025 Ian Marco Moffett and L5 engineers
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_SEEK_H_
+#define _SYS_SEEK_H_ 1
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#endif /* !_SYS_SEEK_H_ */
diff --git a/src/sys/include/sys/syscall.h b/src/sys/include/sys/syscall.h
index 77b7505..c97d5ea 100644
--- a/src/sys/include/sys/syscall.h
+++ b/src/sys/include/sys/syscall.h
@@ -58,6 +58,7 @@
#define SYS_dmsio 0x0D /* DMS I/O */
#define SYS_read 0x0E /* read a file descriptor */
#define SYS_close 0x0F /* close a file */
+#define SYS_lseek 0x10 /* seek to end of file */
typedef __ssize_t scret_t;
typedef __ssize_t scarg_t;
diff --git a/src/sys/os/os_filedes.c b/src/sys/os/os_filedes.c
index 95452af..36748a6 100644
--- a/src/sys/os/os_filedes.c
+++ b/src/sys/os/os_filedes.c
@@ -160,8 +160,10 @@ fd_open(const char *path, mode_t mode)
{
struct filedesc *fd;
struct nameidata nd;
+ struct vop_create_args creat_args;
struct proc *self = proc_self();
struct vnode *vp;
+ uint32_t namei_flags = 0;
int error;
/* We need the current proc */
@@ -180,12 +182,21 @@ fd_open(const char *path, mode_t mode)
}
/*
+ * If we are creating a new file, we'll need to
+ * get the parent vnode so that we can use the
+ * create vop.
+ */
+ if (ISSET(mode, O_CREAT)) {
+ namei_flags |= NAMEI_CREATE;
+ }
+
+ /*
* Now we try to do the lookup, we'll need
* the vnode for file references to be
* useful
*/
nd.path = path;
- nd.flags = 0;
+ nd.flags = namei_flags;
nd.vp_res = &vp;
error = namei(&nd);
if (error < 0) {
@@ -348,6 +359,44 @@ read(int fd, void *buf, size_t count)
return retval;
}
+off_t
+lseek(int fd, off_t offset, int whence)
+{
+ struct filedesc *fdp;
+ struct proc *self = proc_self();
+ struct vattr attr;
+ int error;
+
+ if (fd < 0) {
+ return -EBADF;
+ }
+
+ fdp = fd_get(self, fd);
+ if (fdp == NULL) {
+ return -EBADF;
+ }
+
+ /* Could not get vnode attributes */
+ error = vop_getattr(fdp->vp, &attr);
+ if (error < 0) {
+ return 0;
+ }
+
+ switch (whence) {
+ case SEEK_SET:
+ fdp->off = offset;
+ break;
+ case SEEK_CUR:
+ fdp->off += offset;
+ break;
+ case SEEK_END:
+ fdp->off = attr.size;
+ break;
+ }
+
+ return fdp->off;
+}
+
/*
* ARG0: Path
* ARG1: Mode
@@ -367,3 +416,18 @@ sys_open(struct syscall_args *scargs)
return fd_open(pathbuf, mode);
}
+
+/*
+ * ARG0: Fd
+ * ARG1: Offset
+ * ARG2: Whence
+ */
+scret_t
+sys_lseek(struct syscall_args *scargs)
+{
+ int fd = SCARG(scargs, int, 0);
+ off_t off = SCARG(scargs, off_t, 1);
+ int whence = SCARG(scargs, int, 2);
+
+ return lseek(fd, off, whence);
+}
diff --git a/src/sys/os/os_kalloc.c b/src/sys/os/os_kalloc.c
index 53e2e13..a5e48e5 100644
--- a/src/sys/os/os_kalloc.c
+++ b/src/sys/os/os_kalloc.c
@@ -64,6 +64,17 @@ kalloc(size_t sz)
return tmp;
}
+void *
+krealloc(void *old_ptr, size_t newsize)
+{
+ void *tmp;
+
+ spinlock_acquire(&lock);
+ tmp = tlsf_realloc(tlsf_ctx, old_ptr, newsize);
+ spinlock_release(&lock);
+ return tmp;
+}
+
/*
* Memory deallocation
*/
diff --git a/src/sys/os/vfs_init.c b/src/sys/os/vfs_init.c
index 80d8559..1b6f815 100644
--- a/src/sys/os/vfs_init.c
+++ b/src/sys/os/vfs_init.c
@@ -39,7 +39,8 @@
*/
static struct fs_info fstab[] = {
{ MOUNT_INITRD, &g_omar_vfsops, 0 },
- { MOUNT_DEVFS, &g_devfs_vfops, 0 }
+ { MOUNT_DEVFS, &g_devfs_vfsops, 0 },
+ { MOUNT_TMPFS, &g_tmpfs_vfsops, 0 }
};
/*
diff --git a/src/sys/os/vfs_namei.c b/src/sys/os/vfs_namei.c
index 1425c30..d417db8 100644
--- a/src/sys/os/vfs_namei.c
+++ b/src/sys/os/vfs_namei.c
@@ -46,10 +46,13 @@ namei(struct nameidata *ndp)
struct vnode *vp;
struct vop *vops;
struct vop_lookup_args lookup;
+ struct vop_create_args create;
+ struct nameidata nd_create;
struct fs_info *fip;
char namebuf[NAME_MAX];
+ size_t root_len;
const char *p, *pcur;
- size_t len, i = 0;
+ size_t i = 0;
int error;
if (ndp == NULL) {
@@ -61,23 +64,35 @@ namei(struct nameidata *ndp)
return -EINVAL;
}
- error = mount_lookup("/", &mp);
+ /* Get rid of leading slashes */
+ pcur = p;
+ while (*pcur == '/') {
+ ++pcur;
+ }
+
+ /* Wait until we get the '/' */
+ while (*pcur != '/' && *pcur != '\0') {
+ ++pcur;
+ }
+
+ /* Copy the root path e.g., /tmp */
+ root_len = (size_t)(pcur - p);
+ memcpy(namebuf, p, root_len);
+ error = mount_lookup(namebuf, &mp);
+
if (error < 0) {
- printf("namei: failed to get rootfs\n");
+ error = mount_lookup("/", &mp);
+ }
+ if (error < 0) {
+ printf("namei: could not get mount %s\n", namebuf);
return error;
}
- vp = mp->vp;
fip = mp->fs;
-
- if ((vops = vp->vops) == NULL) {
- printf("namei: failed to get vops\n");
+ if ((vp = mp->vp) == NULL) {
return -EIO;
}
-
- /* We need vops->lookup() */
- if (vops->lookup == NULL) {
- printf("namei: vops does not have lookup op\n");
+ if ((vops = vp->vops) == NULL) {
return -EIO;
}
@@ -101,10 +116,7 @@ namei(struct nameidata *ndp)
}
}
- printf("namei: f: %s\n", ndp->path);
- printf("namei: d: /\n", ndp->path);
- pcur = p;
while (*pcur != '\0') {
/* Get out of the slashes */
while (*pcur == '/')
@@ -123,7 +135,35 @@ namei(struct nameidata *ndp)
}
i = 0;
- printf("namei: n %s\n", namebuf);
+
+ /* Get the vops */
+ vp = mp->vp;
+ if ((vops = vp->vops) == NULL) {
+ return -EIO;
+ }
+
+ /* Create as we go? */
+ if (ISSET(ndp->flags, NAMEI_CREATE)) {
+ if (vops->create == NULL)
+ return -EIO;
+
+ nd_create.path = namebuf;
+ create.ndp = &nd_create;
+ error = vops->create(&create);
+ if (error < 0)
+ return error;
+ }
+
+ /* Do the lookup */
+ lookup.dirvp = vp;
+ lookup.vpp = &vp;
+ lookup.name = namebuf;
+ error = vops->lookup(&lookup);
+ if (error < 0) {
+ return -ENOENT;
+ }
}
- return -ENOENT;
+
+ *ndp->vp_res = vp;
+ return 0;
}
diff --git a/src/sys/os/vfs_subr.c b/src/sys/os/vfs_subr.c
index 6cb7767..2ae18af 100644
--- a/src/sys/os/vfs_subr.c
+++ b/src/sys/os/vfs_subr.c
@@ -224,3 +224,45 @@ vop_reclaim(struct vnode *vp, int flags)
return vops->reclaim(vp, flags);
}
+
+int
+vop_create(struct vnode *vp, struct nameidata *ndp)
+{
+ struct vop *vops;
+ struct vop_create_args args;
+
+ if (vp == NULL || ndp == NULL) {
+ return -EINVAL;
+ }
+
+ if ((vops = vp->vops) == NULL) {
+ return -EIO;
+ }
+
+ if (vops->create == NULL) {
+ return -EIO;
+ }
+
+ args.ndp = ndp;
+ return vops->create(&args);
+}
+
+int
+vop_getattr(struct vnode *vp, struct vattr *res)
+{
+ struct vop *vops;
+
+ if (vp == NULL || res == NULL) {
+ return -EINVAL;
+ }
+
+ if ((vops = vp->vops) == NULL) {
+ return -EIO;
+ }
+
+ if (vops->getattr == NULL) {
+ return -EIO;
+ }
+
+ return vops->getattr(vp, res);
+}