aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-05-19 23:05:21 -0400
committerIan Moffett <ian@osmora.org>2024-05-19 23:05:21 -0400
commit673753e8befcfbb575380ed0d23fc6741b4e50a0 (patch)
tree087ef9499c52523601b8d95d74eec709885a0899
parentf9a6fc6f474ced84a78df50e2b105bd7da052d06 (diff)
kernel: vfs: Add support for open hook
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--sys/fs/devfs.c23
-rw-r--r--sys/include/sys/device.h1
-rw-r--r--sys/include/sys/vfs.h2
-rw-r--r--sys/include/sys/vnode.h1
-rw-r--r--sys/kern/kern_filedesc.c7
-rw-r--r--sys/kern/vfs_subr.c8
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);
+}