diff options
Diffstat (limited to 'src/sys/fs')
-rw-r--r-- | src/sys/fs/devfs.c | 54 | ||||
-rw-r--r-- | src/sys/fs/tmpfs.c | 18 |
2 files changed, 67 insertions, 5 deletions
diff --git a/src/sys/fs/devfs.c b/src/sys/fs/devfs.c index 729449a..0e6b8ef 100644 --- a/src/sys/fs/devfs.c +++ b/src/sys/fs/devfs.c @@ -72,12 +72,13 @@ devfs_lookup(struct vop_lookup_args *args) } /* Found it! Create a vnode */ - error = vfs_valloc(&vp, VTYPE_FILE, 0); + error = vfs_valloc(&vp, VTYPE_CDEV, 0); if (error < 0) { return error; } vp->data = dnp; + vp->vops = &devfs_vops; *args->vpp = vp; return 0; } @@ -116,6 +117,7 @@ devfs_register(const char *name, dev_type_t type, void *devsw, int flags) break; } + dnp->dev = devsw; devname_len = strlen(name); memcpy(dnp->name, name, devname_len); TAILQ_INSERT_TAIL(&nodelist, dnp, link); @@ -123,6 +125,53 @@ devfs_register(const char *name, dev_type_t type, void *devsw, int flags) } /* + * Read a character device + */ +static int +devfs_cdev_read(struct devfs_node *dnp, struct dev_iobuf *iobuf, int flags) +{ + struct cdevsw *cdev; + + if (dnp == NULL || iobuf == NULL) { + return -EINVAL; + } + + if ((cdev = dnp->cdev) == NULL) { + return -EIO; + } + + return cdev->read(dnp, iobuf, flags); +} + +/* + * VFS read callback for devfs + */ +static ssize_t +devfs_read(struct vop_rw_data *args) +{ + struct vnode *vp; + struct devfs_node *dnp; + struct dev_iobuf iobuf; + + if ((vp = args->vp) == NULL) { + return -EIO; + } + + if ((dnp = vp->data) == NULL) { + return -EIO; + } + + iobuf.buf = args->data; + iobuf.count = args->len; + iobuf.off = args->off; + if (dnp->type == DEVFS_CDEV) { + return devfs_cdev_read(dnp, &iobuf, 0); + } + + return -EIO; +} + +/* * Initialize the device filesystem */ static int @@ -157,7 +206,8 @@ devfs_mount(struct fs_info *fip, struct mount_args *margs) } static struct vop devfs_vops = { - .lookup = devfs_lookup + .lookup = devfs_lookup, + .read = devfs_read }; struct vfsops g_devfs_vfsops = { diff --git a/src/sys/fs/tmpfs.c b/src/sys/fs/tmpfs.c index af1537f..3048fb4 100644 --- a/src/sys/fs/tmpfs.c +++ b/src/sys/fs/tmpfs.c @@ -49,6 +49,7 @@ struct tmpfs_node { size_t len; size_t real_len; int ref; + vtype_t vtype; /* vnode vtype mapping */ TAILQ_ENTRY(tmpfs_node) link; }; @@ -62,13 +63,14 @@ static struct vop tmpfs_vops; * Create a new tmpfs node * * @name: Name of node to create + * @type: Type of vnode file should be associated with * @np_res: Result pointer is written here * * Returns zero on success, otherwise a less than * zero value on failure */ static int -tmpfs_new(const char *name, struct tmpfs_node **np_res) +tmpfs_new(const char *name, vtype_t type, struct tmpfs_node **np_res) { struct tmpfs_node *np; size_t name_len; @@ -97,6 +99,7 @@ tmpfs_new(const char *name, struct tmpfs_node **np_res) np->real_len = 0; np->len = TMPFS_INIT_SIZE; np->ref = 1; + np->vtype = type; memset(np->data, 0, TMPFS_INIT_SIZE); memcpy(np->name, name, name_len); @@ -162,7 +165,7 @@ tmpfs_lookup(struct vop_lookup_args *args) return error; } - error = vfs_valloc(&vp, VTYPE_FILE, 0); + error = vfs_valloc(&vp, np->vtype, 0); if (error < 0) { return error; } @@ -197,7 +200,16 @@ tmpfs_create(struct vop_create_args *args) return -EEXIST; } - return tmpfs_new(ndp->path, NULL); + /* Only accept the types we support */ + switch (args->vtype) { + case VTYPE_FILE: + case VTYPE_SOCK: + break; + default: + return -ENOTSUP; + } + + return tmpfs_new(ndp->path, args->vtype, NULL); } /* |