Author: kib
Date: Wed Jun 24 09:42:18 2009
New Revision: 194815
URL: http://svn.freebsd.org/changeset/base/194815

Log:
  MFC r193919:
  Lock the vnode in cd9660, devfs and pseudofs implementation of VOP_IOCTL
  to prevent reclaim, since the vnode is passed unlocked to the VOP.
  
  MFC r193930:
  For cd9660_ioctl, check for recycled vnode after locking it.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/fs/cd9660/cd9660_vnops.c
  stable/7/sys/fs/devfs/devfs_vnops.c
  stable/7/sys/fs/pseudofs/pseudofs_vnops.c

Modified: stable/7/sys/fs/cd9660/cd9660_vnops.c
==============================================================================
--- stable/7/sys/fs/cd9660/cd9660_vnops.c       Wed Jun 24 09:26:33 2009        
(r194814)
+++ stable/7/sys/fs/cd9660/cd9660_vnops.c       Wed Jun 24 09:42:18 2009        
(r194815)
@@ -253,20 +253,35 @@ cd9660_ioctl(ap)
                struct thread *a_td;
        } */ *ap;
 {
-       struct vnode *vp = ap->a_vp;
-       struct iso_node *ip = VTOI(vp);
+       struct vnode *vp;
+       struct iso_node *ip;
+       int error;
 
-       if (vp->v_type == VCHR || vp->v_type == VBLK)
+       vp = ap->a_vp;
+       vn_lock(vp, LK_SHARED | LK_RETRY, ap->a_td);
+       if (vp->v_iflag & VI_DOOMED) {
+               VOP_UNLOCK(vp, 0, ap->a_td);
+               return (EBADF);
+       }
+       if (vp->v_type == VCHR || vp->v_type == VBLK) {
+               VOP_UNLOCK(vp, 0, ap->a_td);
                return (EOPNOTSUPP);
+       }
 
-       switch (ap->a_command) {
+       ip = VTOI(vp);
+       error = 0;
 
+       switch (ap->a_command) {
        case FIOGETLBA:
                *(int *)(ap->a_data) = ip->iso_start;
-               return 0;
+               break;
        default:
-               return (ENOTTY);
+               error = ENOTTY;
+               break;
        }
+
+       VOP_UNLOCK(vp, 0, ap->a_td);
+       return (error);
 }
 
 /*

Modified: stable/7/sys/fs/devfs/devfs_vnops.c
==============================================================================
--- stable/7/sys/fs/devfs/devfs_vnops.c Wed Jun 24 09:26:33 2009        
(r194814)
+++ stable/7/sys/fs/devfs/devfs_vnops.c Wed Jun 24 09:42:18 2009        
(r194815)
@@ -1240,11 +1240,19 @@ devfs_revoke(struct vop_revoke_args *ap)
 static int
 devfs_rioctl(struct vop_ioctl_args *ap)
 {
-       int error;
+       struct vnode *vp;
        struct devfs_mount *dmp;
+       int error;
 
-       dmp = VFSTODEVFS(ap->a_vp->v_mount);
+       vp = ap->a_vp;
+       vn_lock(vp, LK_SHARED | LK_RETRY, ap->a_td);
+       if (vp->v_iflag & VI_DOOMED) {
+               VOP_UNLOCK(vp, 0, ap->a_td);
+               return (EBADF);
+       }
+       dmp = VFSTODEVFS(vp->v_mount);
        sx_xlock(&dmp->dm_lock);
+       VOP_UNLOCK(vp, 0, ap->a_td);
        DEVFS_DMP_HOLD(dmp);
        devfs_populate(dmp);
        if (DEVFS_DMP_DROP(dmp)) {

Modified: stable/7/sys/fs/pseudofs/pseudofs_vnops.c
==============================================================================
--- stable/7/sys/fs/pseudofs/pseudofs_vnops.c   Wed Jun 24 09:26:33 2009        
(r194814)
+++ stable/7/sys/fs/pseudofs/pseudofs_vnops.c   Wed Jun 24 09:42:18 2009        
(r194815)
@@ -260,34 +260,50 @@ pfs_getattr(struct vop_getattr_args *va)
 static int
 pfs_ioctl(struct vop_ioctl_args *va)
 {
-       struct vnode *vn = va->a_vp;
-       struct pfs_vdata *pvd = vn->v_data;
-       struct pfs_node *pn = pvd->pvd_pn;
+       struct vnode *vn;
+       struct pfs_vdata *pvd;
+       struct pfs_node *pn;
        struct proc *proc;
        int error;
 
+       vn = va->a_vp;
+       vn_lock(vn, LK_SHARED | LK_RETRY, va->a_td);
+       if (vn->v_iflag & VI_DOOMED) {
+               VOP_UNLOCK(vn, 0, va->a_td);
+               return (EBADF);
+       }
+       pvd = vn->v_data;
+       pn = pvd->pvd_pn;
+
        PFS_TRACE(("%s: %lx", pn->pn_name, va->a_command));
        pfs_assert_not_owned(pn);
 
-       if (vn->v_type != VREG)
+       if (vn->v_type != VREG) {
+               VOP_UNLOCK(vn, 0, va->a_td);
                PFS_RETURN (EINVAL);
+       }
        KASSERT_PN_IS_FILE(pn);
 
-       if (pn->pn_ioctl == NULL)
+       if (pn->pn_ioctl == NULL) {
+               VOP_UNLOCK(vn, 0, va->a_td);
                PFS_RETURN (ENOTTY);
+       }
 
        /*
         * This is necessary because process' privileges may
         * have changed since the open() call.
         */
-       if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc))
+       if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc)) {
+               VOP_UNLOCK(vn, 0, va->a_td);
                PFS_RETURN (EIO);
+       }
 
        error = pn_ioctl(curthread, proc, pn, va->a_command, va->a_data);
 
        if (proc != NULL)
                PROC_UNLOCK(proc);
 
+       VOP_UNLOCK(vn, 0, va->a_td);
        PFS_RETURN (error);
 }
 
_______________________________________________
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