summaryrefslogtreecommitdiff
path: root/sys/fs/devfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/devfs.c')
-rw-r--r--sys/fs/devfs.c64
1 files changed, 53 insertions, 11 deletions
diff --git a/sys/fs/devfs.c b/sys/fs/devfs.c
index 75cf991..293ee0a 100644
--- a/sys/fs/devfs.c
+++ b/sys/fs/devfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/vnode.h>
#include <sys/errno.h>
+#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/device.h>
#include <fs/devfs.h>
@@ -63,6 +64,22 @@ bdevsw_read(void *devsw, dev_t dev, struct sio_txn *sio)
return bdevsw->read(dev, sio, 0);
}
+static inline int
+cdevsw_write(void *devsw, dev_t dev, struct sio_txn *sio)
+{
+ struct cdevsw *cdevsw = devsw;
+
+ return cdevsw->write(dev, sio, 0);
+}
+
+static inline int
+bdevsw_write(void *devsw, dev_t dev, struct sio_txn *sio)
+{
+ struct bdevsw *bdevsw = devsw;
+
+ return bdevsw->write(dev, sio, 0);
+}
+
/*
* Get a devfs node by name.
*
@@ -110,6 +127,8 @@ devfs_lookup(struct vop_lookup_args *args)
vp->data = dnp;
vp->vops = &g_devfs_vops;
+ vp->major = dnp->major;
+ vp->dev = dnp->dev;
*args->vpp = vp;
return 0;
}
@@ -120,6 +139,8 @@ devfs_getattr(struct vop_getattr_args *args)
struct vnode *vp;
struct vattr *attr;
struct devfs_node *dnp;
+ struct bdevsw *bdev;
+ size_t size = 0;
vp = args->vp;
if ((dnp = vp->data) == NULL) {
@@ -129,6 +150,13 @@ devfs_getattr(struct vop_getattr_args *args)
return -EIO;
}
+ if (dnp->is_block) {
+ bdev = dev_get(dnp->major, dnp->dev);
+ if (bdev->bsize != NULL) {
+ size = bdev->bsize(dnp->dev);
+ }
+ }
+
/*
* Set stat attributes from device node structure
* found within vnode data.
@@ -137,20 +165,13 @@ devfs_getattr(struct vop_getattr_args *args)
* size is hardwired to 0.
*/
attr->mode = dnp->mode;
- attr->size = 0;
+ attr->size = size;
return 0;
}
static int
devfs_reclaim(struct vnode *vp)
{
- struct devfs_node *dnp;
-
- if ((dnp = vp->data) != NULL) {
- dynfree(dnp->name);
- dynfree(vp->data);
- }
-
vp->data = NULL;
return 0;
}
@@ -174,6 +195,25 @@ devfs_read(struct vnode *vp, struct sio_txn *sio)
}
static int
+devfs_write(struct vnode *vp, struct sio_txn *sio)
+{
+ struct devfs_node *dnp;
+ void *devsw;
+
+ if ((dnp = vp->data) == NULL)
+ return -EIO;
+
+ devsw = dev_get(dnp->major, dnp->dev);
+
+ if (!dnp->is_block) {
+ return cdevsw_write(devsw, dnp->dev, sio);
+ }
+
+ /* Block device */
+ return bdevsw_write(devsw, dnp->dev, sio);
+}
+
+static int
devfs_init(struct fs_info *fip)
{
struct vnode *vp;
@@ -220,7 +260,7 @@ devfs_create_entry(const char *name, devmajor_t major, dev_t dev, mode_t mode)
memcpy(dnp->name, name, name_len);
dnp->name[name_len] = '\0';
-
+ dnp->is_block = ISSET(mode, S_IFBLK) ? 1 : 0;
dnp->major = major;
dnp->dev = dev;
dnp->mode = mode;
@@ -232,7 +272,9 @@ const struct vops g_devfs_vops = {
.lookup = devfs_lookup,
.reclaim = devfs_reclaim,
.read = devfs_read,
- .getattr = devfs_getattr
+ .write = devfs_write,
+ .getattr = devfs_getattr,
+ .create = NULL
};
const struct vfsops g_devfs_vfsops = {