summaryrefslogtreecommitdiff
path: root/src/sys/os
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys/os')
-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
5 files changed, 176 insertions, 18 deletions
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);
+}