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; }