Module Name:    src
Committed By:   manu
Date:           Sun Apr  8 15:04:41 UTC 2012

Modified Files:
        src/sys/fs/puffs: puffs_msgif.h puffs_node.c puffs_sys.h puffs_vfsops.c
            puffs_vnops.c

Log Message:
Add name and atttribute cache with filesytem provided TTL.
lookup, create, mknod, mkdir, symlink, getattr and setattr messages
have been extended so that attributes and their TTL can be provided
by the filesytem. lookup, create, mknod, mkdir, and symlink messages
are also extended so that the filesystem can provide name TTL.


To generate a diff of this commit:
cvs rdiff -u -r1.77 -r1.78 src/sys/fs/puffs/puffs_msgif.h
cvs rdiff -u -r1.23 -r1.24 src/sys/fs/puffs/puffs_node.c
cvs rdiff -u -r1.78 -r1.79 src/sys/fs/puffs/puffs_sys.h
cvs rdiff -u -r1.100 -r1.101 src/sys/fs/puffs/puffs_vfsops.c
cvs rdiff -u -r1.164 -r1.165 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_msgif.h
diff -u src/sys/fs/puffs/puffs_msgif.h:1.77 src/sys/fs/puffs/puffs_msgif.h:1.78
--- src/sys/fs/puffs/puffs_msgif.h:1.77	Tue Sep 27 01:48:57 2011
+++ src/sys/fs/puffs/puffs_msgif.h	Sun Apr  8 15:04:41 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_msgif.h,v 1.77 2011/09/27 01:48:57 christos Exp $	*/
+/*	$NetBSD: puffs_msgif.h,v 1.78 2012/04/08 15:04:41 manu Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -159,8 +159,9 @@ struct puffs_kargs {
 #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_MASK		0x3f
 #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_FHFLAG_DYNAMIC		0x01
 #define PUFFS_FHFLAG_NFSV2		0x02
@@ -360,6 +361,10 @@ struct puffs_vnmsg_lookup {
 	enum vtype		pvnr_vtype;		/* IN	*/
 	voff_t			pvnr_size;		/* IN	*/
 	dev_t			pvnr_rdev;		/* IN	*/
+	/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
+	struct vattr		pvnr_va;		/* IN	*/
+	struct timespec		pvnr_va_ttl;		/* IN	*/
+	struct timespec		pvnr_cn_ttl;		/* IN	*/
 };
 
 struct puffs_vnmsg_create {
@@ -370,6 +375,9 @@ struct puffs_vnmsg_create {
 
 	struct vattr		pvnr_va;		/* OUT	*/
 	puffs_cookie_t		pvnr_newnode;		/* IN	*/
+	/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
+	struct timespec		pvnr_va_ttl;		/* IN	*/
+	struct timespec		pvnr_cn_ttl;		/* IN	*/
 };
 
 struct puffs_vnmsg_mknod {
@@ -380,6 +388,9 @@ struct puffs_vnmsg_mknod {
 
 	struct vattr		pvnr_va;		/* OUT	*/
 	puffs_cookie_t		pvnr_newnode;		/* IN	*/
+	/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
+	struct timespec		pvnr_va_ttl;		/* IN	*/
+	struct timespec		pvnr_cn_ttl;		/* IN	*/
 };
 
 struct puffs_vnmsg_open {
@@ -410,6 +421,8 @@ struct puffs_vnmsg_setgetattr {
 
 	struct puffs_kcred	pvnr_cred;		/* OUT	*/
 	struct vattr		pvnr_va;		/* IN/OUT (op depend) */
+	/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
+	struct timespec		pvnr_va_ttl;		/* IN	*/
 };
 
 #define puffs_vnmsg_read puffs_vnmsg_rw
@@ -480,6 +493,9 @@ struct puffs_vnmsg_mkdir {
 
 	struct vattr		pvnr_va;		/* OUT	*/
 	puffs_cookie_t		pvnr_newnode;		/* IN	*/
+	/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
+	struct timespec		pvnr_va_ttl;		/* IN	*/
+	struct timespec		pvnr_cn_ttl;		/* IN	*/
 };
 
 struct puffs_vnmsg_rmdir {
@@ -522,6 +538,9 @@ struct puffs_vnmsg_symlink {
 	struct vattr		pvnr_va;		/* OUT	*/
 	puffs_cookie_t		pvnr_newnode;		/* IN	*/
 	char			pvnr_link[MAXPATHLEN];	/* OUT	*/
+	/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
+	struct timespec		pvnr_va_ttl;		/* IN	*/
+	struct timespec		pvnr_cn_ttl;		/* IN	*/
 };
 
 struct puffs_vnmsg_readdir {

Index: src/sys/fs/puffs/puffs_node.c
diff -u src/sys/fs/puffs/puffs_node.c:1.23 src/sys/fs/puffs/puffs_node.c:1.24
--- src/sys/fs/puffs/puffs_node.c:1.23	Thu Jan 19 08:14:41 2012
+++ src/sys/fs/puffs/puffs_node.c	Sun Apr  8 15:04:41 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_node.c,v 1.23 2012/01/19 08:14:41 manu Exp $	*/
+/*	$NetBSD: puffs_node.c,v 1.24 2012/04/08 15:04:41 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_node.c,v 1.23 2012/01/19 08:14:41 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_node.c,v 1.24 2012/04/08 15:04:41 manu Exp $");
 
 #include <sys/param.h>
 #include <sys/hash.h>
@@ -63,6 +63,7 @@ static struct puffs_node *puffs_cookie2p
 					     puffs_cookie_t);
 
 struct pool puffs_pnpool;
+struct pool puffs_vapool;
 
 /*
  * Grab a vnode, intialize all the puffs-dependent stuff.
@@ -483,6 +484,8 @@ puffs_releasenode(struct puffs_node *pn)
 		mutex_destroy(&pn->pn_mtx);
 		mutex_destroy(&pn->pn_sizemtx);
 		seldestroy(&pn->pn_sel);
+		if (pn->pn_va_cache != NULL)
+			pool_put(&puffs_vapool, pn->pn_va_cache);
 		pool_put(&puffs_pnpool, pn);
 	} else {
 		mutex_exit(&pn->pn_mtx);

Index: src/sys/fs/puffs/puffs_sys.h
diff -u src/sys/fs/puffs/puffs_sys.h:1.78 src/sys/fs/puffs/puffs_sys.h:1.79
--- src/sys/fs/puffs/puffs_sys.h:1.78	Mon Aug 29 04:12:45 2011
+++ src/sys/fs/puffs/puffs_sys.h	Sun Apr  8 15:04:41 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_sys.h,v 1.78 2011/08/29 04:12:45 manu Exp $	*/
+/*	$NetBSD: puffs_sys.h,v 1.79 2012/04/08 15:04:41 manu Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006  Antti Kantee.  All Rights Reserved.
@@ -53,6 +53,7 @@ extern const struct vnodeopv_desc puffs_
 extern const struct vnodeopv_desc puffs_msgop_opv_desc;
 
 extern struct pool puffs_pnpool;
+extern struct pool puffs_vapool;
 
 #ifdef DEBUG
 #ifndef PUFFSDEBUG
@@ -89,6 +90,8 @@ extern int puffsdebug; /* puffs_subr.c *
     (((pmp)->pmp_flags & PUFFS_KFLAG_NOCACHE_PAGE) == 0)
 #define PUFFS_USE_FULLPNBUF(pmp)	\
     ((pmp)->pmp_flags & PUFFS_KFLAG_LOOKUP_FULLPNBUF)
+#define PUFFS_USE_FS_TTL(pmp)	\
+    ((pmp)->pmp_flags & PUFFS_KFLAG_CACHE_FS_TTL)
 
 #define PUFFS_WCACHEINFO(pmp)	0
 
@@ -210,6 +213,10 @@ struct puffs_node {
 	struct lockf *	pn_lockf;
 
 	kmutex_t	pn_sizemtx;	/* size modification mutex	*/
+	
+	int		pn_cn_timeout;	/* path cache */
+	int		pn_va_timeout;	/* attribute cache */
+	struct vattr *	pn_va_cache;	/* attribute cache */
 
 	LIST_ENTRY(puffs_node) pn_hashent;
 };

Index: src/sys/fs/puffs/puffs_vfsops.c
diff -u src/sys/fs/puffs/puffs_vfsops.c:1.100 src/sys/fs/puffs/puffs_vfsops.c:1.101
--- src/sys/fs/puffs/puffs_vfsops.c:1.100	Wed Oct 19 01:39:29 2011
+++ src/sys/fs/puffs/puffs_vfsops.c	Sun Apr  8 15:04:41 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_vfsops.c,v 1.100 2011/10/19 01:39:29 manu Exp $	*/
+/*	$NetBSD: puffs_vfsops.c,v 1.101 2012/04/08 15:04:41 manu Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.100 2011/10/19 01:39:29 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.101 2012/04/08 15:04:41 manu Exp $");
 
 #include <sys/param.h>
 #include <sys/mount.h>
@@ -763,6 +763,8 @@ puffs_vfsop_init(void)
 
 	pool_init(&puffs_pnpool, sizeof(struct puffs_node), 0, 0, 0,
 	    "puffpnpl", &pool_allocator_nointr, IPL_NONE);
+	pool_init(&puffs_vapool, sizeof(struct vattr), 0, 0, 0,
+	    "puffvapl", &pool_allocator_nointr, IPL_NONE);
 	puffs_msgif_init();
 }
 
@@ -772,6 +774,7 @@ puffs_vfsop_done(void)
 
 	puffs_msgif_destroy();
 	pool_destroy(&puffs_pnpool);
+	pool_destroy(&puffs_vapool);
 }
 
 int

Index: src/sys/fs/puffs/puffs_vnops.c
diff -u src/sys/fs/puffs/puffs_vnops.c:1.164 src/sys/fs/puffs/puffs_vnops.c:1.165
--- src/sys/fs/puffs/puffs_vnops.c:1.164	Fri Mar 16 23:13:48 2012
+++ src/sys/fs/puffs/puffs_vnops.c	Sun Apr  8 15:04:41 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_vnops.c,v 1.164 2012/03/16 23:13:48 jakllsch Exp $	*/
+/*	$NetBSD: puffs_vnops.c,v 1.165 2012/04/08 15:04:41 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.164 2012/03/16 23:13:48 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.165 2012/04/08 15:04:41 manu Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -40,6 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: puffs_vnops.
 #include <sys/namei.h>
 #include <sys/vnode.h>
 #include <sys/proc.h>
+#include <sys/kernel.h> /* For hz, hardclock_ticks */
 
 #include <uvm/uvm.h>
 
@@ -410,6 +411,8 @@ static int callrmdir(struct puffs_mount 
 static void callinactive(struct puffs_mount *, puffs_cookie_t, int);
 static void callreclaim(struct puffs_mount *, puffs_cookie_t);
 static int  flushvncache(struct vnode *, off_t, off_t, bool);
+static void update_va(struct vnode *, struct vattr *, struct vattr *,
+		      struct timespec *, struct timespec *);
 
 
 #define PUFFS_ABORT_LOOKUP	1
@@ -455,6 +458,8 @@ puffs_abortbutton(struct puffs_mount *pm
  * don't want to think of the consequences for the time being.
  */
 
+#define TTL_TO_TIMEOUT(ts) \
+    (hardclock_ticks + (ts->tv_sec * hz) + (ts->tv_nsec * hz / 1000000000))
 int
 puffs_vnop_lookup(void *v)
 {
@@ -467,14 +472,16 @@ puffs_vnop_lookup(void *v)
 	PUFFS_MSG_VARS(vn, lookup);
 	struct puffs_mount *pmp;
 	struct componentname *cnp;
-	struct vnode *vp, *dvp;
-	struct puffs_node *dpn;
+	struct vnode *vp, *dvp, *cvp;
+	struct puffs_node *dpn, *cpn;
 	int isdot;
 	int error;
 
 	pmp = MPTOPUFFSMP(ap->a_dvp->v_mount);
 	cnp = ap->a_cnp;
 	dvp = ap->a_dvp;
+	cvp = NULL;
+	cpn = NULL;
 	*ap->a_vpp = NULL;
 
 	/* r/o fs?  we check create later to handle EEXIST */
@@ -494,7 +501,31 @@ puffs_vnop_lookup(void *v)
 	if (PUFFS_USE_NAMECACHE(pmp)) {
 		error = cache_lookup(dvp, ap->a_vpp, cnp);
 
-		if (error >= 0)
+		if ((error == 0) && PUFFS_USE_FS_TTL(pmp)) {
+
+			cvp = *ap->a_vpp;
+			cpn = VPTOPP(cvp);
+			if (hardclock_ticks > cpn->pn_cn_timeout) {
+				cache_purge1(cvp, NULL, PURGE_CHILDREN);
+
+				/*
+				 * cached vnode (cvp) is still locked
+				 * so that we can reuse it upon a new
+				 * successful lookup. 
+				 */
+				*ap->a_vpp = NULL;
+				error = -1;
+			}
+		}
+
+		/*
+		 * Do not use negative caching, since the filesystem
+		 * provides no TTL for it.
+		 */
+		if ((error == ENOENT) && PUFFS_USE_FS_TTL(pmp))
+			error = -1;
+
+		if (error >= 0) 
 			return error;
 	}
 
@@ -503,12 +534,18 @@ puffs_vnop_lookup(void *v)
 		if (cnp->cn_nameiop == RENAME && (cnp->cn_flags & ISLASTCN))
 			return EISDIR;
 
+		if (cvp != NULL) 
+			vput(cvp);
+
 		vp = ap->a_dvp;
 		vref(vp);
 		*ap->a_vpp = vp;
 		return 0;
 	}
 
+	if (cvp != NULL)
+		mutex_enter(&cpn->pn_sizemtx);
+
 	PUFFS_MSG_ALLOC(vn, lookup);
 	puffs_makecn(&lookup_msg->pvnr_cn, &lookup_msg->pvnr_cn_cred,
 	    cnp, PUFFS_USE_FULLPNBUF(pmp));
@@ -545,7 +582,8 @@ puffs_vnop_lookup(void *v)
 			/* save negative cache entry */
 			} else {
 				if ((cnp->cn_flags & MAKEENTRY)
-				    && PUFFS_USE_NAMECACHE(pmp))
+				    && PUFFS_USE_NAMECACHE(pmp)
+				    && !PUFFS_USE_FS_TTL(pmp))
 					cache_enter(dvp, NULL, cnp);
 			}
 		}
@@ -564,21 +602,41 @@ puffs_vnop_lookup(void *v)
 		goto out;
 	}
 
-	error = puffs_cookie2vnode(pmp, lookup_msg->pvnr_newnode, 1, 1, &vp);
-	if (error == PUFFS_NOSUCHCOOKIE) {
-		error = puffs_getvnode(dvp->v_mount,
-		    lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype,
-		    lookup_msg->pvnr_size, lookup_msg->pvnr_rdev, &vp);
-		if (error) {
+	/*
+	 * On successfull relookup, do not create a new node.
+	 */
+	if (cvp != NULL) {
+		vp = cvp;
+	} else {
+		error = puffs_cookie2vnode(pmp, lookup_msg->pvnr_newnode,
+					   1, 1, &vp);
+
+		if (error == PUFFS_NOSUCHCOOKIE) {
+			error = puffs_getvnode(dvp->v_mount,
+			    lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype,
+			    lookup_msg->pvnr_size, lookup_msg->pvnr_rdev, &vp);
+			if (error) {
+				puffs_abortbutton(pmp, PUFFS_ABORT_LOOKUP,
+				    VPTOPNC(dvp), lookup_msg->pvnr_newnode,
+				    ap->a_cnp);
+				goto out;
+			}
+
+			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+		} else if (error) {
 			puffs_abortbutton(pmp, PUFFS_ABORT_LOOKUP, VPTOPNC(dvp),
 			    lookup_msg->pvnr_newnode, ap->a_cnp);
 			goto out;
 		}
-		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-	} else if (error) {
-		puffs_abortbutton(pmp, PUFFS_ABORT_LOOKUP, VPTOPNC(dvp),
-		    lookup_msg->pvnr_newnode, ap->a_cnp);
-		goto out;
+	}
+
+	/*
+	 * Update cache and TTL
+	 */
+	if (PUFFS_USE_FS_TTL(pmp)) {
+		struct timespec *va_ttl = &lookup_msg->pvnr_va_ttl;
+		struct timespec *cn_ttl = &lookup_msg->pvnr_cn_ttl;
+		update_va(vp, NULL, &lookup_msg->pvnr_va, va_ttl, cn_ttl);
 	}
 
 	*ap->a_vpp = vp;
@@ -594,6 +652,16 @@ puffs_vnop_lookup(void *v)
 		    strlen(cnp->cn_nameptr) - cnp->cn_namelen);
 
  out:
+	if (cvp != NULL) {
+		mutex_exit(&cpn->pn_sizemtx);
+	 	/*
+		 * We had a cached vnode but new lookup failed, 	
+		 * unlock it and let it die now.
+		 */
+		if (error != 0)
+			vput(cvp);
+	}
+
 	if (cnp->cn_flags & ISDOTDOT)
 		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
 
@@ -658,9 +726,19 @@ puffs_vnop_create(void *v)
 
 	error = puffs_newnode(mp, dvp, ap->a_vpp,
 	    create_msg->pvnr_newnode, cnp, ap->a_vap->va_type, 0);
-	if (error)
+	if (error) {
 		puffs_abortbutton(pmp, PUFFS_ABORT_CREATE, dpn->pn_cookie,
 		    create_msg->pvnr_newnode, cnp);
+		goto out;
+	}
+
+	if (PUFFS_USE_FS_TTL(pmp)) {
+		struct timespec *va_ttl = &create_msg->pvnr_va_ttl;
+		struct timespec *cn_ttl = &create_msg->pvnr_cn_ttl;
+		struct vattr *rvap = &create_msg->pvnr_va;
+
+		update_va(*ap->a_vpp, NULL, rvap, va_ttl, cn_ttl);
+	}
 
  out:
 	vput(dvp);
@@ -704,9 +782,19 @@ puffs_vnop_mknod(void *v)
 	error = puffs_newnode(mp, dvp, ap->a_vpp,
 	    mknod_msg->pvnr_newnode, cnp, ap->a_vap->va_type,
 	    ap->a_vap->va_rdev);
-	if (error)
+	if (error) {
 		puffs_abortbutton(pmp, PUFFS_ABORT_MKNOD, dpn->pn_cookie,
 		    mknod_msg->pvnr_newnode, cnp);
+		goto out;
+	}
+
+	if (PUFFS_USE_FS_TTL(pmp)) {
+		struct timespec *va_ttl = &mknod_msg->pvnr_va_ttl;
+		struct timespec *cn_ttl = &mknod_msg->pvnr_cn_ttl;
+		struct vattr *rvap = &mknod_msg->pvnr_va;
+
+		update_va(*ap->a_vpp, NULL, rvap, va_ttl, cn_ttl);
+	}
 
  out:
 	vput(dvp);
@@ -822,6 +910,60 @@ puffs_vnop_access(void *v)
 	return error;
 }
 
+static void
+update_va(struct vnode *vp, struct vattr *vap, struct vattr *rvap,
+	  struct timespec *va_ttl, struct timespec *cn_ttl)
+{
+	struct puffs_node *pn = VPTOPP(vp);
+
+	if (cn_ttl != NULL)
+		pn->pn_cn_timeout = TTL_TO_TIMEOUT(cn_ttl);
+
+	/*
+	 * Don't listen to the file server regarding special device
+	 * size info, the file server doesn't know anything about them.
+	 */
+	if (vp->v_type == VBLK || vp->v_type == VCHR)
+		rvap->va_size = vp->v_size;
+
+	/* Ditto for blocksize (ufs comment: this doesn't belong here) */
+	if (vp->v_type == VBLK)
+		rvap->va_blocksize = BLKDEV_IOSIZE;
+	else if (vp->v_type == VCHR)
+		rvap->va_blocksize = MAXBSIZE;
+
+	if (vap != NULL) {
+		(void) memcpy(vap, rvap, sizeof(struct vattr));
+		vap->va_fsid = vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0];
+
+		if (pn->pn_stat & PNODE_METACACHE_ATIME)
+			vap->va_atime = pn->pn_mc_atime;
+		if (pn->pn_stat & PNODE_METACACHE_CTIME)
+			vap->va_ctime = pn->pn_mc_ctime;
+		if (pn->pn_stat & PNODE_METACACHE_MTIME)
+			vap->va_mtime = pn->pn_mc_mtime;
+		if (pn->pn_stat & PNODE_METACACHE_SIZE)
+			vap->va_size = pn->pn_mc_size;
+	}
+
+	if (!(pn->pn_stat & PNODE_METACACHE_SIZE)) {
+		if (rvap->va_size != VNOVAL
+		    && vp->v_type != VBLK && vp->v_type != VCHR) {
+			uvm_vnp_setsize(vp, rvap->va_size);
+			pn->pn_serversize = rvap->va_size;
+		}
+	}
+
+	if (va_ttl != NULL) {
+		if (pn->pn_va_cache == NULL)
+			pn->pn_va_cache = pool_get(&puffs_vapool, PR_WAITOK);
+
+		(void)memcpy(pn->pn_va_cache, rvap, sizeof(*rvap));
+
+		pn->pn_va_timeout = TTL_TO_TIMEOUT(va_ttl);
+	}
+}
+
 int
 puffs_vnop_getattr(void *v)
 {
@@ -837,6 +979,7 @@ puffs_vnop_getattr(void *v)
 	struct puffs_mount *pmp = MPTOPUFFSMP(mp);
 	struct vattr *vap, *rvap;
 	struct puffs_node *pn = VPTOPP(vp);
+	struct timespec *va_ttl = NULL;
 	int error = 0;
 
 	/*
@@ -857,6 +1000,13 @@ puffs_vnop_getattr(void *v)
 	REFPN(pn);
 	vap = ap->a_vap;
 
+	if (PUFFS_USE_FS_TTL(pmp)) {
+		if (hardclock_ticks < pn->pn_va_timeout) {
+			update_va(vp, vap, pn->pn_va_cache, NULL, NULL);
+			goto out2;
+		}
+	}
+
 	PUFFS_MSG_ALLOC(vn, getattr);
 	vattr_null(&getattr_msg->pvnr_va);
 	puffs_credcvt(&getattr_msg->pvnr_cred, ap->a_cred);
@@ -869,41 +1019,17 @@ puffs_vnop_getattr(void *v)
 		goto out;
 
 	rvap = &getattr_msg->pvnr_va;
-	/*
-	 * Don't listen to the file server regarding special device
-	 * size info, the file server doesn't know anything about them.
-	 */
-	if (vp->v_type == VBLK || vp->v_type == VCHR)
-		rvap->va_size = vp->v_size;
 
-	/* Ditto for blocksize (ufs comment: this doesn't belong here) */
-	if (vp->v_type == VBLK)
-		rvap->va_blocksize = BLKDEV_IOSIZE;
-	else if (vp->v_type == VCHR)
-		rvap->va_blocksize = MAXBSIZE;
+	if (PUFFS_USE_FS_TTL(pmp))
+		va_ttl = &getattr_msg->pvnr_va_ttl;
 
-	(void) memcpy(vap, rvap, sizeof(struct vattr));
-	vap->va_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0];
-
-	if (pn->pn_stat & PNODE_METACACHE_ATIME)
-		vap->va_atime = pn->pn_mc_atime;
-	if (pn->pn_stat & PNODE_METACACHE_CTIME)
-		vap->va_ctime = pn->pn_mc_ctime;
-	if (pn->pn_stat & PNODE_METACACHE_MTIME)
-		vap->va_mtime = pn->pn_mc_mtime;
-	if (pn->pn_stat & PNODE_METACACHE_SIZE) {
-		vap->va_size = pn->pn_mc_size;
-	} else {
-		if (rvap->va_size != VNOVAL
-		    && vp->v_type != VBLK && vp->v_type != VCHR) {
-			uvm_vnp_setsize(vp, rvap->va_size);
-			pn->pn_serversize = rvap->va_size;
-		}
-	}
+	update_va(vp, vap, rvap, va_ttl, NULL);
 
  out:
-	puffs_releasenode(pn);
 	PUFFS_MSG_RELEASE(getattr);
+
+ out2:
+	puffs_releasenode(pn);
 	
 	mutex_exit(&pn->pn_sizemtx);
 
@@ -954,6 +1080,13 @@ dosetattr(struct vnode *vp, struct vattr
 		pn->pn_stat &= ~PNODE_METACACHE_MASK;
 	}
 
+	/*
+	 * Flush attribute cache so that another thread do 
+	 * not get a stale value during the operation.
+	 */
+	if (PUFFS_USE_FS_TTL(pmp))
+		pn->pn_va_timeout = 0;
+
 	PUFFS_MSG_ALLOC(vn, setattr);
 	(void)memcpy(&setattr_msg->pvnr_va, vap, sizeof(struct vattr));
 	puffs_credcvt(&setattr_msg->pvnr_cred, cred);
@@ -965,6 +1098,14 @@ dosetattr(struct vnode *vp, struct vattr
 	puffs_msg_enqueue(pmp, park_setattr);
 	if ((flags & SETATTR_ASYNC) == 0)
 		error = puffs_msg_wait2(pmp, park_setattr, vp->v_data, NULL);
+
+	if ((error == 0) && PUFFS_USE_FS_TTL(pmp)) {
+		struct timespec *va_ttl = &setattr_msg->pvnr_va_ttl;
+		struct vattr *rvap = &setattr_msg->pvnr_va;
+
+		update_va(vp, NULL, rvap, va_ttl, NULL);
+	}
+
 	PUFFS_MSG_RELEASE(setattr);
 	if ((flags & SETATTR_ASYNC) == 0) {
 		error = checkerr(pmp, error, __func__);
@@ -1340,6 +1481,7 @@ flushvncache(struct vnode *vp, off_t off
 	pflags = PGO_CLEANIT;
 	if (wait)
 		pflags |= PGO_SYNCIO;
+
 	mutex_enter(vp->v_interlock);
 	return VOP_PUTPAGES(vp, trunc_page(offlo), round_page(offhi), pflags);
 }
@@ -1550,9 +1692,19 @@ puffs_vnop_mkdir(void *v)
 
 	error = puffs_newnode(mp, dvp, ap->a_vpp,
 	    mkdir_msg->pvnr_newnode, cnp, VDIR, 0);
-	if (error)
+	if (error) {
 		puffs_abortbutton(pmp, PUFFS_ABORT_MKDIR, dpn->pn_cookie,
 		    mkdir_msg->pvnr_newnode, cnp);
+		goto out;
+	}
+
+	if (PUFFS_USE_FS_TTL(pmp)) {
+		struct timespec *va_ttl = &mkdir_msg->pvnr_va_ttl;
+		struct timespec *cn_ttl = &mkdir_msg->pvnr_cn_ttl;
+		struct vattr *rvap = &mkdir_msg->pvnr_va;
+
+		update_va(*ap->a_vpp, NULL, rvap, va_ttl, cn_ttl);
+	}
 
  out:
 	vput(dvp);
@@ -1703,9 +1855,19 @@ puffs_vnop_symlink(void *v)
 
 	error = puffs_newnode(mp, dvp, ap->a_vpp,
 	    symlink_msg->pvnr_newnode, cnp, VLNK, 0);
-	if (error)
+	if (error) {
 		puffs_abortbutton(pmp, PUFFS_ABORT_SYMLINK, dpn->pn_cookie,
 		    symlink_msg->pvnr_newnode, cnp);
+		goto out;
+	}
+
+	if (PUFFS_USE_FS_TTL(pmp)) {
+		struct timespec *va_ttl = &symlink_msg->pvnr_va_ttl;
+		struct timespec *cn_ttl = &symlink_msg->pvnr_cn_ttl;
+		struct vattr *rvap = &symlink_msg->pvnr_va;
+
+		update_va(*ap->a_vpp, NULL, rvap, va_ttl, cn_ttl);
+	}
 
  out:
 	vput(dvp);

Reply via email to