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);
        }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to