summaryrefslogtreecommitdiff
path: root/sys/fs/ctlfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/ctlfs.c')
-rw-r--r--sys/fs/ctlfs.c92
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 = {