Module Name:    src
Committed By:   snj
Date:           Sat Oct  3 23:11:27 UTC 2009

Modified Files:
        src/sys/fs/puffs [netbsd-5]: puffs_node.c puffs_vnops.c

Log Message:
Pull up following revision(s) (requested by pooka in ticket #1042):
        sys/fs/puffs/puffs_node.c: revision 1.14
        sys/fs/puffs/puffs_vnops.c: revision 1.134
* fix a race i introduced almost two years ago in rev 1.116:
  operations creating a node cannot be considered outgoing operations,
  since after return from userspace they modify file system state
  by creating a new node.  if we do not protect the file system by
  holding the directory lock, a lookup operation might race us into
  the kernel and create the node earlier.
* remove pnode from hashlish before sending the reclaim faf off to
  userspace.  also, hold pmp_lock while frobbing the list.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.13.10.1 src/sys/fs/puffs/puffs_node.c
cvs rdiff -u -r1.129.4.1 -r1.129.4.2 src/sys/fs/puffs/puffs_vnops.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/fs/puffs/puffs_node.c
diff -u src/sys/fs/puffs/puffs_node.c:1.13 src/sys/fs/puffs/puffs_node.c:1.13.10.1
--- src/sys/fs/puffs/puffs_node.c:1.13	Tue May  6 12:33:16 2008
+++ src/sys/fs/puffs/puffs_node.c	Sat Oct  3 23:11:27 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_node.c,v 1.13 2008/05/06 12:33:16 ad Exp $	*/
+/*	$NetBSD: puffs_node.c,v 1.13.10.1 2009/10/03 23:11:27 snj Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_node.c,v 1.13 2008/05/06 12:33:16 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_node.c,v 1.13.10.1 2009/10/03 23:11:27 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/hash.h>
@@ -223,7 +223,7 @@
 		if (pnc->pnc_cookie == ck) {
 			mutex_exit(&pmp->pmp_lock);
 			puffs_senderr(pmp, PUFFS_ERR_MAKENODE, EEXIST,
-			    "cookie exists", ck);
+			    "newcookie exists", ck);
 			return EPROTO;
 		}
 	}
@@ -260,7 +260,6 @@
 		panic("puffs_putvnode: %p not a puffs vnode", vp);
 #endif
 
-	LIST_REMOVE(pnode, pn_hashent);
 	genfs_node_destroy(vp);
 	puffs_releasenode(pnode);
 	vp->v_data = NULL;
@@ -336,6 +335,9 @@
 	 */
 	mutex_enter(&pmp->pmp_lock);
 	if (pmp->pmp_root) {
+		struct puffs_node *pnode = vp->v_data;
+
+		LIST_REMOVE(pnode, pn_hashent);
 		mutex_exit(&pmp->pmp_lock);
 		puffs_putvnode(vp);
 		goto retry;

Index: src/sys/fs/puffs/puffs_vnops.c
diff -u src/sys/fs/puffs/puffs_vnops.c:1.129.4.1 src/sys/fs/puffs/puffs_vnops.c:1.129.4.2
--- src/sys/fs/puffs/puffs_vnops.c:1.129.4.1	Sat Sep 26 18:53:48 2009
+++ src/sys/fs/puffs/puffs_vnops.c	Sat Oct  3 23:11:27 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_vnops.c,v 1.129.4.1 2009/09/26 18:53:48 snj Exp $	*/
+/*	$NetBSD: puffs_vnops.c,v 1.129.4.2 2009/10/03 23:11:27 snj Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.129.4.1 2009/09/26 18:53:48 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.129.4.2 2009/10/03 23:11:27 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/fstrans.h>
@@ -644,16 +644,7 @@
 	create_msg->pvnr_va = *ap->a_vap;
 	puffs_msg_setinfo(park_create, PUFFSOP_VN,
 	    PUFFS_VN_CREATE, VPTOPNC(dvp));
-
-	/*
-	 * Do the dance:
-	 * + insert into queue ("interlock")
-	 * + unlock vnode
-	 * + wait for response
-	 */
-	puffs_msg_enqueue(pmp, park_create);
-	REFPN_AND_UNLOCKVP(dvp, dpn);
-	error = puffs_msg_wait2(pmp, park_create, dpn, NULL);
+	PUFFS_MSG_ENQUEUEWAIT2(pmp, park_create, dvp->v_data, NULL, error);
 
 	error = checkerr(pmp, error, __func__);
 	if (error)
@@ -666,10 +657,10 @@
 		    create_msg->pvnr_newnode, cnp);
 
  out:
+	vput(dvp);
 	if (error || (cnp->cn_flags & SAVESTART) == 0)
 		PNBUF_PUT(cnp->cn_pnbuf);
 
-	RELEPN_AND_VP(dvp, dpn);
 	DPRINTF(("puffs_create: return %d\n", error));
 	PUFFS_MSG_RELEASE(create);
 	return error;
@@ -700,9 +691,7 @@
 	puffs_msg_setinfo(park_mknod, PUFFSOP_VN,
 	    PUFFS_VN_MKNOD, VPTOPNC(dvp));
 
-	puffs_msg_enqueue(pmp, park_mknod);
-	REFPN_AND_UNLOCKVP(dvp, dpn);
-	error = puffs_msg_wait2(pmp, park_mknod, dpn, NULL);
+	PUFFS_MSG_ENQUEUEWAIT2(pmp, park_mknod, dvp->v_data, NULL, error);
 
 	error = checkerr(pmp, error, __func__);
 	if (error)
@@ -716,10 +705,10 @@
 		    mknod_msg->pvnr_newnode, cnp);
 
  out:
+	vput(dvp);
 	PUFFS_MSG_RELEASE(mknod);
 	if (error || (cnp->cn_flags & SAVESTART) == 0)
 		PNBUF_PUT(cnp->cn_pnbuf);
-	RELEPN_AND_VP(dvp, dpn);
 	return error;
 }
 
@@ -1073,6 +1062,8 @@
 	} */ *ap = v;
 	struct vnode *vp = ap->a_vp;
 	struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
+	struct puffs_node *pnode = vp->v_data;
+	bool notifyserver = true;
 
 	/*
 	 * first things first: check if someone is trying to reclaim the
@@ -1085,14 +1076,23 @@
 		KASSERT(pmp->pmp_root != NULL);
 		pmp->pmp_root = NULL;
 		mutex_exit(&pmp->pmp_lock);
-		goto out;
+		notifyserver = false;
 	}
 
-	callreclaim(MPTOPUFFSMP(vp->v_mount), VPTOPNC(vp));
-
- out:
+	/*
+	 * purge info from kernel before issueing FAF, since we
+	 * don't really know when we'll get around to it after
+	 * that and someone might race us into node creation
+	 */
+	mutex_enter(&pmp->pmp_lock);
+	LIST_REMOVE(pnode, pn_hashent);
+	mutex_exit(&pmp->pmp_lock);
 	if (PUFFS_USE_NAMECACHE(pmp))
 		cache_purge(vp);
+
+	if (notifyserver)
+		callreclaim(MPTOPUFFSMP(vp->v_mount), VPTOPNC(vp));
+
 	puffs_putvnode(vp);
 
 	return 0;
@@ -1475,9 +1475,7 @@
 	puffs_msg_setinfo(park_mkdir, PUFFSOP_VN,
 	    PUFFS_VN_MKDIR, VPTOPNC(dvp));
 
-	puffs_msg_enqueue(pmp, park_mkdir);
-	REFPN_AND_UNLOCKVP(dvp, dpn);
-	error = puffs_msg_wait2(pmp, park_mkdir, dpn, NULL);
+	PUFFS_MSG_ENQUEUEWAIT2(pmp, park_mkdir, dvp->v_data, NULL, error);
 
 	error = checkerr(pmp, error, __func__);
 	if (error)
@@ -1490,10 +1488,10 @@
 		    mkdir_msg->pvnr_newnode, cnp);
 
  out:
+	vput(dvp);
 	PUFFS_MSG_RELEASE(mkdir);
 	if (error || (cnp->cn_flags & SAVESTART) == 0)
 		PNBUF_PUT(cnp->cn_pnbuf);
-	RELEPN_AND_VP(dvp, dpn);
 	return error;
 }
 
@@ -1636,9 +1634,7 @@
 	puffs_msg_setinfo(park_symlink, PUFFSOP_VN,
 	    PUFFS_VN_SYMLINK, VPTOPNC(dvp));
 
-	puffs_msg_enqueue(pmp, park_symlink);
-	REFPN_AND_UNLOCKVP(dvp, dpn);
-	error = puffs_msg_wait2(pmp, park_symlink, dpn, NULL);
+	PUFFS_MSG_ENQUEUEWAIT2(pmp, park_symlink, dvp->v_data, NULL, error);
 
 	error = checkerr(pmp, error, __func__);
 	if (error)
@@ -1651,10 +1647,10 @@
 		    symlink_msg->pvnr_newnode, cnp);
 
  out:
+	vput(dvp);
 	PUFFS_MSG_RELEASE(symlink);
 	if (error || (cnp->cn_flags & SAVESTART) == 0)
 		PNBUF_PUT(cnp->cn_pnbuf);
-	RELEPN_AND_VP(dvp, dpn);
 
 	return error;
 }

Reply via email to