svn commit: r303310 - in head/sys: fs/devfs kern
Conrad E. Meyer
cem at FreeBSD.org
Mon Jul 25 16:28:03 UTC 2016
Author: cem
Date: Mon Jul 25 16:28:02 2016
New Revision: 303310
URL: https://svnweb.freebsd.org/changeset/base/303310
Log:
devfs: Move most ioctl logic down to vnode layer
Devfs' file layer ioctl is now just a thin shim around the vnode layer.
Reviewed by: kib
Sponsored by: EMC / Isilon Storage Division
Differential Revision: https://reviews.freebsd.org/D7286
Modified:
head/sys/fs/devfs/devfs_vnops.c
head/sys/kern/vfs_vnops.c
Modified: head/sys/fs/devfs/devfs_vnops.c
==============================================================================
--- head/sys/fs/devfs/devfs_vnops.c Mon Jul 25 16:18:20 2016 (r303309)
+++ head/sys/fs/devfs/devfs_vnops.c Mon Jul 25 16:28:02 2016 (r303310)
@@ -779,47 +779,61 @@ devfs_getattr(struct vop_getattr_args *a
static int
devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, struct thread *td)
{
- struct cdev *dev;
- struct cdevsw *dsw;
- struct vnode *vp;
- struct vnode *vpold;
- int error, i, ref;
- const char *p;
- struct fiodgname_arg *fgn;
struct file *fpop;
+ int error;
fpop = td->td_fpop;
- error = devfs_fp_check(fp, &dev, &dsw, &ref);
- if (error != 0) {
- error = vnops.fo_ioctl(fp, com, data, cred, td);
- return (error);
- }
+ td->td_fpop = fp;
+ error = vnops.fo_ioctl(fp, com, data, cred, td);
+ td->td_fpop = fpop;
+ return (error);
+}
+
+static int
+devfs_ioctl(struct vop_ioctl_args *ap)
+{
+ struct fiodgname_arg *fgn;
+ struct vnode *vpold, *vp;
+ struct cdevsw *dsw;
+ struct thread *td;
+ struct cdev *dev;
+ int error, ref, i;
+ const char *p;
+ u_long com;
+
+ vp = ap->a_vp;
+ com = ap->a_command;
+ td = ap->a_td;
+
+ dsw = devvn_refthread(vp, &dev, &ref);
+ if (dsw == NULL)
+ return (ENXIO);
+ KASSERT(dev->si_refcount > 0,
+ ("devfs: un-referenced struct cdev *(%s)", devtoname(dev)));
if (com == FIODTYPE) {
- *(int *)data = dsw->d_flags & D_TYPEMASK;
- td->td_fpop = fpop;
- dev_relthread(dev, ref);
- return (0);
+ *(int *)ap->a_data = dsw->d_flags & D_TYPEMASK;
+ error = 0;
+ goto out;
} else if (com == FIODGNAME) {
- fgn = data;
+ fgn = ap->a_data;
p = devtoname(dev);
i = strlen(p) + 1;
if (i > fgn->len)
error = EINVAL;
else
error = copyout(p, fgn->buf, i);
- td->td_fpop = fpop;
- dev_relthread(dev, ref);
- return (error);
+ goto out;
}
- error = dsw->d_ioctl(dev, com, data, fp->f_flag, td);
- td->td_fpop = NULL;
+
+ error = dsw->d_ioctl(dev, com, ap->a_data, ap->a_fflag, td);
+
+out:
dev_relthread(dev, ref);
if (error == ENOIOCTL)
error = ENOTTY;
- if (error == 0 && com == TIOCSCTTY) {
- vp = fp->f_vnode;
+ if (error == 0 && com == TIOCSCTTY) {
/* Do nothing if reassigning same control tty */
sx_slock(&proctree_lock);
if (td->td_proc->p_session->s_ttyvp == vp) {
@@ -1862,6 +1876,7 @@ static struct fileops devfs_ops_f = {
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
+/* Vops for non-CHR vnodes in /dev. */
static struct vop_vector devfs_vnodeops = {
.vop_default = &default_vnodeops,
@@ -1885,6 +1900,7 @@ static struct vop_vector devfs_vnodeops
.vop_vptocnp = devfs_vptocnp,
};
+/* Vops for VCHR vnodes in /dev. */
static struct vop_vector devfs_specops = {
.vop_default = &default_vnodeops,
@@ -1894,6 +1910,7 @@ static struct vop_vector devfs_specops =
.vop_create = VOP_PANIC,
.vop_fsync = devfs_fsync,
.vop_getattr = devfs_getattr,
+ .vop_ioctl = devfs_ioctl,
.vop_link = VOP_PANIC,
.vop_mkdir = VOP_PANIC,
.vop_mknod = VOP_PANIC,
Modified: head/sys/kern/vfs_vnops.c
==============================================================================
--- head/sys/kern/vfs_vnops.c Mon Jul 25 16:18:20 2016 (r303309)
+++ head/sys/kern/vfs_vnops.c Mon Jul 25 16:28:02 2016 (r303310)
@@ -1492,6 +1492,10 @@ vn_ioctl(fp, com, data, active_cred, td)
return (VOP_IOCTL(vp, com, data, fp->f_flag,
active_cred, td));
}
+ break;
+ case VCHR:
+ return (VOP_IOCTL(vp, com, data, fp->f_flag,
+ active_cred, td));
default:
return (ENOTTY);
}
More information about the svn-src-head
mailing list