Author: kib
Date: Wed Oct 15 13:16:51 2014
New Revision: 273131
URL: https://svnweb.freebsd.org/changeset/base/273131

Log:
  When vnode bypass cannot be performed on the cdev file descriptor for
  read/write/poll/ioctl, call standard vnode filedescriptor fop.  This
  restores the special handling for terminals by calling the deadfs VOP,
  instead of always returning ENXIO for destroyed devices or revoked
  terminals.
  
  Since destroyed (and not revoked) device would use devfs_specops VOP
  vector, make dead_read/write/poll non-static and fill VOP table with
  pointers to the functions, to instead of VOP_PANIC.
  
  Noted and reviewed by:        bde
  Sponsored by: The FreeBSD Foundation
  MFC after:    1 week

Modified:
  head/sys/fs/deadfs/dead_vnops.c
  head/sys/fs/devfs/devfs_vnops.c
  head/sys/sys/vnode.h

Modified: head/sys/fs/deadfs/dead_vnops.c
==============================================================================
--- head/sys/fs/deadfs/dead_vnops.c     Wed Oct 15 13:08:53 2014        
(r273130)
+++ head/sys/fs/deadfs/dead_vnops.c     Wed Oct 15 13:16:51 2014        
(r273131)
@@ -43,9 +43,6 @@
  */
 static vop_lookup_t    dead_lookup;
 static vop_open_t      dead_open;
-static vop_poll_t      dead_poll;
-static vop_read_t      dead_read;
-static vop_write_t     dead_write;
 static vop_getwritemount_t dead_getwritemount;
 static vop_rename_t    dead_rename;
 
@@ -130,7 +127,7 @@ dead_open(ap)
  * Vnode op for read
  */
 /* ARGSUSED */
-static int
+int
 dead_read(ap)
        struct vop_read_args /* {
                struct vnode *a_vp;
@@ -151,7 +148,7 @@ dead_read(ap)
  * Vnode op for write
  */
 /* ARGSUSED */
-static int
+int
 dead_write(ap)
        struct vop_write_args /* {
                struct vnode *a_vp;
@@ -163,7 +160,7 @@ dead_write(ap)
        return (EIO);
 }
 
-static int
+int
 dead_poll(ap)
        struct vop_poll_args *ap;
 {

Modified: head/sys/fs/devfs/devfs_vnops.c
==============================================================================
--- head/sys/fs/devfs/devfs_vnops.c     Wed Oct 15 13:08:53 2014        
(r273130)
+++ head/sys/fs/devfs/devfs_vnops.c     Wed Oct 15 13:16:51 2014        
(r273131)
@@ -737,8 +737,10 @@ devfs_ioctl_f(struct file *fp, u_long co
 
        fpop = td->td_fpop;
        error = devfs_fp_check(fp, &dev, &dsw, &ref);
-       if (error)
+       if (error != 0) {
+               error = vnops.fo_ioctl(fp, com, data, cred, td);
                return (error);
+       }
 
        if (com == FIODTYPE) {
                *(int *)data = dsw->d_flags & D_TYPEMASK;
@@ -1152,8 +1154,10 @@ devfs_poll_f(struct file *fp, int events
 
        fpop = td->td_fpop;
        error = devfs_fp_check(fp, &dev, &dsw, &ref);
-       if (error)
-               return (poll_no_poll(events));
+       if (error != 0) {
+               error = vnops.fo_poll(fp, events, cred, td);
+               return (error);
+       }
        error = dsw->d_poll(dev, events, td);
        td->td_fpop = fpop;
        dev_relthread(dev, ref);
@@ -1185,8 +1189,10 @@ devfs_read_f(struct file *fp, struct uio
                return (EINVAL);
        fpop = td->td_fpop;
        error = devfs_fp_check(fp, &dev, &dsw, &ref);
-       if (error)
+       if (error != 0) {
+               error = vnops.fo_read(fp, uio, cred, flags, td);
                return (error);
+       }
        resid = uio->uio_resid;
        ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT);
        if (ioflag & O_DIRECT)
@@ -1660,8 +1666,10 @@ devfs_write_f(struct file *fp, struct ui
                return (EINVAL);
        fpop = td->td_fpop;
        error = devfs_fp_check(fp, &dev, &dsw, &ref);
-       if (error)
+       if (error != 0) {
+               error = vnops.fo_write(fp, uio, cred, flags, td);
                return (error);
+       }
        KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td));
        ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT | O_FSYNC);
        if (ioflag & O_DIRECT)
@@ -1744,8 +1752,9 @@ static struct vop_vector devfs_specops =
        .vop_mknod =            VOP_PANIC,
        .vop_open =             devfs_open,
        .vop_pathconf =         devfs_pathconf,
+       .vop_poll =             dead_poll,
        .vop_print =            devfs_print,
-       .vop_read =             VOP_PANIC,
+       .vop_read =             dead_read,
        .vop_readdir =          VOP_PANIC,
        .vop_readlink =         VOP_PANIC,
        .vop_reallocblks =      VOP_PANIC,
@@ -1761,7 +1770,7 @@ static struct vop_vector devfs_specops =
        .vop_strategy =         VOP_PANIC,
        .vop_symlink =          VOP_PANIC,
        .vop_vptocnp =          devfs_vptocnp,
-       .vop_write =            VOP_PANIC,
+       .vop_write =            dead_write,
 };
 
 /*

Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h        Wed Oct 15 13:08:53 2014        (r273130)
+++ head/sys/sys/vnode.h        Wed Oct 15 13:16:51 2014        (r273131)
@@ -758,6 +758,9 @@ int vop_enoent(struct vop_generic_args *
 int    vop_enotty(struct vop_generic_args *ap);
 int    vop_null(struct vop_generic_args *ap);
 int    vop_panic(struct vop_generic_args *ap);
+int    dead_poll(struct vop_poll_args *ap);
+int    dead_read(struct vop_read_args *ap);
+int    dead_write(struct vop_write_args *ap);
 
 /* These are called from within the actual VOPS. */
 void   vop_create_post(void *a, int rc);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to