diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/ctlfs.c | 3 | ||||
-rw-r--r-- | sys/fs/devfs.c | 3 | ||||
-rw-r--r-- | sys/fs/initramfs.c | 3 | ||||
-rw-r--r-- | sys/include/sys/fcntl.h | 1 | ||||
-rw-r--r-- | sys/include/sys/vnode.h | 8 | ||||
-rw-r--r-- | sys/kern/kern_descrip.c | 36 |
6 files changed, 48 insertions, 6 deletions
diff --git a/sys/fs/ctlfs.c b/sys/fs/ctlfs.c index 64d3a1a..9225114 100644 --- a/sys/fs/ctlfs.c +++ b/sys/fs/ctlfs.c @@ -380,7 +380,8 @@ static const struct vops ctlfs_vops = { .read = ctlfs_read, .getattr = NULL, .write = NULL, - .reclaim = ctlfs_reclaim + .reclaim = ctlfs_reclaim, + .create = NULL }; const struct vfsops g_ctlfs_vfsops = { diff --git a/sys/fs/devfs.c b/sys/fs/devfs.c index 0c087f0..293ee0a 100644 --- a/sys/fs/devfs.c +++ b/sys/fs/devfs.c @@ -273,7 +273,8 @@ const struct vops g_devfs_vops = { .reclaim = devfs_reclaim, .read = devfs_read, .write = devfs_write, - .getattr = devfs_getattr + .getattr = devfs_getattr, + .create = NULL }; const struct vfsops g_devfs_vfsops = { diff --git a/sys/fs/initramfs.c b/sys/fs/initramfs.c index c3f9b14..c41deb4 100644 --- a/sys/fs/initramfs.c +++ b/sys/fs/initramfs.c @@ -279,7 +279,8 @@ const struct vops g_initramfs_vops = { .read = initramfs_read, .write = NULL, .reclaim = initramfs_reclaim, - .getattr = initramfs_getattr + .getattr = initramfs_getattr, + .create = NULL, }; const struct vfsops g_initramfs_vfsops = { diff --git a/sys/include/sys/fcntl.h b/sys/include/sys/fcntl.h index 122a378..83d38af 100644 --- a/sys/include/sys/fcntl.h +++ b/sys/include/sys/fcntl.h @@ -33,6 +33,7 @@ #define O_RDONLY 0x0000 #define O_WRONLY 0x0001 #define O_RDWR 0x0002 +#define O_CREAT 0x0004 /* Makes seal checking easier */ #if defined(_KERNEL) diff --git a/sys/include/sys/vnode.h b/sys/include/sys/vnode.h index cd71817..1a6b2aa 100644 --- a/sys/include/sys/vnode.h +++ b/sys/include/sys/vnode.h @@ -86,6 +86,13 @@ struct vop_lookup_args { struct vnode **vpp; /* Result vnode */ }; +struct vop_create_args { + const char *path; /* Full path */ + const char *ppath; /* Parent path */ + struct vnode *dirvp; /* Directory vnode */ + struct vnode **vpp; /* Result vnode */ +}; + /* * A field in this structure is unavailable * if it has a value of VNOVAL. @@ -106,6 +113,7 @@ struct vops { int(*read)(struct vnode *vp, struct sio_txn *sio); int(*write)(struct vnode *vp, struct sio_txn *sio); int(*reclaim)(struct vnode *vp); + int(*create)(struct vop_create_args *args); }; extern struct vnode *g_root_vnode; diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index a2dd667..da67530 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -229,6 +229,29 @@ done: return retval; } +static int +fd_do_create(const char *path, struct nameidata *ndp) +{ + struct vop_create_args cargs; + struct vnode *dirvp = ndp->vp; + const struct vops *vops = dirvp->vops; + int error; + + if (vops->create == NULL) { + return -EINVAL; + } + + cargs.path = path; + cargs.ppath = ndp->path; + cargs.dirvp = dirvp; + cargs.vpp = &ndp->vp; + if ((error = vops->create(&cargs)) < 0) { + return error; + } + + return 0; +} + int fd_read(unsigned int fd, void *buf, size_t count) { @@ -247,18 +270,17 @@ fd_write(unsigned int fd, void *buf, size_t count) * * @pathname: Path of file to open. * @flags: Flags to use. - * - * TODO: Use of flags. */ int fd_open(const char *pathname, int flags) { int error; + const struct vops *vops; struct filedesc *filedes; struct nameidata nd; nd.path = pathname; - nd.flags = 0; + nd.flags = ISSET(flags, O_CREAT) ? NAMEI_WANTPARENT : 0; if ((error = namei(&nd)) < 0) { return error; @@ -269,6 +291,14 @@ fd_open(const char *pathname, int flags) return error; } + vops = nd.vp->vops; + if (ISSET(flags, O_CREAT) && vops->create != NULL) { + error = fd_do_create(pathname, &nd); + } + if (error < 0) { + return error; + } + filedes->vp = nd.vp; filedes->flags = flags; return filedes->fdno; |