diff options
Diffstat (limited to 'sys/fs/devfs.c')
-rw-r--r-- | sys/fs/devfs.c | 97 |
1 files changed, 86 insertions, 11 deletions
diff --git a/sys/fs/devfs.c b/sys/fs/devfs.c index 75cf991..3bd1b11 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,8 @@ #include <sys/types.h> #include <sys/vnode.h> #include <sys/errno.h> +#include <sys/stat.h> +#include <sys/syslog.h> #include <sys/mount.h> #include <sys/device.h> #include <fs/devfs.h> @@ -37,6 +39,7 @@ #include <string.h> struct devfs_node { + struct devstat stat; char *name; uint8_t is_block : 1; mode_t mode; @@ -63,6 +66,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 +129,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 +141,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 +152,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 +167,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; } @@ -159,6 +182,7 @@ static int devfs_read(struct vnode *vp, struct sio_txn *sio) { struct devfs_node *dnp; + struct devstat *statp; void *devsw; if ((dnp = vp->data) == NULL) @@ -169,11 +193,37 @@ devfs_read(struct vnode *vp, struct sio_txn *sio) if (!dnp->is_block) return cdevsw_read(devsw, dnp->dev, sio); + statp = &dnp->stat; + ++statp->nreads; + /* Block device */ return bdevsw_read(devsw, dnp->dev, sio); } static int +devfs_write(struct vnode *vp, struct sio_txn *sio) +{ + struct devfs_node *dnp; + struct devstat *statp; + 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); + } + + statp = &dnp->stat; + ++statp->nwrites; + + /* Block device */ + return bdevsw_write(devsw, dnp->dev, sio); +} + +static int devfs_init(struct fs_info *fip) { struct vnode *vp; @@ -193,6 +243,24 @@ devfs_init(struct fs_info *fip) return 0; } +int +devfs_devstat(struct vnode *vp, struct devstat *res) +{ + struct devfs_node *dnp; + + if ((dnp = vp->data) == NULL) { + return -EIO; + } + + /* Not supported on char devices */ + if (!dnp->is_block) { + return -ENOTSUP; + } + + *res = dnp->stat; + return 0; +} + /* * Create an entry within devfs. * @@ -205,6 +273,7 @@ int devfs_create_entry(const char *name, devmajor_t major, dev_t dev, mode_t mode) { struct devfs_node *dnp; + struct devstat *statp; size_t name_len; dnp = dynalloc(sizeof(*dnp)); @@ -218,9 +287,13 @@ devfs_create_entry(const char *name, devmajor_t major, dev_t dev, mode_t mode) return -ENOMEM; } + statp = &dnp->stat; + statp->nwrites = 0; + statp->nreads = 0; + 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 +305,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 = { |