diff options
Diffstat (limited to 'sys/fs/devfs.c')
-rw-r--r-- | sys/fs/devfs.c | 59 |
1 files changed, 49 insertions, 10 deletions
diff --git a/sys/fs/devfs.c b/sys/fs/devfs.c index 024239d..3bd1b11 100644 --- a/sys/fs/devfs.c +++ b/sys/fs/devfs.c @@ -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; @@ -126,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; } @@ -136,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) { @@ -145,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. @@ -153,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; } @@ -175,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) @@ -185,6 +193,9 @@ 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); } @@ -193,6 +204,7 @@ 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) @@ -204,6 +216,9 @@ devfs_write(struct vnode *vp, struct sio_txn *sio) return cdevsw_write(devsw, dnp->dev, sio); } + statp = &dnp->stat; + ++statp->nwrites; + /* Block device */ return bdevsw_write(devsw, dnp->dev, sio); } @@ -228,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. * @@ -240,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)); @@ -253,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; @@ -268,7 +306,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 = { |