Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Dec 2012 12:54:12 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r244651 - in stable/9/sys: kern sys
Message-ID:  <201212241254.qBOCsCdE007824@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Dec 24 12:54:12 2012
New Revision: 244651
URL: http://svnweb.freebsd.org/changeset/base/244651

Log:
  MFC r240283:
  Add MNTK_LOOKUP_EXCL_DOTDOT struct mount flag, which specifies to the
  lookup code that dotdot lookups shall override any shared lock
  requests with the exclusive one. The flag is useful for filesystems
  which sometimes need to upgrade shared lock to exclusive inside the
  VOP_LOOKUP or later, which cannot be done safely for dotdot, due to
  dvp also locked and causing LOR.

Modified:
  stable/9/sys/kern/vfs_lookup.c
  stable/9/sys/sys/mount.h
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/vfs_lookup.c
==============================================================================
--- stable/9/sys/kern/vfs_lookup.c	Mon Dec 24 10:10:18 2012	(r244650)
+++ stable/9/sys/kern/vfs_lookup.c	Mon Dec 24 12:54:12 2012	(r244651)
@@ -393,11 +393,13 @@ namei(struct nameidata *ndp)
 }
 
 static int
-compute_cn_lkflags(struct mount *mp, int lkflags)
+compute_cn_lkflags(struct mount *mp, int lkflags, int cnflags)
 {
 
-	if (mp == NULL || 
-	    ((lkflags & LK_SHARED) && !(mp->mnt_kern_flag & MNTK_LOOKUP_SHARED))) {
+	if (mp == NULL || ((lkflags & LK_SHARED) &&
+	    (!(mp->mnt_kern_flag & MNTK_LOOKUP_SHARED) ||
+	    ((cnflags & ISDOTDOT) &&
+	    (mp->mnt_kern_flag & MNTK_LOOKUP_EXCL_DOTDOT))))) {
 		lkflags &= ~LK_SHARED;
 		lkflags |= LK_EXCLUSIVE;
 	}
@@ -526,7 +528,8 @@ lookup(struct nameidata *ndp)
 	dp = ndp->ni_startdir;
 	ndp->ni_startdir = NULLVP;
 	vn_lock(dp,
-	    compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags | LK_RETRY));
+	    compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags | LK_RETRY,
+	    cnp->cn_flags));
 
 dirloop:
 	/*
@@ -683,7 +686,7 @@ dirloop:
 			VFS_UNLOCK_GIANT(tvfslocked);
 			vn_lock(dp,
 			    compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags |
-			    LK_RETRY));
+			    LK_RETRY, ISDOTDOT));
 		}
 	}
 
@@ -721,7 +724,8 @@ unionlookup:
 	vprint("lookup in", dp);
 #endif
 	lkflags_save = cnp->cn_lkflags;
-	cnp->cn_lkflags = compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags);
+	cnp->cn_lkflags = compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags,
+	    cnp->cn_flags);
 	if ((error = VOP_LOOKUP(dp, &ndp->ni_vp, cnp)) != 0) {
 		cnp->cn_lkflags = lkflags_save;
 		KASSERT(ndp->ni_vp == NULL, ("leaf should be empty"));
@@ -740,7 +744,7 @@ unionlookup:
 			VFS_UNLOCK_GIANT(tvfslocked);
 			vn_lock(dp,
 			    compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags |
-			    LK_RETRY));
+			    LK_RETRY, cnp->cn_flags));
 			goto unionlookup;
 		}
 
@@ -812,8 +816,8 @@ unionlookup:
 		dvfslocked = 0;
 		vref(vp_crossmp);
 		ndp->ni_dvp = vp_crossmp;
-		error = VFS_ROOT(mp, compute_cn_lkflags(mp, cnp->cn_lkflags),
-		    &tdp);
+		error = VFS_ROOT(mp, compute_cn_lkflags(mp, cnp->cn_lkflags,
+		    cnp->cn_flags), &tdp);
 		vfs_unbusy(mp);
 		if (vn_lock(vp_crossmp, LK_SHARED | LK_NOWAIT))
 			panic("vp_crossmp exclusively locked or reclaimed");

Modified: stable/9/sys/sys/mount.h
==============================================================================
--- stable/9/sys/sys/mount.h	Mon Dec 24 10:10:18 2012	(r244650)
+++ stable/9/sys/sys/mount.h	Mon Dec 24 12:54:12 2012	(r244651)
@@ -369,6 +369,7 @@ void          __mnt_vnode_markerfree(str
 #define	MNTK_NO_IOPF	0x00000100	/* Disallow page faults during reads
 					   and writes. Filesystem shall properly
 					   handle i/o state on EFAULT. */
+#define	MNTK_LOOKUP_EXCL_DOTDOT	0x00000800
 #define MNTK_NOASYNC	0x00800000	/* disable async */
 #define MNTK_UNMOUNT	0x01000000	/* unmount in progress */
 #define	MNTK_MWAIT	0x02000000	/* waiting for unmount to finish */



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