diff options
Diffstat (limited to 'sys/fs/ctlfs.c')
-rw-r--r-- | sys/fs/ctlfs.c | 92 |
1 files changed, 63 insertions, 29 deletions
diff --git a/sys/fs/ctlfs.c b/sys/fs/ctlfs.c index efbf448..b86fa0a 100644 --- a/sys/fs/ctlfs.c +++ b/sys/fs/ctlfs.c @@ -234,6 +234,35 @@ ctlfs_lookup(struct vop_lookup_args *args) return 0; } +static int +ctlfs_get_ops(struct vnode *vp, struct ctlfs_entry **enpres, + const struct ctlops **iopres) +{ + const struct ctlops *iop; + struct ctlfs_entry *enp; + + if (enpres == NULL || iopres == NULL) { + return -EINVAL; + } + + if ((enp = vp->data) == NULL) { + pr_error("no vnode data for ctlfs entry\n"); + return -EIO; + } + if (enp->magic != CTLFS_ENTRY_MAG) { + pr_error("ctlfs entry has bad magic\n"); + return -EIO; + } + if ((iop = enp->io) == NULL) { + pr_error("no i/o ops for ctlfs entry\n"); + return -EIO; + } + + *enpres = enp; + *iopres = iop; + return 0; +} + /* * Create a ctlfs node (directory) within the * root fs. @@ -344,18 +373,10 @@ ctlfs_read(struct vnode *vp, struct sio_txn *sio) const struct ctlops *iop; struct ctlfs_entry *enp; struct ctlfs_dev dev; + int error; - if ((enp = vp->data) == NULL) { - pr_error("no vnode data for ctlfs entry\n"); - return -EIO; - } - if (enp->magic != CTLFS_ENTRY_MAG) { - pr_error("ctlfs entry has bad magic\n"); - return -EIO; - } - if ((iop = enp->io) == NULL) { - pr_error("no i/o ops for ctlfs entry\n"); - return -EIO; + if ((error = ctlfs_get_ops(vp, &enp, &iop)) < 0) { + return error; } if (iop->read == NULL) { pr_trace("no read op for ctlfs entry\n"); @@ -368,28 +389,40 @@ ctlfs_read(struct vnode *vp, struct sio_txn *sio) return iop->read(&dev, sio); } +/* + * Write a control file + * + * Args passed to driver: + * - ctlfs_dev.ctlname + * - ctlfs_dev.iop + * - ctlfs_dev.mode + */ static int -ctlfs_reclaim(struct vnode *vp) +ctlfs_write(struct vnode *vp, struct sio_txn *sio) { - struct ctlfs_hdr *hp; + const struct ctlops *iop; + struct ctlfs_entry *enp; + struct ctlfs_dev dev; + int error; - if (vp->data == NULL) { - return 0; + if ((error = ctlfs_get_ops(vp, &enp, &iop)) < 0) { + return error; } - - /* Ensure the magic is correct */ - hp = vp->data; - switch (hp->magic) { - case CTLFS_NODE_MAG: - case CTLFS_ENTRY_MAG: - dynfree(hp->name); - break; - default: - pr_error("reclaim: bad magic in vp\n"); - break; + if (iop->write == NULL) { + pr_trace("no write op for ctlfs entry\n"); + return -EIO; } - dynfree(vp->data); + dev.ctlname = enp->name; + dev.ops = iop; + dev.mode = enp->mode; + return iop->write(&dev, sio); +} + +static int +ctlfs_reclaim(struct vnode *vp) +{ + vp->data = NULL; return 0; } @@ -397,8 +430,9 @@ static const struct vops ctlfs_vops = { .lookup = ctlfs_lookup, .read = ctlfs_read, .getattr = NULL, - .write = NULL, - .reclaim = ctlfs_reclaim + .write = ctlfs_write, + .reclaim = ctlfs_reclaim, + .create = NULL }; const struct vfsops g_ctlfs_vfsops = { |