Module Name:    src
Committed By:   chs
Date:           Tue Dec 29 22:13:40 UTC 2020

Modified Files:
        src/sys/kern: vfs_lookup.c

Log Message:
Honor LOCKPARENT for ".." of the root directory.

Reported-by: [email protected]


To generate a diff of this commit:
cvs rdiff -u -r1.224 -r1.225 src/sys/kern/vfs_lookup.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_lookup.c
diff -u src/sys/kern/vfs_lookup.c:1.224 src/sys/kern/vfs_lookup.c:1.225
--- src/sys/kern/vfs_lookup.c:1.224	Mon Jun 15 18:44:10 2020
+++ src/sys/kern/vfs_lookup.c	Tue Dec 29 22:13:40 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_lookup.c,v 1.224 2020/06/15 18:44:10 ad Exp $	*/
+/*	$NetBSD: vfs_lookup.c,v 1.225 2020/12/29 22:13:40 chs Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.224 2020/06/15 18:44:10 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.225 2020/12/29 22:13:40 chs Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_magiclinks.h"
@@ -1047,6 +1047,28 @@ lookup_crossmount(struct namei_state *st
 }
 
 /*
+ * Determine the desired locking mode for the directory of a lookup.
+ */
+static int
+lookup_lktype(struct vnode *searchdir, struct componentname *cnp)
+{
+
+	/*
+	 * If the file system supports VOP_LOOKUP() with a shared lock, and
+	 * we are not making any modifications (nameiop LOOKUP) or this is
+	 * not the last component then get a shared lock.  Where we can't do
+	 * fast-forwarded lookups (for example with layered file systems)
+	 * then this is the fallback for reducing lock contention.
+	 */
+	if ((searchdir->v_mount->mnt_iflag & IMNT_SHRLOOKUP) != 0 &&
+	    (cnp->cn_nameiop == LOOKUP || (cnp->cn_flags & ISLASTCN) == 0)) {
+		return LK_SHARED;
+	} else {
+		return LK_EXCLUSIVE;
+	}
+}
+
+/*
  * Call VOP_LOOKUP for a single lookup; return a new search directory
  * (used when crossing mountpoints up or searching union mounts down) and
  * the found object, which for create operations may be NULL on success.
@@ -1100,6 +1122,11 @@ lookup_once(struct namei_state *state,
 				foundobj = searchdir;
 				vref(foundobj);
 				*foundobj_ret = foundobj;
+				if (cnp->cn_flags & LOCKPARENT) {
+					lktype = lookup_lktype(searchdir, cnp);
+					vn_lock(searchdir, lktype | LK_RETRY);
+					searchdir_locked = true;
+				}
 				error = 0;
 				goto done;
 			}
@@ -1137,19 +1164,7 @@ lookup_once(struct namei_state *state,
 		}
 	}
 
-	/*
-	 * If the file system supports VOP_LOOKUP() with a shared lock, and
-	 * we are not making any modifications (nameiop LOOKUP) or this is
-	 * not the last component then get a shared lock.  Where we can't do
-	 * fast-forwarded lookups (for example with layered file systems)
-	 * then this is the fallback for reducing lock contention.
-	 */
-	if ((searchdir->v_mount->mnt_iflag & IMNT_SHRLOOKUP) != 0 &&
-	    (cnp->cn_nameiop == LOOKUP || (cnp->cn_flags & ISLASTCN) == 0)) {
-	    	lktype = LK_SHARED;
-	} else {
-		lktype = LK_EXCLUSIVE;
-	}
+	lktype = lookup_lktype(searchdir, cnp);
 
 	/*
 	 * We now have a segment name to search for, and a directory to search.

Reply via email to