diff options
Diffstat (limited to 'src/sys/os')
-rw-r--r-- | src/sys/os/os_filedes.c | 66 | ||||
-rw-r--r-- | src/sys/os/os_kalloc.c | 11 | ||||
-rw-r--r-- | src/sys/os/vfs_init.c | 3 | ||||
-rw-r--r-- | src/sys/os/vfs_namei.c | 72 | ||||
-rw-r--r-- | src/sys/os/vfs_subr.c | 42 |
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); +} |