Thu Mar 8 14:58:58 2012 UTC ()
The kernel can lookup the same node multiple time and will reclaim as
many times it looked up. All reclaims but the last one must be ignored,
otherwise we discard a node which will still get operations. We therefore
have to keep track of lookup/reclaim count and hnour reclaims only when
the count reaches zero.


(manu)
diff -r1.50 -r1.51 src/lib/libperfuse/ops.c
diff -r1.25 -r1.26 src/lib/libperfuse/perfuse_priv.h
diff -r1.15 -r1.16 src/lib/libperfuse/subr.c

cvs diff -r1.50 -r1.51 src/lib/libperfuse/ops.c (expand / switch to context diff)
--- src/lib/libperfuse/ops.c 2012/01/29 06:22:02 1.50
+++ src/lib/libperfuse/ops.c 2012/03/08 14:58:57 1.51
@@ -1,4 +1,4 @@
-/*  $NetBSD: ops.c,v 1.50 2012/01/29 06:22:02 manu Exp $ */
+/*  $NetBSD: ops.c,v 1.51 2012/03/08 14:58:57 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -514,6 +514,7 @@
 	 * Check for cached name
 	 */
 	if ((oldpnd != NULL) && !entry_expired(oldpnd->pnd_pn)) {
+		oldpnd->pnd_puffs_nlookup++;
 		*pnp = oldpnd->pnd_pn;
 		return 0;
 	}
@@ -550,7 +551,8 @@
 
 	if (oldpnd != NULL) {
 		if (oldpnd->pnd_nodeid == feo->nodeid) {
-			oldpnd->pnd_nlookup++;
+			oldpnd->pnd_fuse_nlookup++;
+			oldpnd->pnd_puffs_nlookup++;
 			*pnp = oldpnd->pnd_pn;
 
 			ps->ps_destroy_msg(pm);
@@ -2702,6 +2704,7 @@
 		return 0;
 
 	pnd->pnd_flags |= PND_RECLAIMED;
+	pnd->pnd_puffs_nlookup--;
 
 #ifdef PERFUSE_DEBUG
 	if (perfuse_diagflags & PDF_RECLAIM)
@@ -2718,11 +2721,11 @@
 
 #ifdef PERFUSE_DEBUG
 	if (perfuse_diagflags & PDF_RECLAIM)
-		DPRINTF("%s (nodeid %"PRId64") is %sreclaimed, "
+		DPRINTF("%s (nodeid %"PRId64") is %sreclaimed, nlookup = %d "
 			"has childcount %d %s%s%s%s, pending ops:%s%s%s\n", 
 		        perfuse_node_path((puffs_cookie_t)pn), pnd->pnd_nodeid,
 		        pnd->pnd_flags & PND_RECLAIMED ? "" : "not ",
-		        pnd->pnd_childcount,
+			pnd->pnd_puffs_nlookup, pnd->pnd_childcount,
 			pnd->pnd_flags & PND_OPEN ? "open " : "not open",
 			pnd->pnd_flags & PND_RFH ? "r" : "",
 			pnd->pnd_flags & PND_WFH ? "w" : "",
@@ -2731,8 +2734,8 @@
 			pnd->pnd_flags & PND_INWRITE ? " write" : "",
 			pnd->pnd_flags & PND_INOPEN ? " open" : "");
 #endif
-
 		if (!(pnd->pnd_flags & PND_RECLAIMED) ||
+		    (pnd->pnd_puffs_nlookup != 0) ||
 		    (pnd->pnd_childcount != 0))
 			return 0;
 
@@ -2758,7 +2761,7 @@
 		pm = ps->ps_new_msg(pu, (puffs_cookie_t)pn, FUSE_FORGET, 
 			      sizeof(*ffi), NULL);
 		ffi = GET_INPAYLOAD(ps, pm, fuse_forget_in);
-		ffi->nlookup = pnd->pnd_nlookup;
+		ffi->nlookup = pnd->pnd_fuse_nlookup;
 
 		/*
 		 * No reply is expected, pm is freed in xchg_msg

cvs diff -r1.25 -r1.26 src/lib/libperfuse/perfuse_priv.h (expand / switch to context diff)
--- src/lib/libperfuse/perfuse_priv.h 2012/01/29 06:22:02 1.25
+++ src/lib/libperfuse/perfuse_priv.h 2012/03/08 14:58:57 1.26
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse_priv.h,v 1.25 2012/01/29 06:22:02 manu Exp $ */
+/*  $NetBSD: perfuse_priv.h,v 1.26 2012/03/08 14:58:57 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -108,7 +108,8 @@
 	uint64_t pnd_rfh;
 	uint64_t pnd_wfh;
 	uint64_t pnd_nodeid;			/* nodeid, this is not inode */
-	uint64_t pnd_nlookup;			/* vnode refcount */
+	uint64_t pnd_fuse_nlookup;		/* vnode refcount */
+	int pnd_puffs_nlookup;			/* vnode refcount */
 	uint64_t pnd_lock_owner;
 	struct dirent *pnd_dirent;		/* native buffer for readdir */
 	off_t pnd_dirent_len;

cvs diff -r1.15 -r1.16 src/lib/libperfuse/subr.c (expand / switch to context diff)
--- src/lib/libperfuse/subr.c 2012/01/29 06:22:02 1.15
+++ src/lib/libperfuse/subr.c 2012/03/08 14:58:57 1.16
@@ -1,4 +1,4 @@
-/*  $NetBSD: subr.c,v 1.15 2012/01/29 06:22:02 manu Exp $ */
+/*  $NetBSD: subr.c,v 1.16 2012/03/08 14:58:57 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -67,7 +67,8 @@
 	pnd->pnd_rfh = FUSE_UNKNOWN_FH;
 	pnd->pnd_wfh = FUSE_UNKNOWN_FH;
 	pnd->pnd_nodeid = PERFUSE_UNKNOWN_NODEID;
-	pnd->pnd_nlookup = 1;
+	pnd->pnd_fuse_nlookup = 1;
+	pnd->pnd_puffs_nlookup = 1;
 	pnd->pnd_parent = parent;
 	pnd->pnd_pn = (puffs_cookie_t)pn;
 	(void)strlcpy(pnd->pnd_name, name, MAXPATHLEN);