From owner-svn-src-stable@FreeBSD.ORG Fri Jan 6 15:07:29 2012 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D8AB0106566B; Fri, 6 Jan 2012 15:07:28 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C067A8FC16; Fri, 6 Jan 2012 15:07:28 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q06F7SAj094820; Fri, 6 Jan 2012 15:07:28 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q06F7Sj6094812; Fri, 6 Jan 2012 15:07:28 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201201061507.q06F7Sj6094812@svn.freebsd.org> From: Konstantin Belousov Date: Fri, 6 Jan 2012 15:07:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r229703 - in stable/9: . sys/cddl/contrib/opensolaris/uts/common/fs/zfs sys/fs/devfs sys/fs/nullfs sys/fs/pseudofs sys/kern X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 06 Jan 2012 15:07:29 -0000 Author: kib Date: Fri Jan 6 15:07:28 2012 New Revision: 229703 URL: http://svn.freebsd.org/changeset/base/229703 Log: MFC r227697: Change the interface for VOP_VPTOCNP(), now the dvp must be referenced. Convert all in-tree implementations of VOP_VPTOCNP(). This fixes VOP_VPTOCNP bypass for nullfs. Approved by: re (bz) Modified: stable/9/UPDATING stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c stable/9/sys/fs/devfs/devfs_vnops.c stable/9/sys/fs/nullfs/null_vnops.c stable/9/sys/fs/pseudofs/pseudofs_vnops.c stable/9/sys/kern/vfs_cache.c stable/9/sys/kern/vfs_default.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/cddl/contrib/opensolaris/ (props changed) Modified: stable/9/UPDATING ============================================================================== --- stable/9/UPDATING Fri Jan 6 15:01:05 2012 (r229702) +++ stable/9/UPDATING Fri Jan 6 15:07:28 2012 (r229703) @@ -10,6 +10,11 @@ Items affecting the ports and packages s /usr/ports/UPDATING. Please read that file before running portupgrade. 20120106: + The interface of the VOP_VPTOCNP(9) changed, now the returned + vnode shall be referenced, previously it was required to be + only held. All in-tree filesystems are converted. + +20120106: 9.0-RELEASE. 20111101: Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c ============================================================================== --- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c Fri Jan 6 15:01:05 2012 (r229702) +++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c Fri Jan 6 15:07:28 2012 (r229703) @@ -1594,7 +1594,7 @@ zfsctl_snapshot_vptocnp(struct vop_vptoc *ap->a_buflen -= len; bcopy(sep->se_name, ap->a_buf + *ap->a_buflen, len); mutex_exit(&sdp->sd_lock); - vhold(dvp); + vref(dvp); *ap->a_vpp = dvp; } VN_RELE(dvp); Modified: stable/9/sys/fs/devfs/devfs_vnops.c ============================================================================== --- stable/9/sys/fs/devfs/devfs_vnops.c Fri Jan 6 15:01:05 2012 (r229702) +++ stable/9/sys/fs/devfs/devfs_vnops.c Fri Jan 6 15:07:28 2012 (r229703) @@ -261,7 +261,7 @@ devfs_vptocnp(struct vop_vptocnp_args *a } else if (vp->v_type == VDIR) { if (dd == dmp->dm_rootdir) { *dvp = vp; - vhold(*dvp); + vref(*dvp); goto finished; } i -= dd->de_dirent->d_namlen; @@ -289,6 +289,8 @@ devfs_vptocnp(struct vop_vptocnp_args *a mtx_unlock(&devfs_de_interlock); vholdl(*dvp); VI_UNLOCK(*dvp); + vref(*dvp); + vdrop(*dvp); } else { mtx_unlock(&devfs_de_interlock); error = ENOENT; Modified: stable/9/sys/fs/nullfs/null_vnops.c ============================================================================== --- stable/9/sys/fs/nullfs/null_vnops.c Fri Jan 6 15:01:05 2012 (r229702) +++ stable/9/sys/fs/nullfs/null_vnops.c Fri Jan 6 15:07:28 2012 (r229703) @@ -784,6 +784,7 @@ null_vptocnp(struct vop_vptocnp_args *ap vhold(lvp); VOP_UNLOCK(vp, 0); /* vp is held by vn_vptocnp_locked that called us */ ldvp = lvp; + vref(lvp); error = vn_vptocnp(&ldvp, cred, ap->a_buf, ap->a_buflen); vdrop(lvp); if (error != 0) { @@ -797,19 +798,17 @@ null_vptocnp(struct vop_vptocnp_args *ap */ error = vn_lock(ldvp, LK_EXCLUSIVE); if (error != 0) { + vrele(ldvp); vn_lock(vp, locked | LK_RETRY); - vdrop(ldvp); return (ENOENT); } vref(ldvp); - vdrop(ldvp); error = null_nodeget(vp->v_mount, ldvp, dvp); if (error == 0) { #ifdef DIAGNOSTIC NULLVPTOLOWERVP(*dvp); #endif - vhold(*dvp); - vput(*dvp); + VOP_UNLOCK(*dvp, 0); /* keep reference on *dvp */ } else vput(ldvp); Modified: stable/9/sys/fs/pseudofs/pseudofs_vnops.c ============================================================================== --- stable/9/sys/fs/pseudofs/pseudofs_vnops.c Fri Jan 6 15:01:05 2012 (r229702) +++ stable/9/sys/fs/pseudofs/pseudofs_vnops.c Fri Jan 6 15:07:28 2012 (r229703) @@ -410,8 +410,7 @@ pfs_vptocnp(struct vop_vptocnp_args *ap) } *buflen = i; - vhold(*dvp); - vput(*dvp); + VOP_UNLOCK(*dvp, 0); vn_lock(vp, locked | LK_RETRY); vfs_unbusy(mp); Modified: stable/9/sys/kern/vfs_cache.c ============================================================================== --- stable/9/sys/kern/vfs_cache.c Fri Jan 6 15:01:05 2012 (r229702) +++ stable/9/sys/kern/vfs_cache.c Fri Jan 6 15:07:28 2012 (r229703) @@ -1067,16 +1067,8 @@ vn_vptocnp(struct vnode **vp, struct ucr CACHE_RLOCK(); error = vn_vptocnp_locked(vp, cred, buf, buflen); - if (error == 0) { - /* - * vn_vptocnp_locked() dropped hold acquired by - * VOP_VPTOCNP immediately after locking the - * cache. Since we are going to drop the cache rlock, - * re-hold the result. - */ - vhold(*vp); + if (error == 0) CACHE_RUNLOCK(); - } return (error); } @@ -1095,6 +1087,9 @@ vn_vptocnp_locked(struct vnode **vp, str if (ncp != NULL) { if (*buflen < ncp->nc_nlen) { CACHE_RUNLOCK(); + vfslocked = VFS_LOCK_GIANT((*vp)->v_mount); + vrele(*vp); + VFS_UNLOCK_GIANT(vfslocked); numfullpathfail4++; error = ENOMEM; SDT_PROBE(vfs, namecache, fullpath, return, error, @@ -1105,18 +1100,23 @@ vn_vptocnp_locked(struct vnode **vp, str memcpy(buf + *buflen, ncp->nc_name, ncp->nc_nlen); SDT_PROBE(vfs, namecache, fullpath, hit, ncp->nc_dvp, ncp->nc_name, vp, 0, 0); + dvp = *vp; *vp = ncp->nc_dvp; + vref(*vp); + CACHE_RUNLOCK(); + vfslocked = VFS_LOCK_GIANT(dvp->v_mount); + vrele(dvp); + VFS_UNLOCK_GIANT(vfslocked); + CACHE_RLOCK(); return (0); } SDT_PROBE(vfs, namecache, fullpath, miss, vp, 0, 0, 0, 0); - vhold(*vp); CACHE_RUNLOCK(); vfslocked = VFS_LOCK_GIANT((*vp)->v_mount); vn_lock(*vp, LK_SHARED | LK_RETRY); error = VOP_VPTOCNP(*vp, &dvp, cred, buf, buflen); - VOP_UNLOCK(*vp, 0); - vdrop(*vp); + vput(*vp); VFS_UNLOCK_GIANT(vfslocked); if (error) { numfullpathfail2++; @@ -1127,16 +1127,20 @@ vn_vptocnp_locked(struct vnode **vp, str *vp = dvp; CACHE_RLOCK(); - if ((*vp)->v_iflag & VI_DOOMED) { + if (dvp->v_iflag & VI_DOOMED) { /* forced unmount */ CACHE_RUNLOCK(); - vdrop(*vp); + vfslocked = VFS_LOCK_GIANT(dvp->v_mount); + vrele(dvp); + VFS_UNLOCK_GIANT(vfslocked); error = ENOENT; SDT_PROBE(vfs, namecache, fullpath, return, error, vp, NULL, 0, 0); return (error); } - vdrop(*vp); + /* + * *vp has its use count incremented still. + */ return (0); } @@ -1148,10 +1152,11 @@ static int vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, char *buf, char **retbuf, u_int buflen) { - int error, slash_prefixed; + int error, slash_prefixed, vfslocked; #ifdef KDTRACE_HOOKS struct vnode *startvp = vp; #endif + struct vnode *vp1; buflen--; buf[buflen] = '\0'; @@ -1160,6 +1165,7 @@ vn_fullpath1(struct thread *td, struct v SDT_PROBE(vfs, namecache, fullpath, entry, vp, 0, 0, 0, 0); numfullpathcalls++; + vref(vp); CACHE_RLOCK(); if (vp->v_type != VDIR) { error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen); @@ -1167,6 +1173,9 @@ vn_fullpath1(struct thread *td, struct v return (error); if (buflen == 0) { CACHE_RUNLOCK(); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); + VFS_UNLOCK_GIANT(vfslocked); return (ENOMEM); } buf[--buflen] = '/'; @@ -1176,16 +1185,29 @@ vn_fullpath1(struct thread *td, struct v if (vp->v_vflag & VV_ROOT) { if (vp->v_iflag & VI_DOOMED) { /* forced unmount */ CACHE_RUNLOCK(); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); + VFS_UNLOCK_GIANT(vfslocked); error = ENOENT; SDT_PROBE(vfs, namecache, fullpath, return, error, vp, NULL, 0, 0); break; } - vp = vp->v_mount->mnt_vnodecovered; + vp1 = vp->v_mount->mnt_vnodecovered; + vref(vp1); + CACHE_RUNLOCK(); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); + VFS_UNLOCK_GIANT(vfslocked); + vp = vp1; + CACHE_RLOCK(); continue; } if (vp->v_type != VDIR) { CACHE_RUNLOCK(); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); + VFS_UNLOCK_GIANT(vfslocked); numfullpathfail1++; error = ENOTDIR; SDT_PROBE(vfs, namecache, fullpath, return, @@ -1197,6 +1219,9 @@ vn_fullpath1(struct thread *td, struct v break; if (buflen == 0) { CACHE_RUNLOCK(); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); + VFS_UNLOCK_GIANT(vfslocked); error = ENOMEM; SDT_PROBE(vfs, namecache, fullpath, return, error, startvp, NULL, 0, 0); @@ -1210,6 +1235,9 @@ vn_fullpath1(struct thread *td, struct v if (!slash_prefixed) { if (buflen == 0) { CACHE_RUNLOCK(); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); + VFS_UNLOCK_GIANT(vfslocked); numfullpathfail4++; SDT_PROBE(vfs, namecache, fullpath, return, ENOMEM, startvp, NULL, 0, 0); @@ -1219,6 +1247,9 @@ vn_fullpath1(struct thread *td, struct v } numfullpathfound++; CACHE_RUNLOCK(); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); + VFS_UNLOCK_GIANT(vfslocked); SDT_PROBE(vfs, namecache, fullpath, return, 0, startvp, buf + buflen, 0, 0); Modified: stable/9/sys/kern/vfs_default.c ============================================================================== --- stable/9/sys/kern/vfs_default.c Fri Jan 6 15:01:05 2012 (r229702) +++ stable/9/sys/kern/vfs_default.c Fri Jan 6 15:07:28 2012 (r229703) @@ -843,7 +843,7 @@ out: free(dirbuf, M_TEMP); if (!error) { *buflen = i; - vhold(*dvp); + vref(*dvp); } if (covered) { vput(*dvp);