Module Name:    src
Committed By:   manu
Date:           Fri Aug 10 16:49:36 UTC 2012

Modified Files:
        src/lib/libperfuse: perfuse.c
        src/lib/libpuffs: puffs.3
        src/sys/fs/puffs: puffs_msgif.h puffs_vnops.c

Log Message:
Add PUFFS_KFLAG_CACHE_DOTDOT so that vnodes hold a reference on their
parent, keeping them active, and allowing to lookup .. without sending
a request to the filesystem.

Enable the featuure for perfused, as this is how FUSE works.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/lib/libperfuse/perfuse.c
cvs rdiff -u -r1.53 -r1.54 src/lib/libpuffs/puffs.3
cvs rdiff -u -r1.79 -r1.80 src/sys/fs/puffs/puffs_msgif.h
cvs rdiff -u -r1.173 -r1.174 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/lib/libperfuse/perfuse.c
diff -u src/lib/libperfuse/perfuse.c:1.29 src/lib/libperfuse/perfuse.c:1.30
--- src/lib/libperfuse/perfuse.c:1.29	Sat Jul 21 05:49:42 2012
+++ src/lib/libperfuse/perfuse.c	Fri Aug 10 16:49:36 2012
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse.c,v 1.29 2012/07/21 05:49:42 manu Exp $ */
+/*  $NetBSD: perfuse.c,v 1.30 2012/08/10 16:49:36 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -515,6 +515,14 @@ perfuse_init(struct perfuse_callbacks *p
 #else
 	puffs_flags = PUFFS_KFLAG_NOCACHE_NAME;
 #endif
+
+	/*
+	 * Do not lookuo .. 
+	 * That means we keep all parent vnode active
+	 */
+#ifdef PUFFS_KFLAG_CACHE_DOTDOT
+	puffs_flags |= PUFFS_KFLAG_CACHE_DOTDOT;
+#endif
 	
 	/* 
 	 * It would be nice to avoid useless inactive, and only

Index: src/lib/libpuffs/puffs.3
diff -u src/lib/libpuffs/puffs.3:1.53 src/lib/libpuffs/puffs.3:1.54
--- src/lib/libpuffs/puffs.3:1.53	Wed Apr 18 14:24:26 2012
+++ src/lib/libpuffs/puffs.3	Fri Aug 10 16:49:36 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: puffs.3,v 1.53 2012/04/18 14:24:26 wiz Exp $
+.\"	$NetBSD: puffs.3,v 1.54 2012/08/10 16:49:36 manu Exp $
 .\"
 .\" Copyright (c) 2006, 2007, 2008 Antti Kantee.  All rights reserved.
 .\"
@@ -252,6 +252,9 @@ will be called instead of
 .Fn puffs_node_getattr
 and
 .Fn puffs_node_setattr .
+.It Dv PUFFS_KFLAG_CACHE_DOTDOT
+Never send lookups for .. to the filesystem. Parent vnodes are all
+kept active until their children are reclaimed.
 .It Dv PUFFS_FLAG_OPDUMP
 This option makes the framework dump a textual representation of
 each operation before executing it.

Index: src/sys/fs/puffs/puffs_msgif.h
diff -u src/sys/fs/puffs/puffs_msgif.h:1.79 src/sys/fs/puffs/puffs_msgif.h:1.80
--- src/sys/fs/puffs/puffs_msgif.h:1.79	Sat Jul 21 05:17:10 2012
+++ src/sys/fs/puffs/puffs_msgif.h	Fri Aug 10 16:49:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_msgif.h,v 1.79 2012/07/21 05:17:10 manu Exp $	*/
+/*	$NetBSD: puffs_msgif.h,v 1.80 2012/08/10 16:49:35 manu Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -152,16 +152,17 @@ struct puffs_kargs {
 };
 #define pa_root_rdev devunion.dev
 
-#define PUFFS_KFLAG_NOCACHE_NAME	0x01	/* don't use name cache     */
-#define PUFFS_KFLAG_NOCACHE_PAGE	0x02	/* don't use page cache	    */
-#define PUFFS_KFLAG_NOCACHE		0x03	/* no cache whatsoever      */
-#define PUFFS_KFLAG_ALLOPS		0x04	/* ignore pa_vnopmask       */
-#define PUFFS_KFLAG_WTCACHE		0x08	/* write-through page cache */
-#define PUFFS_KFLAG_IAONDEMAND		0x10	/* inactive only on demand  */
-#define PUFFS_KFLAG_LOOKUP_FULLPNBUF	0x20	/* full pnbuf in lookup     */
-#define PUFFS_KFLAG_NOCACHE_ATTR	0x40	/* no attrib cache (unused) */
-#define PUFFS_KFLAG_CACHE_FS_TTL	0x80	/* cache use TTL from FS    */
-#define PUFFS_KFLAG_MASK		0xbf
+#define PUFFS_KFLAG_NOCACHE_NAME	0x001	/* don't use name cache     */
+#define PUFFS_KFLAG_NOCACHE_PAGE	0x002	/* don't use page cache	    */
+#define PUFFS_KFLAG_NOCACHE		0x003	/* no cache whatsoever      */
+#define PUFFS_KFLAG_ALLOPS		0x004	/* ignore pa_vnopmask       */
+#define PUFFS_KFLAG_WTCACHE		0x008	/* write-through page cache */
+#define PUFFS_KFLAG_IAONDEMAND		0x010	/* inactive only on demand  */
+#define PUFFS_KFLAG_LOOKUP_FULLPNBUF	0x020	/* full pnbuf in lookup     */
+#define PUFFS_KFLAG_NOCACHE_ATTR	0x040	/* no attrib cache (unused) */
+#define PUFFS_KFLAG_CACHE_FS_TTL	0x080	/* cache use TTL from FS    */
+#define PUFFS_KFLAG_CACHE_DOTDOT	0x100	/* don't send lookup for .. */
+#define PUFFS_KFLAG_MASK		0x1bf
 
 #define PUFFS_FHFLAG_DYNAMIC		0x01
 #define PUFFS_FHFLAG_NFSV2		0x02

Index: src/sys/fs/puffs/puffs_vnops.c
diff -u src/sys/fs/puffs/puffs_vnops.c:1.173 src/sys/fs/puffs/puffs_vnops.c:1.174
--- src/sys/fs/puffs/puffs_vnops.c:1.173	Fri Aug 10 14:52:56 2012
+++ src/sys/fs/puffs/puffs_vnops.c	Fri Aug 10 16:49:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_vnops.c,v 1.173 2012/08/10 14:52:56 manu Exp $	*/
+/*	$NetBSD: puffs_vnops.c,v 1.174 2012/08/10 16:49:35 manu 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.173 2012/08/10 14:52:56 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.174 2012/08/10 16:49:35 manu Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -418,6 +418,7 @@ static void callreclaim(struct puffs_mou
 static int  flushvncache(struct vnode *, off_t, off_t, bool);
 static void update_va(struct vnode *, struct vattr *, struct vattr *,
 		      struct timespec *, struct timespec *, int);
+static void update_parent(struct vnode *, struct vnode *);
 
 
 #define PUFFS_ABORT_LOOKUP	1
@@ -505,6 +506,23 @@ puffs_vnop_lookup(void *v)
 	    cnp->cn_nameptr, dvp, cnp->cn_nameiop));
 
 	/*
+	 * If dotdot cache is enabled, unlock parent, lock ..
+	 * (grand-parent) and relock parent.
+	 */
+	if (PUFFS_USE_DOTDOTCACHE(pmp) && (cnp->cn_flags & ISDOTDOT)) {
+		VOP_UNLOCK(dvp);
+
+		vp = VPTOPP(ap->a_dvp)->pn_parent;
+		vref(vp);
+
+		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
+
+		*ap->a_vpp = vp;
+		return 0;
+	}
+
+	/*
 	 * Check if someone fed it into the cache
 	 */
 	if (!isdot && PUFFS_USE_NAMECACHE(pmp)) {
@@ -674,6 +692,11 @@ puffs_vnop_lookup(void *v)
 		    strlen(cnp->cn_nameptr) - cnp->cn_namelen);
 
 	VPTOPP(vp)->pn_nlookup++;
+
+	if (PUFFS_USE_DOTDOTCACHE(pmp) &&
+	    (VPTOPP(vp)->pn_parent != dvp))
+		update_parent(vp, dvp);
+
  out:
 	if (cvp != NULL) {
 		mutex_exit(&cpn->pn_sizemtx);
@@ -763,6 +786,10 @@ puffs_vnop_create(void *v)
 
 	VPTOPP(*ap->a_vpp)->pn_nlookup++;
 
+	if (PUFFS_USE_DOTDOTCACHE(pmp) &&
+	    (VPTOPP(*ap->a_vpp)->pn_parent != dvp))
+		update_parent(*ap->a_vpp, dvp);
+
  out:
 	vput(dvp);
 
@@ -822,6 +849,10 @@ puffs_vnop_mknod(void *v)
 
 	VPTOPP(*ap->a_vpp)->pn_nlookup++;
 
+	if (PUFFS_USE_DOTDOTCACHE(pmp) &&
+	    (VPTOPP(*ap->a_vpp)->pn_parent != dvp))
+		update_parent(*ap->a_vpp, dvp);
+
  out:
 	vput(dvp);
 	PUFFS_MSG_RELEASE(mknod);
@@ -992,6 +1023,20 @@ update_va(struct vnode *vp, struct vattr
 	}
 }
 
+static void 
+update_parent(struct vnode *vp, struct vnode *dvp)
+{
+	struct puffs_node *pn = VPTOPP(vp);
+
+	if (pn->pn_parent != NULL) {
+		KASSERT(pn->pn_parent != dvp);
+		vrele(pn->pn_parent);
+	}
+
+	vref(dvp);
+	pn->pn_parent = dvp;
+}
+
 int
 puffs_vnop_getattr(void *v)
 {
@@ -1365,6 +1410,13 @@ puffs_vnop_reclaim(void *v)
 		callreclaim(MPTOPUFFSMP(vp->v_mount), VPTOPNC(vp), nlookup);
 	}
 
+	if (PUFFS_USE_DOTDOTCACHE(pmp)) {
+		if (__predict_true(VPTOPP(vp)->pn_parent != NULL))
+			vrele(VPTOPP(vp)->pn_parent);
+		else
+			KASSERT(vp->v_vflag & VV_ROOT);
+	}
+
 	puffs_putvnode(vp);
 	vp->v_data = NULL;
 
@@ -1797,6 +1849,10 @@ puffs_vnop_mkdir(void *v)
 
 	VPTOPP(*ap->a_vpp)->pn_nlookup++;
 
+	if (PUFFS_USE_DOTDOTCACHE(pmp) &&
+	    (VPTOPP(*ap->a_vpp)->pn_parent != dvp))
+		update_parent(*ap->a_vpp, dvp);
+
  out:
 	vput(dvp);
 	PUFFS_MSG_RELEASE(mkdir);
@@ -1963,6 +2019,10 @@ puffs_vnop_symlink(void *v)
 
 	VPTOPP(*ap->a_vpp)->pn_nlookup++;
 
+	if (PUFFS_USE_DOTDOTCACHE(pmp) && 
+	    (VPTOPP(*ap->a_vpp)->pn_parent != dvp))
+		update_parent(*ap->a_vpp, dvp);
+
  out:
 	vput(dvp);
 	PUFFS_MSG_RELEASE(symlink);
@@ -2060,9 +2120,15 @@ puffs_vnop_rename(void *v)
 	 * XXX: stay in touch with the cache.  I don't like this, but
 	 * don't have a better solution either.  See also puffs_link().
 	 */
-	if (error == 0)
+	if (error == 0) {
 		puffs_updatenode(fpn, PUFFS_UPDATECTIME, 0);
 
+		if (PUFFS_USE_DOTDOTCACHE(pmp) &&
+		    (VPTOPP(fvp)->pn_parent != tdvp))
+			update_parent(fvp, tdvp);
+	}
+
+
  out:
 	if (doabort)
 		VOP_ABORTOP(tdvp, ap->a_tcnp);

Reply via email to