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