svn commit: r355061 - head/sys/fs/tmpfs

Konstantin Belousov kib at FreeBSD.org
Sun Nov 24 19:06:39 UTC 2019


Author: kib
Date: Sun Nov 24 19:06:38 2019
New Revision: 355061
URL: https://svnweb.freebsd.org/changeset/base/355061

Log:
  tmpfs: resolve deadlock between rename and unmount.
  
  Top-level kern_renameat() increases the writecount on the mount point,
  which, together with tmpfs unmount suspending the mount, already
  ensures that unmount cannot proceed while rename unlocks and relocks
  all operated vnodes.
  
  Remove vfs_busy() call from tmpfs_rename() which was done while
  holding a vnode lock, creating the deadlock.  The only intent of the
  busy operation seems to be the prevention of unmount, which is already
  ensured.
  
  Reported and tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/fs/tmpfs/tmpfs_vnops.c

Modified: head/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vnops.c	Sun Nov 24 19:02:13 2019	(r355060)
+++ head/sys/fs/tmpfs/tmpfs_vnops.c	Sun Nov 24 19:06:38 2019	(r355061)
@@ -792,7 +792,6 @@ tmpfs_rename(struct vop_rename_args *v)
 	struct vnode *tdvp = v->a_tdvp;
 	struct vnode *tvp = v->a_tvp;
 	struct componentname *tcnp = v->a_tcnp;
-	struct mount *mp = NULL;
 	char *newname;
 	struct tmpfs_dirent *de;
 	struct tmpfs_mount *tmp;
@@ -829,18 +828,10 @@ tmpfs_rename(struct vop_rename_args *v)
 	 */
 	if (fdvp != tdvp && fdvp != tvp) {
 		if (vn_lock(fdvp, LK_EXCLUSIVE | LK_NOWAIT) != 0) {
-			mp = tdvp->v_mount;
-			error = vfs_busy(mp, 0);
-			if (error != 0) {
-				mp = NULL;
-				goto out;
-			}
 			error = tmpfs_rename_relock(fdvp, &fvp, tdvp, &tvp,
 			    fcnp, tcnp);
-			if (error != 0) {
-				vfs_unbusy(mp);
+			if (error != 0)
 				return (error);
-			}
 			ASSERT_VOP_ELOCKED(fdvp,
 			    "tmpfs_rename: fdvp not locked");
 			ASSERT_VOP_ELOCKED(tdvp,
@@ -1083,9 +1074,6 @@ out:
 	/* Release source nodes. */
 	vrele(fdvp);
 	vrele(fvp);
-
-	if (mp != NULL)
-		vfs_unbusy(mp);
 
 	return (error);
 }


More information about the svn-src-head mailing list