Module Name:    src
Committed By:   hannken
Date:           Sun Jun  4 07:59:17 UTC 2017

Modified Files:
        src/sys/kern: vnode_if.sh vnode_if.src

Log Message:
Add "FSTRANS=LOCK" and "FSTRANS=UNLOCK" to vop_lock and vop_unlock.

Add two "static inline" functions to vnode_if.c to handle MPSAFE
and FSTRANS before and after the "VCALL()".

Take FSTRANS and handle error before "VCALL(...vop_lock...)" and
release it after "VCALL(...vop_unlock...)".


To generate a diff of this commit:
cvs rdiff -u -r1.64 -r1.65 src/sys/kern/vnode_if.sh
cvs rdiff -u -r1.75 -r1.76 src/sys/kern/vnode_if.src

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/vnode_if.sh
diff -u src/sys/kern/vnode_if.sh:1.64 src/sys/kern/vnode_if.sh:1.65
--- src/sys/kern/vnode_if.sh:1.64	Sun Apr 16 17:18:28 2017
+++ src/sys/kern/vnode_if.sh	Sun Jun  4 07:59:17 2017
@@ -29,7 +29,7 @@ copyright="\
  * SUCH DAMAGE.
  */
 "
-SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.64 2017/04/16 17:18:28 riastradh Exp $'
+SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.65 2017/06/04 07:59:17 hannken Exp $'
 
 # Script to produce VFS front-end sugar.
 #
@@ -100,7 +100,7 @@ awk_parser='
 	args_name=$1;
 	argc=0;
 	willmake=-1;
-	fstrans=0;
+	fstrans="";
 	next;
 }
 # Last line of description
@@ -113,11 +113,9 @@ awk_parser='
 	if ($1 == "VERSION") {
 		args_name=args_name "_v" $2;
 		next;
-	} else if ($1 == "FSTRANS=YES") {
-		fstrans = 1;
-		next;
-	} else if ($1 == "FSTRANS=NO") {
-		fstrans = -1;
+	} else if ($1 ~ "^FSTRANS=") {
+		fstrans = $1;
+		sub("FSTRANS=", "", fstrans);
 		next;
 	}
 
@@ -147,8 +145,12 @@ awk_parser='
 		willmake=argc;
 		i++;
 	}
-	if (argc == 0 && fstrans == 0 && lockstate[0] != 1)
-		fstrans = 1;
+	if (argc == 0 && fstrans == "") {
+		if (lockstate[0] == 1)
+			fstrans = "NO";
+		else
+			fstrans = "YES";
+	}
 
 	# XXX: replace non-portable types for rump.  We should really
 	# nuke the types from the kernel, but that is a battle for
@@ -316,6 +318,57 @@ echo '
 
 if [ -z "${rump}" ] ; then
 	echo "
+enum fst_op { FST_NO, FST_YES, FST_TRY };
+
+static inline int
+vop_pre(vnode_t *vp, struct mount **mp, bool *mpsafe, enum fst_op op)
+{
+	int error;
+
+	*mpsafe = (vp->v_vflag & VV_MPSAFE);
+
+	if (!*mpsafe) {
+		KERNEL_LOCK(1, curlwp);
+	}
+
+	if (op == FST_YES || op == FST_TRY) {
+		for (;;) {
+			*mp = vp->v_mount;
+			if (op == FST_TRY) {
+				error = fstrans_start_nowait(*mp, FSTRANS_SHARED);
+				if (error) {
+					if (!*mpsafe) {
+						KERNEL_UNLOCK_ONE(curlwp);
+					}
+					return error;
+				}
+			} else {
+				fstrans_start(*mp, FSTRANS_SHARED);
+			}
+			if (__predict_true(*mp == vp->v_mount))
+				break;
+			fstrans_done(*mp);
+		}
+	} else {
+		*mp = vp->v_mount;
+	}
+
+	return 0;
+}
+
+static inline void
+vop_post(vnode_t *vp, struct mount *mp, bool mpsafe, enum fst_op op)
+{
+
+	if (op == FST_YES) {
+		fstrans_done(mp);
+	}
+
+	if (!mpsafe) {
+		KERNEL_UNLOCK_ONE(curlwp);
+	}
+}
+
 const struct vnodeop_desc vop_default_desc = {"
 echo '	0,
 	"default",
@@ -402,8 +455,7 @@ function bodyrump() {
 function bodynorm() {
 	printf("{\n\tint error;\n\tbool mpsafe;\n\tstruct %s_args a;\n",
 		args_name);
-	if (fstrans == 1)
-		printf("\tstruct mount *mp = %s->v_mount;\n", argname[0]);
+	printf("\tstruct mount *mp;\n");
 	if (lockdebug) {
 		printf("#ifdef VNODE_LOCKDEBUG\n");
 		for (i=0; i<argc; i++) {
@@ -425,15 +477,27 @@ function bodynorm() {
 			printf("#endif\n");
 		}
 	}
-	printf("\tmpsafe = (%s->v_vflag & VV_MPSAFE);\n", argname[0]);
-	printf("\tif (!mpsafe) { KERNEL_LOCK(1, curlwp); }\n");
-	if (fstrans == 1)
-		printf("\tfstrans_start(mp, FSTRANS_SHARED);\n");
+	if (fstrans == "LOCK")
+		printf("\terror = vop_pre(%s, &mp, &mpsafe, %s);\n",
+			argname[0], "(flags & LK_NOWAIT ? FST_TRY : FST_YES)");
+	else if (fstrans == "UNLOCK")
+		printf("\terror = vop_pre(%s, &mp, &mpsafe, FST_%s);\n",
+			argname[0], "NO");
+	else
+		printf("\terror = vop_pre(%s, &mp, &mpsafe, FST_%s);\n",
+			argname[0], fstrans);
+	printf("\tif (error)\n\t\treturn error;\n");
 	printf("\terror = (VCALL(%s, VOFFSET(%s), &a));\n",
 		argname[0], name);
-	if (fstrans == 1)
-		printf("\tfstrans_done(mp);\n");
-	printf("\tif (!mpsafe) { KERNEL_UNLOCK_ONE(curlwp); }\n");
+	if (fstrans == "LOCK")
+		printf("\tvop_post(%s, mp, mpsafe, %s);\n",
+			argname[0], "(error ? FST_YES : FST_NO)");
+	else if (fstrans == "UNLOCK")
+		printf("\tvop_post(%s, mp, mpsafe, FST_%s);\n",
+			argname[0], "YES");
+	else
+		printf("\tvop_post(%s, mp, mpsafe, FST_%s);\n",
+			argname[0], fstrans);
 	if (willmake != -1) {
 		printf("#ifdef DIAGNOSTIC\n");
 		printf("\tif (error == 0)\n"				\

Index: src/sys/kern/vnode_if.src
diff -u src/sys/kern/vnode_if.src:1.75 src/sys/kern/vnode_if.src:1.76
--- src/sys/kern/vnode_if.src:1.75	Fri May 26 14:21:00 2017
+++ src/sys/kern/vnode_if.src	Sun Jun  4 07:59:17 2017
@@ -1,4 +1,4 @@
-#	$NetBSD: vnode_if.src,v 1.75 2017/05/26 14:21:00 riastradh Exp $
+#	$NetBSD: vnode_if.src,v 1.76 2017/06/04 07:59:17 hannken Exp $
 #
 # Copyright (c) 1992, 1993
 #	The Regents of the University of California.  All rights reserved.
@@ -407,7 +407,7 @@ vop_reclaim {
 #% lock               vp      U L U
 #
 vop_lock {
-	FSTRANS=NO
+	FSTRANS=LOCK
 	IN LOCKED=NO struct vnode *vp;
 	IN int flags;
 };
@@ -416,7 +416,7 @@ vop_lock {
 #% unlock     vp      L U L
 #
 vop_unlock {
-	FSTRANS=NO
+	FSTRANS=UNLOCK
 	IN LOCKED=YES struct vnode *vp;
 };
 

Reply via email to