diff options
Diffstat (limited to 'sys/fs/devfs.c')
-rw-r--r-- | sys/fs/devfs.c | 64 |
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 = { |