Module Name:    src
Committed By:   pooka
Date:           Fri Dec  4 20:26:35 UTC 2009

Modified Files:
        src/sys/fs/puffs: puffs_vnops.c

Log Message:
Push all information cached in the vnode to the file server before
issuing INACTIVE.  PR kern/42194.
Also, send setattr in fsync asynchronously if FSYNC_WAIT is not set.


To generate a diff of this commit:
cvs rdiff -u -r1.140 -r1.141 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_vnops.c
diff -u src/sys/fs/puffs/puffs_vnops.c:1.140 src/sys/fs/puffs/puffs_vnops.c:1.141
--- src/sys/fs/puffs/puffs_vnops.c:1.140	Thu Nov 19 16:21:04 2009
+++ src/sys/fs/puffs/puffs_vnops.c	Fri Dec  4 20:26:35 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_vnops.c,v 1.140 2009/11/19 16:21:04 pooka Exp $	*/
+/*	$NetBSD: puffs_vnops.c,v 1.141 2009/12/04 20:26:35 pooka 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.140 2009/11/19 16:21:04 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.141 2009/12/04 20:26:35 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -395,6 +395,8 @@
 			   struct componentname *);
 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);
+
 
 #define PUFFS_ABORT_LOOKUP	1
 #define PUFFS_ABORT_CREATE	2
@@ -883,13 +885,15 @@
 	return error;
 }
 
+#define SETATTR_CHSIZE	0x01
+#define SETATTR_ASYNC	0x02
 static int
-dosetattr(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, int chsize)
+dosetattr(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, int flags)
 {
 	PUFFS_MSG_VARS(vn, setattr);
 	struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
 	struct puffs_node *pn = vp->v_data;
-	int error;
+	int error = 0;
 
 	if ((vp->v_mount->mnt_flag & MNT_RDONLY) &&
 	    (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL
@@ -928,16 +932,24 @@
 	puffs_credcvt(&setattr_msg->pvnr_cred, cred);
 	puffs_msg_setinfo(park_setattr, PUFFSOP_VN,
 	    PUFFS_VN_SETATTR, VPTOPNC(vp));
+	if (flags & SETATTR_ASYNC)
+		puffs_msg_setfaf(park_setattr);
 
-	PUFFS_MSG_ENQUEUEWAIT2(pmp, park_setattr, vp->v_data, NULL, error);
+	puffs_msg_enqueue(pmp, park_setattr);
+	if ((flags & SETATTR_ASYNC) == 0)
+		error = puffs_msg_wait2(pmp, park_setattr, vp->v_data, NULL);
 	PUFFS_MSG_RELEASE(setattr);
-	error = checkerr(pmp, error, __func__);
-	if (error)
-		return error;
+	if ((flags & SETATTR_ASYNC) == 0) {
+		error = checkerr(pmp, error, __func__);
+		if (error)
+			return error;
+	} else {
+		error = 0;
+	}
 
 	if (vap->va_size != VNOVAL) {
 		pn->pn_serversize = vap->va_size;
-		if (chsize)
+		if (flags & SETATTR_CHSIZE)
 			uvm_vnp_setsize(vp, vap->va_size);
 	}
 
@@ -954,7 +966,7 @@
 		kauth_cred_t a_cred;
 	} */ *ap = v;
 
-	return dosetattr(ap->a_vp, ap->a_vap, ap->a_cred, 1);
+	return dosetattr(ap->a_vp, ap->a_vap, ap->a_cred, SETATTR_CHSIZE);
 }
 
 static __inline int
@@ -1006,6 +1018,7 @@
 	pnode = vp->v_data;
 
 	if (doinact(pmp, pnode->pn_stat & PNODE_DOINACT)) {
+		flushvncache(vp, 0, 0, false);
 		PUFFS_MSG_ALLOC(vn, inactive);
 		puffs_msg_setinfo(park_inactive, PUFFSOP_VN,
 		    PUFFS_VN_INACTIVE, VPTOPNC(vp));
@@ -1269,31 +1282,19 @@
 	}
 }
 
-int
-puffs_vnop_fsync(void *v)
+static int
+flushvncache(struct vnode *vp, off_t offlo, off_t offhi, bool wait)
 {
-	struct vop_fsync_args /* {
-		const struct vnodeop_desc *a_desc;
-		struct vnode *a_vp;
-		kauth_cred_t a_cred;
-		int a_flags;
-		off_t a_offlo;
-		off_t a_offhi;
-	} */ *ap = v;
-	PUFFS_MSG_VARS(vn, fsync);
-	struct vnode *vp = ap->a_vp;
-	struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
-	struct puffs_node *pn;
+	struct puffs_node *pn = VPTOPP(vp);
 	struct vattr va;
-	int pflags, error, dofaf;
-
-	pn = VPTOPP(vp);
+	int pflags, error;
 
 	/* flush out information from our metacache, see vop_setattr */
 	if (pn->pn_stat & PNODE_METACACHE_MASK
 	    && (pn->pn_stat & PNODE_DYING) == 0) {
 		vattr_null(&va);
-		error = VOP_SETATTR(vp, &va, FSCRED); 
+		error = dosetattr(vp, &va, FSCRED,
+		    SETATTR_CHSIZE | (wait ? 0 : SETATTR_ASYNC));
 		if (error)
 			return error;
 	}
@@ -1302,11 +1303,31 @@
 	 * flush pages to avoid being overly dirty
 	 */
 	pflags = PGO_CLEANIT;
-	if (ap->a_flags & FSYNC_WAIT)
+	if (wait)
 		pflags |= PGO_SYNCIO;
 	mutex_enter(&vp->v_interlock);
-	error = VOP_PUTPAGES(vp, trunc_page(ap->a_offlo),
-	    round_page(ap->a_offhi), pflags);
+	return VOP_PUTPAGES(vp, trunc_page(offlo), round_page(offhi), pflags);
+}
+
+int
+puffs_vnop_fsync(void *v)
+{
+	struct vop_fsync_args /* {
+		const struct vnodeop_desc *a_desc;
+		struct vnode *a_vp;
+		kauth_cred_t a_cred;
+		int a_flags;
+		off_t a_offlo;
+		off_t a_offhi;
+	} */ *ap = v;
+	PUFFS_MSG_VARS(vn, fsync);
+	struct vnode *vp = ap->a_vp;
+	struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
+	struct puffs_node *pn = VPTOPP(vp);
+	int error, dofaf;
+
+	error = flushvncache(vp, ap->a_offlo, ap->a_offhi,
+	    (ap->a_flags & FSYNC_WAIT) == FSYNC_WAIT);
 	if (error)
 		return error;
 

Reply via email to