diff options
author | Ian Moffett <ian@osmora.org> | 2024-05-19 23:05:21 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-05-19 23:05:21 -0400 |
commit | 673753e8befcfbb575380ed0d23fc6741b4e50a0 (patch) | |
tree | 087ef9499c52523601b8d95d74eec709885a0899 | |
parent | f9a6fc6f474ced84a78df50e2b105bd7da052d06 (diff) |
kernel: vfs: Add support for open hook
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | sys/fs/devfs.c | 23 | ||||
-rw-r--r-- | sys/include/sys/device.h | 1 | ||||
-rw-r--r-- | sys/include/sys/vfs.h | 2 | ||||
-rw-r--r-- | sys/include/sys/vnode.h | 1 | ||||
-rw-r--r-- | sys/kern/kern_filedesc.c | 7 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 8 |
6 files changed, 39 insertions, 3 deletions
diff --git a/sys/fs/devfs.c b/sys/fs/devfs.c index 79606eb..d7944aa 100644 --- a/sys/fs/devfs.c +++ b/sys/fs/devfs.c @@ -158,6 +158,26 @@ vop_read(struct vnode *vp, struct sio_txn *sio) } static int +vop_open(struct vnode *vp) +{ + struct device_node *node; + struct device *dev; + + if (vp == NULL) { + return -EIO; + } + + node = vp->data; + dev = device_fetch(node->major, node->minor); + + if (dev->open == NULL) { + return -EIO; + } + + return dev->open(dev); +} + +static int devfs_init(struct fs_info *info, struct vnode *source) { if (source != NULL) @@ -249,5 +269,6 @@ struct vfsops g_devfs_ops = { struct vops g_devfs_vops = { .vget = vop_vget, - .read = vop_read + .read = vop_read, + .open = vop_open }; diff --git a/sys/include/sys/device.h b/sys/include/sys/device.h index 9851ee2..69e367f 100644 --- a/sys/include/sys/device.h +++ b/sys/include/sys/device.h @@ -42,6 +42,7 @@ struct device { int(*write)(struct device *dev, struct sio_txn *sio); int(*read)(struct device *dev, struct sio_txn *sio); int(*ioctl)(struct device *dev, uint32_t cmd, uintptr_t arg); + int(*open)(struct device *dev); paddr_t(*mmap)(struct device *dev, off_t off, vm_prot_t prot); TAILQ_ENTRY(device) link; }; diff --git a/sys/include/sys/vfs.h b/sys/include/sys/vfs.h index f5fede8..98aef3f 100644 --- a/sys/include/sys/vfs.h +++ b/sys/include/sys/vfs.h @@ -56,7 +56,9 @@ ssize_t vfs_hash_path(const char *path); ssize_t vfs_read(struct vnode *vp, struct sio_txn *sio); ssize_t vfs_write(struct vnode *vp, struct sio_txn *sio); + int vfs_getattr(struct vnode *vp, struct vattr *vattr); +int vfs_open(struct vnode *vp); uint64_t sys_mount(struct syscall_args *args); diff --git a/sys/include/sys/vnode.h b/sys/include/sys/vnode.h index 6dc2cbc..71fc5c2 100644 --- a/sys/include/sys/vnode.h +++ b/sys/include/sys/vnode.h @@ -44,6 +44,7 @@ struct vops { int(*read)(struct vnode *vp, struct sio_txn *sio); int(*write)(struct vnode *vp, struct sio_txn *sio); int(*getattr)(struct vnode *vp, struct vattr *vattr); + int(*open)(struct vnode *vp); }; struct vattr { diff --git a/sys/kern/kern_filedesc.c b/sys/kern/kern_filedesc.c index 6bce6d2..74ab859 100644 --- a/sys/kern/kern_filedesc.c +++ b/sys/kern/kern_filedesc.c @@ -291,12 +291,15 @@ open(const char *pathname, int oflag) int status; /* - * Attempt to create a vnode and allocate a - * file descriptor + * Attempt to create a vnode, call the open hook then + * allocate a file descriptor */ if ((status = vfs_path_to_node(pathname, &vp)) != 0) { return status; } + if ((status = vfs_open(vp)) != 0) { + return status; + } if ((status = fd_alloc(this_td(), &fd)) != 0) { return status; } diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 5b31057..f760831 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -239,3 +239,11 @@ vfs_getattr(struct vnode *vp, struct vattr *vattr) { return vp->vops->getattr(vp, vattr); } + +int vfs_open(struct vnode *vp) +{ + if (vp->vops->open == NULL) + return -EIO; + + return vp->vops->open(vp); +} |