diff options
Diffstat (limited to 'src/sys/os')
-rw-r--r-- | src/sys/os/os_filedes.c | 13 | ||||
-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 | 22 |
5 files changed, 103 insertions, 18 deletions
diff --git a/src/sys/os/os_filedes.c b/src/sys/os/os_filedes.c index 95452af..ca56fc3 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) { 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..adfcffb 100644 --- a/src/sys/os/vfs_subr.c +++ b/src/sys/os/vfs_subr.c @@ -224,3 +224,25 @@ 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); +} |