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;