Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Jan 2020 22:12:25 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r356336 - head/sys/fs/unionfs
Message-ID:  <202001032212.003MCP5L067726@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Fri Jan  3 22:12:25 2020
New Revision: 356336
URL: https://svnweb.freebsd.org/changeset/base/356336

Log:
  unionfs: fix up VOP_UNLOCK use after flags stopped being supported
  
  For the most part the code was passing the LK_RELEASE flag.
  The 2 cases which did not use the VOP_UNLOCK_FLAGS macro.
  
  This fixes a panic when stacking unionfs on top of e.g., tmpfs when
  debug is enabled.
  
  Note there are latent bugs which prevent unionfs from working with debug
  regardless of this change.
  
  PR:		243064
  Reported by:	Mason Loring Bliss

Modified:
  head/sys/fs/unionfs/union_subr.c
  head/sys/fs/unionfs/union_vfsops.c
  head/sys/fs/unionfs/union_vnops.c

Modified: head/sys/fs/unionfs/union_subr.c
==============================================================================
--- head/sys/fs/unionfs/union_subr.c	Fri Jan  3 22:10:11 2020	(r356335)
+++ head/sys/fs/unionfs/union_subr.c	Fri Jan  3 22:12:25 2020	(r356336)
@@ -361,9 +361,9 @@ unionfs_noderem(struct vnode *vp, struct thread *td)
 	VI_UNLOCK(vp);
 
 	if (lvp != NULLVP)
-		VOP_UNLOCK(lvp, LK_RELEASE);
+		VOP_UNLOCK(lvp, 0);
 	if (uvp != NULLVP)
-		VOP_UNLOCK(uvp, LK_RELEASE);
+		VOP_UNLOCK(uvp, 0);
 
 	if (dvp != NULLVP && unp->un_hash.le_prev != NULL)
 		unionfs_rem_cached_vnode(unp, dvp);
@@ -551,7 +551,7 @@ unionfs_relookup(struct vnode *dvp, struct vnode **vpp
 		cn->cn_flags |= NOCACHE;
 
 	vref(dvp);
-	VOP_UNLOCK(dvp, LK_RELEASE);
+	VOP_UNLOCK(dvp, 0);
 
 	if ((error = relookup(dvp, vpp, cn))) {
 		uma_zfree(namei_zone, cn->cn_pnbuf);
@@ -961,7 +961,7 @@ unionfs_vn_create_on_upper(struct vnode **vpp, struct 
 	}
 
 unionfs_vn_create_on_upper_free_out1:
-	VOP_UNLOCK(udvp, LK_RELEASE);
+	VOP_UNLOCK(udvp, 0);
 
 unionfs_vn_create_on_upper_free_out2:
 	if (cn.cn_flags & HASBUF) {

Modified: head/sys/fs/unionfs/union_vfsops.c
==============================================================================
--- head/sys/fs/unionfs/union_vfsops.c	Fri Jan  3 22:10:11 2020	(r356335)
+++ head/sys/fs/unionfs/union_vfsops.c	Fri Jan  3 22:12:25 2020	(r356336)
@@ -167,7 +167,7 @@ unionfs_domount(struct mount *mp)
 		uid = va.va_uid;
 		gid = va.va_gid;
 	}
-	VOP_UNLOCK(mp->mnt_vnodecovered, LK_RELEASE);
+	VOP_UNLOCK(mp->mnt_vnodecovered, 0);
 	if (error)
 		return (error);
 
@@ -252,7 +252,7 @@ unionfs_domount(struct mount *mp)
 	 * Save reference
 	 */
 	if (below) {
-		VOP_UNLOCK(upperrootvp, LK_RELEASE);
+		VOP_UNLOCK(upperrootvp, 0);
 		vn_lock(lowerrootvp, LK_EXCLUSIVE | LK_RETRY);
 		ump->um_lowervp = upperrootvp;
 		ump->um_uppervp = lowerrootvp;
@@ -278,7 +278,7 @@ unionfs_domount(struct mount *mp)
 	/*
 	 * Unlock the node
 	 */
-	VOP_UNLOCK(ump->um_uppervp, LK_RELEASE);
+	VOP_UNLOCK(ump->um_uppervp, 0);
 
 	/*
 	 * Get the unionfs root vnode.

Modified: head/sys/fs/unionfs/union_vnops.c
==============================================================================
--- head/sys/fs/unionfs/union_vnops.c	Fri Jan  3 22:10:11 2020	(r356335)
+++ head/sys/fs/unionfs/union_vnops.c	Fri Jan  3 22:12:25 2020	(r356336)
@@ -128,7 +128,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
 		if (udvp != NULLVP) {
 			dtmpvp = udvp;
 			if (ldvp != NULLVP)
-				VOP_UNLOCK(ldvp, LK_RELEASE);
+				VOP_UNLOCK(ldvp, 0);
 		}
 		else
 			dtmpvp = ldvp;
@@ -136,7 +136,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
 		error = VOP_LOOKUP(dtmpvp, &vp, cnp);
 
 		if (dtmpvp == udvp && ldvp != NULLVP) {
-			VOP_UNLOCK(udvp, LK_RELEASE);
+			VOP_UNLOCK(udvp, 0);
 			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
 		}
 
@@ -148,10 +148,10 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
 			 */
 			if (nameiop == DELETE  || nameiop == RENAME ||
 			    (cnp->cn_lkflags & LK_TYPE_MASK))
-				VOP_UNLOCK(vp, LK_RELEASE);
+				VOP_UNLOCK(vp, 0);
 			vrele(vp);
 
-			VOP_UNLOCK(dvp, LK_RELEASE);
+			VOP_UNLOCK(dvp, 0);
 			*(ap->a_vpp) = dunp->un_dvp;
 			vref(dunp->un_dvp);
 
@@ -188,7 +188,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
 			}
 			if (nameiop == DELETE || nameiop == RENAME ||
 			    (cnp->cn_lkflags & LK_TYPE_MASK))
-				VOP_UNLOCK(uvp, LK_RELEASE);
+				VOP_UNLOCK(uvp, 0);
 		}
 
 		/* check whiteout */
@@ -232,7 +232,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
 				return (lerror);
 			}
 			if (cnp->cn_lkflags & LK_TYPE_MASK)
-				VOP_UNLOCK(lvp, LK_RELEASE);
+				VOP_UNLOCK(lvp, 0);
 		}
 	}
 
@@ -267,7 +267,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
 			goto unionfs_lookup_out;
 
 		if (LK_SHARED == (cnp->cn_lkflags & LK_TYPE_MASK))
-			VOP_UNLOCK(vp, LK_RELEASE);
+			VOP_UNLOCK(vp, 0);
 		if (LK_EXCLUSIVE != VOP_ISLOCKED(vp)) {
 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 			lockflag = 1;
@@ -275,7 +275,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
 		error = unionfs_mkshadowdir(MOUNTTOUNIONFSMOUNT(dvp->v_mount),
 		    udvp, VTOUNIONFS(vp), cnp, td);
 		if (lockflag != 0)
-			VOP_UNLOCK(vp, LK_RELEASE);
+			VOP_UNLOCK(vp, 0);
 		if (error != 0) {
 			UNIONFSDEBUG("unionfs_lookup: Unable to create shadow dir.");
 			if ((cnp->cn_lkflags & LK_TYPE_MASK) == LK_EXCLUSIVE)
@@ -372,7 +372,7 @@ unionfs_create(struct vop_create_args *ap)
 		if (vp->v_type == VSOCK)
 			*(ap->a_vpp) = vp;
 		else {
-			VOP_UNLOCK(vp, LK_RELEASE);
+			VOP_UNLOCK(vp, 0);
 			error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
 			    ap->a_dvp, ap->a_vpp, cnp, curthread);
 			vrele(vp);
@@ -446,7 +446,7 @@ unionfs_mknod(struct vop_mknod_args *ap)
 		if (vp->v_type == VSOCK)
 			*(ap->a_vpp) = vp;
 		else {
-			VOP_UNLOCK(vp, LK_RELEASE);
+			VOP_UNLOCK(vp, 0);
 			error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
 			    ap->a_dvp, ap->a_vpp, cnp, curthread);
 			vrele(vp);
@@ -903,7 +903,7 @@ unionfs_ioctl(struct vop_ioctl_args *ap)
 	unionfs_get_node_status(unp, ap->a_td, &unsp);
 	ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
 	unionfs_tryrem_node_status(unp, unsp);
-	VOP_UNLOCK(ap->a_vp, LK_RELEASE);
+	VOP_UNLOCK(ap->a_vp, 0);
 
 	if (ovp == NULLVP)
 		return (EBADF);
@@ -930,7 +930,7 @@ unionfs_poll(struct vop_poll_args *ap)
 	unionfs_get_node_status(unp, ap->a_td, &unsp);
 	ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
 	unionfs_tryrem_node_status(unp, unsp);
-	VOP_UNLOCK(ap->a_vp, LK_RELEASE);
+	VOP_UNLOCK(ap->a_vp, 0);
 
 	if (ovp == NULLVP)
 		return (EBADF);
@@ -990,7 +990,7 @@ unionfs_remove(struct vop_remove_args *ap)
 		ump = NULL;
 		vp = uvp = lvp = NULLVP;
 		/* search vnode */
-		VOP_UNLOCK(ap->a_vp, LK_RELEASE);
+		VOP_UNLOCK(ap->a_vp, 0);
 		error = unionfs_relookup(udvp, &vp, cnp, &cn, td,
 		    cnp->cn_nameptr, strlen(cnp->cn_nameptr), DELETE);
 		if (error != 0 && error != ENOENT) {
@@ -1193,7 +1193,7 @@ unionfs_rename(struct vop_rename_args *ap)
 			if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
 				goto unionfs_rename_abort;
 			error = unionfs_copyfile(unp, 1, fcnp->cn_cred, td);
-			VOP_UNLOCK(fvp, LK_RELEASE);
+			VOP_UNLOCK(fvp, 0);
 			if (error != 0)
 				goto unionfs_rename_abort;
 			break;
@@ -1201,7 +1201,7 @@ unionfs_rename(struct vop_rename_args *ap)
 			if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
 				goto unionfs_rename_abort;
 			error = unionfs_mkshadowdir(ump, rfdvp, unp, fcnp, td);
-			VOP_UNLOCK(fvp, LK_RELEASE);
+			VOP_UNLOCK(fvp, 0);
 			if (error != 0)
 				goto unionfs_rename_abort;
 			break;
@@ -1258,13 +1258,13 @@ unionfs_rename(struct vop_rename_args *ap)
 		if ((error = vn_lock(fdvp, LK_EXCLUSIVE)) != 0)
 			goto unionfs_rename_abort;
 		error = unionfs_relookup_for_delete(fdvp, fcnp, td);
-		VOP_UNLOCK(fdvp, LK_RELEASE);
+		VOP_UNLOCK(fdvp, 0);
 		if (error != 0)
 			goto unionfs_rename_abort;
 
 		/* Locke of tvp is canceled in order to avoid recursive lock. */
 		if (tvp != NULLVP && tvp != tdvp)
-			VOP_UNLOCK(tvp, LK_RELEASE);
+			VOP_UNLOCK(tvp, 0);
 		error = unionfs_relookup_for_rename(tdvp, tcnp, td);
 		if (tvp != NULLVP && tvp != tdvp)
 			vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY);
@@ -1282,11 +1282,11 @@ unionfs_rename(struct vop_rename_args *ap)
 	}
 
 	if (ltdvp != NULLVP)
-		VOP_UNLOCK(ltdvp, LK_RELEASE);
+		VOP_UNLOCK(ltdvp, 0);
 	if (tdvp != rtdvp)
 		vrele(tdvp);
 	if (ltvp != NULLVP)
-		VOP_UNLOCK(ltvp, LK_RELEASE);
+		VOP_UNLOCK(ltvp, 0);
 	if (tvp != rtvp && tvp != NULLVP) {
 		if (rtvp == NULLVP)
 			vput(tvp);
@@ -1360,7 +1360,7 @@ unionfs_mkdir(struct vop_mkdir_args *ap)
 		}
 
 		if ((error = VOP_MKDIR(udvp, &uvp, cnp, ap->a_vap)) == 0) {
-			VOP_UNLOCK(uvp, LK_RELEASE);
+			VOP_UNLOCK(uvp, 0);
 			cnp->cn_lkflags = LK_EXCLUSIVE;
 			error = unionfs_nodeget(ap->a_dvp->v_mount, uvp, NULLVP,
 			    ap->a_dvp, ap->a_vpp, cnp, td);
@@ -1458,7 +1458,7 @@ unionfs_symlink(struct vop_symlink_args *ap)
 	if (udvp != NULLVP) {
 		error = VOP_SYMLINK(udvp, &uvp, cnp, ap->a_vap, ap->a_target);
 		if (error == 0) {
-			VOP_UNLOCK(uvp, LK_RELEASE);
+			VOP_UNLOCK(uvp, 0);
 			cnp->cn_lkflags = LK_EXCLUSIVE;
 			error = unionfs_nodeget(ap->a_dvp->v_mount, uvp, NULLVP,
 			    ap->a_dvp, ap->a_vpp, cnp, td);
@@ -1817,7 +1817,7 @@ static void
 unionfs_revlock(struct vnode *vp, int flags)
 {
 	if (flags & LK_RELEASE)
-		VOP_UNLOCK(vp, flags);
+		VOP_UNLOCK_FLAGS(vp, flags);
 	else {
 		/* UPGRADE */
 		if (vn_lock(vp, flags) != 0)
@@ -1849,7 +1849,7 @@ unionfs_lock(struct vop_lock1_args *ap)
 	vp = ap->a_vp;
 
 	if (LK_RELEASE == (flags & LK_TYPE_MASK) || !(flags & LK_TYPE_MASK))
-		return (VOP_UNLOCK(vp, flags | LK_RELEASE));
+		return (VOP_UNLOCK_FLAGS(vp, flags | LK_RELEASE));
 
 	if ((flags & LK_INTERLOCK) == 0)
 		VI_LOCK(vp);
@@ -1884,12 +1884,12 @@ unionfs_lock(struct vop_lock1_args *ap)
 			/* Share Lock is once released and a deadlock is avoided.  */
 			vholdnz(uvp);
 			uhold = 1;
-			VOP_UNLOCK(uvp, LK_RELEASE);
+			VOP_UNLOCK(uvp, 0);
 			unp = VTOUNIONFS(vp);
 			if (unp == NULL) {
 				/* vnode is released. */
 				VI_UNLOCK(vp);
-				VOP_UNLOCK(lvp, LK_RELEASE);
+				VOP_UNLOCK(lvp, 0);
 				vdrop(uvp);
 				return (EBUSY);
 			}
@@ -1909,7 +1909,7 @@ unionfs_lock(struct vop_lock1_args *ap)
 			/* vnode is released. */
 			VI_UNLOCK(vp);
 			if (error == 0)
-				VOP_UNLOCK(lvp, LK_RELEASE);
+				VOP_UNLOCK(lvp, 0);
 			vdrop(lvp);
 			if (uhold != 0)
 				vdrop(uvp);
@@ -1940,10 +1940,10 @@ unionfs_lock(struct vop_lock1_args *ap)
 			/* vnode is released. */
 			VI_UNLOCK(vp);
 			if (error == 0)
-				VOP_UNLOCK(uvp, LK_RELEASE);
+				VOP_UNLOCK(uvp, 0);
 			vdrop(uvp);
 			if (lvp != NULLVP) {
-				VOP_UNLOCK(lvp, LK_RELEASE);
+				VOP_UNLOCK(lvp, 0);
 				vdrop(lvp);
 			}
 			return (vop_stdlock(ap));
@@ -1974,7 +1974,6 @@ static int
 unionfs_unlock(struct vop_unlock_args *ap)
 {
 	int		error;
-	int		flags;
 	int		uhold;
 	struct vnode   *vp;
 	struct vnode   *lvp;
@@ -1985,7 +1984,6 @@ unionfs_unlock(struct vop_unlock_args *ap)
 
 	error = 0;
 	uhold = 0;
-	flags = ap->a_flags | LK_RELEASE;
 	vp = ap->a_vp;
 
 	unp = VTOUNIONFS(vp);
@@ -1996,13 +1994,13 @@ unionfs_unlock(struct vop_unlock_args *ap)
 
 	if (lvp != NULLVP) {
 		vholdnz(lvp);
-		error = VOP_UNLOCK(lvp, flags);
+		error = VOP_UNLOCK(lvp, 0);
 	}
 
 	if (error == 0 && uvp != NULLVP) {
 		vholdnz(uvp);
 		uhold = 1;
-		error = VOP_UNLOCK(uvp, flags);
+		error = VOP_UNLOCK(uvp, 0);
 	}
 
 	if (lvp != NULLVP)
@@ -2072,7 +2070,7 @@ unionfs_advlock(struct vop_advlock_args *ap)
 			unionfs_tryrem_node_status(unp, unsp);
 	}
 
-	VOP_UNLOCK(vp, LK_RELEASE);
+	VOP_UNLOCK(vp, 0);
 
 	error = VOP_ADVLOCK(uvp, ap->a_id, ap->a_op, ap->a_fl, ap->a_flags);
 
@@ -2081,7 +2079,7 @@ unionfs_advlock(struct vop_advlock_args *ap)
 	return error;
 
 unionfs_advlock_abort:
-	VOP_UNLOCK(vp, LK_RELEASE);
+	VOP_UNLOCK(vp, 0);
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_advlock: leave (%d)\n", error);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001032212.003MCP5L067726>