fix a page locking deadlock problem for nfs.

add a flag that specify if the file can be truncated safely or not
to nfsm_loadattr and friends.  when it isn't safe, just mark the nfsnode
as "should be truncated later".

ok'ed by Frank van der Linden and Chuck Silvers.
close kern/18036.
This commit is contained in:
yamt 2002-10-21 12:52:32 +00:00
parent 75a75e1d7a
commit 005c29fafb
8 changed files with 124 additions and 69 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_bio.c,v 1.82 2002/09/01 10:39:38 bouyer Exp $ */ /* $NetBSD: nfs_bio.c,v 1.83 2002/10/21 12:52:32 yamt Exp $ */
/* /*
* Copyright (c) 1989, 1993 * Copyright (c) 1989, 1993
@ -39,7 +39,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.82 2002/09/01 10:39:38 bouyer Exp $"); __KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.83 2002/10/21 12:52:32 yamt Exp $");
#include "opt_nfs.h" #include "opt_nfs.h"
#include "opt_ddb.h" #include "opt_ddb.h"
@ -1133,6 +1133,14 @@ nfs_getpages(v)
np->n_rcred = curproc->p_ucred; np->n_rcred = curproc->p_ucred;
crhold(np->n_rcred); crhold(np->n_rcred);
/*
* if we have delayed truncation and it's safe, do it now.
*/
if (ap->a_flags & PGO_SYNCIO) {
nfs_delayedtruncate(vp);
}
/* /*
* call the genfs code to get the pages. `pgs' may be NULL * call the genfs code to get the pages. `pgs' may be NULL
* when doing read-ahead. * when doing read-ahead.

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_nqlease.c,v 1.40 2002/05/12 23:04:35 matt Exp $ */ /* $NetBSD: nfs_nqlease.c,v 1.41 2002/10/21 12:52:33 yamt Exp $ */
/* /*
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -53,7 +53,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_nqlease.c,v 1.40 2002/05/12 23:04:35 matt Exp $"); __KERNEL_RCSID(0, "$NetBSD: nfs_nqlease.c,v 1.41 2002/10/21 12:52:33 yamt Exp $");
#include "fs_nfs.h" #include "fs_nfs.h"
#include "opt_nfs.h" #include "opt_nfs.h"
@ -880,7 +880,7 @@ nqnfs_getlease(vp, rwflag, cred, p)
if (reqtime > time.tv_sec) { if (reqtime > time.tv_sec) {
frev = fxdr_hyper(tl); frev = fxdr_hyper(tl);
nqnfs_clientlease(nmp, np, rwflag, cachable, reqtime, frev); nqnfs_clientlease(nmp, np, rwflag, cachable, reqtime, frev);
nfsm_loadattr(vp, (struct vattr *)0); nfsm_loadattr(vp, (struct vattr *)0, 0);
} else } else
error = NQNFS_EXPIRED; error = NQNFS_EXPIRED;
nfsm_reqdone; nfsm_reqdone;

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_subs.c,v 1.104 2002/08/23 05:38:51 enami Exp $ */ /* $NetBSD: nfs_subs.c,v 1.105 2002/10/21 12:52:33 yamt Exp $ */
/* /*
* Copyright (c) 1989, 1993 * Copyright (c) 1989, 1993
@ -74,7 +74,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.104 2002/08/23 05:38:51 enami Exp $"); __KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.105 2002/10/21 12:52:33 yamt Exp $");
#include "fs_nfs.h" #include "fs_nfs.h"
#include "opt_nfs.h" #include "opt_nfs.h"
@ -1527,11 +1527,12 @@ nfs_vfs_done()
* copy the attributes to *vaper * copy the attributes to *vaper
*/ */
int int
nfsm_loadattrcache(vpp, mdp, dposp, vaper) nfsm_loadattrcache(vpp, mdp, dposp, vaper, flags)
struct vnode **vpp; struct vnode **vpp;
struct mbuf **mdp; struct mbuf **mdp;
caddr_t *dposp; caddr_t *dposp;
struct vattr *vaper; struct vattr *vaper;
int flags;
{ {
int32_t t1; int32_t t1;
caddr_t cp2; caddr_t cp2;
@ -1544,14 +1545,15 @@ nfsm_loadattrcache(vpp, mdp, dposp, vaper)
error = nfsm_disct(mdp, dposp, NFSX_FATTR(v3), t1, &cp2); error = nfsm_disct(mdp, dposp, NFSX_FATTR(v3), t1, &cp2);
if (error) if (error)
return (error); return (error);
return nfs_loadattrcache(vpp, (struct nfs_fattr *)cp2, vaper); return nfs_loadattrcache(vpp, (struct nfs_fattr *)cp2, vaper, flags);
} }
int int
nfs_loadattrcache(vpp, fp, vaper) nfs_loadattrcache(vpp, fp, vaper, flags)
struct vnode **vpp; struct vnode **vpp;
struct nfs_fattr *fp; struct nfs_fattr *fp;
struct vattr *vaper; struct vattr *vaper;
int flags;
{ {
struct vnode *vp = *vpp; struct vnode *vp = *vpp;
struct vattr *vap; struct vattr *vap;
@ -1699,10 +1701,20 @@ nfs_loadattrcache(vpp, fp, vaper)
} else { } else {
np->n_size = vap->va_size; np->n_size = vap->va_size;
if (vap->va_type == VREG) { if (vap->va_type == VREG) {
if ((flags & NAC_NOTRUNC)
&& np->n_size < vp->v_size) {
/*
* we can't free pages now because
* the pages can be owned by ourselves.
*/
np->n_flag |= NTRUNCDELAYED;
}
else {
uvm_vnp_setsize(vp, np->n_size); uvm_vnp_setsize(vp, np->n_size);
} }
} }
} }
}
np->n_attrstamp = time.tv_sec; np->n_attrstamp = time.tv_sec;
if (vaper != NULL) { if (vaper != NULL) {
memcpy((caddr_t)vaper, (caddr_t)vap, sizeof(*vap)); memcpy((caddr_t)vaper, (caddr_t)vap, sizeof(*vap));
@ -1758,6 +1770,18 @@ nfs_getattrcache(vp, vaper)
return (0); return (0);
} }
void
nfs_delayedtruncate(vp)
struct vnode *vp;
{
struct nfsnode *np = VTONFS(vp);
if (np->n_flag & NTRUNCDELAYED) {
np->n_flag &= ~NTRUNCDELAYED;
uvm_vnp_setsize(vp, np->n_size);
}
}
/* /*
* Heuristic to see if the server XDR encodes directory cookies or not. * Heuristic to see if the server XDR encodes directory cookies or not.
* it is not supposed to, but a lot of servers may do this. Also, since * it is not supposed to, but a lot of servers may do this. Also, since

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_var.h,v 1.23 2002/03/17 22:22:40 christos Exp $ */ /* $NetBSD: nfs_var.h,v 1.24 2002/10/21 12:52:34 yamt Exp $ */
/*- /*-
* Copyright (c) 1996 The NetBSD Foundation, Inc. * Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -243,10 +243,11 @@ struct nfsdircache *nfs_enterdircache __P((struct vnode *, off_t, off_t,
void nfs_invaldircache __P((struct vnode *, int)); void nfs_invaldircache __P((struct vnode *, int));
void nfs_init __P((void)); void nfs_init __P((void));
int nfsm_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *, int nfsm_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *,
struct vattr *)); struct vattr *, int flags));
int nfs_loadattrcache __P((struct vnode **, struct nfs_fattr *, int nfs_loadattrcache __P((struct vnode **, struct nfs_fattr *,
struct vattr *)); struct vattr *, int flags));
int nfs_getattrcache __P((struct vnode *, struct vattr *)); int nfs_getattrcache __P((struct vnode *, struct vattr *));
void nfs_delayedtruncate __P((struct vnode *));
int nfs_namei __P((struct nameidata *, fhandle_t *, int, struct nfssvc_sock *, int nfs_namei __P((struct nameidata *, fhandle_t *, int, struct nfssvc_sock *,
struct mbuf *, struct mbuf **, caddr_t *, struct vnode **, struct mbuf *, struct mbuf **, caddr_t *, struct vnode **,
struct proc *, int, int)); struct proc *, int, int));
@ -264,6 +265,9 @@ int nfsrv_setpublicfs __P((struct mount *, struct netexport *,
int nfs_ispublicfh __P((fhandle_t *)); int nfs_ispublicfh __P((fhandle_t *));
int netaddr_match __P((int, union nethostaddr *, struct mbuf *)); int netaddr_match __P((int, union nethostaddr *, struct mbuf *));
/* flags for nfs_loadattrcache and friends */
#define NAC_NOTRUNC 1 /* don't truncate file size */
void nfs_clearcommit __P((struct mount *)); void nfs_clearcommit __P((struct mount *));
void nfs_merge_commit_ranges __P((struct vnode *)); void nfs_merge_commit_ranges __P((struct vnode *));
int nfs_in_committed_range __P((struct vnode *, off_t, off_t)); int nfs_in_committed_range __P((struct vnode *, off_t, off_t));

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_vfsops.c,v 1.118 2002/10/21 03:58:07 enami Exp $ */ /* $NetBSD: nfs_vfsops.c,v 1.119 2002/10/21 12:52:34 yamt Exp $ */
/* /*
* Copyright (c) 1989, 1993, 1995 * Copyright (c) 1989, 1993, 1995
@ -39,7 +39,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c,v 1.118 2002/10/21 03:58:07 enami Exp $"); __KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c,v 1.119 2002/10/21 12:52:34 yamt Exp $");
#if defined(_KERNEL_OPT) #if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h" #include "opt_compat_netbsd.h"
@ -169,7 +169,7 @@ nfs_statfs(mp, sbp, p)
nfsm_fhtom(vp, v3); nfsm_fhtom(vp, v3);
nfsm_request(vp, NFSPROC_FSSTAT, p, cred); nfsm_request(vp, NFSPROC_FSSTAT, p, cred);
if (v3) if (v3)
nfsm_postop_attr(vp, retattr); nfsm_postop_attr(vp, retattr, 0);
if (error) { if (error) {
if (mrep != NULL) if (mrep != NULL)
m_free(mrep); m_free(mrep);
@ -237,7 +237,7 @@ nfs_fsinfo(nmp, vp, cred, p)
nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1)); nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1));
nfsm_fhtom(vp, 1); nfsm_fhtom(vp, 1);
nfsm_request(vp, NFSPROC_FSINFO, p, cred); nfsm_request(vp, NFSPROC_FSINFO, p, cred);
nfsm_postop_attr(vp, retattr); nfsm_postop_attr(vp, retattr, 0);
if (!error) { if (!error) {
nfsm_dissect(fsp, struct nfsv3_fsinfo *, NFSX_V3FSINFO); nfsm_dissect(fsp, struct nfsv3_fsinfo *, NFSX_V3FSINFO);
pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref); pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref);

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_vnops.c,v 1.152 2002/10/18 19:08:15 thorpej Exp $ */ /* $NetBSD: nfs_vnops.c,v 1.153 2002/10/21 12:52:35 yamt Exp $ */
/* /*
* Copyright (c) 1989, 1993 * Copyright (c) 1989, 1993
@ -43,7 +43,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.152 2002/10/18 19:08:15 thorpej Exp $"); __KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.153 2002/10/21 12:52:35 yamt Exp $");
#include "opt_nfs.h" #include "opt_nfs.h"
#include "opt_uvmhist.h" #include "opt_uvmhist.h"
@ -364,7 +364,7 @@ nfs_access(v)
} }
*tl = txdr_unsigned(mode); *tl = txdr_unsigned(mode);
nfsm_request(vp, NFSPROC_ACCESS, ap->a_p, ap->a_cred); nfsm_request(vp, NFSPROC_ACCESS, ap->a_p, ap->a_cred);
nfsm_postop_attr(vp, attrflag); nfsm_postop_attr(vp, attrflag, 0);
if (!error) { if (!error) {
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
rmode = fxdr_unsigned(u_int32_t, *tl); rmode = fxdr_unsigned(u_int32_t, *tl);
@ -628,7 +628,7 @@ nfs_getattr(v)
nfsm_fhtom(vp, v3); nfsm_fhtom(vp, v3);
nfsm_request(vp, NFSPROC_GETATTR, ap->a_p, ap->a_cred); nfsm_request(vp, NFSPROC_GETATTR, ap->a_p, ap->a_cred);
if (!error) { if (!error) {
nfsm_loadattr(vp, ap->a_vap); nfsm_loadattr(vp, ap->a_vap, 0);
if (vp->v_type == VDIR && if (vp->v_type == VDIR &&
ap->a_vap->va_blocksize < NFS_DIRFRAGSIZ) ap->a_vap->va_blocksize < NFS_DIRFRAGSIZ)
ap->a_vap->va_blocksize = NFS_DIRFRAGSIZ; ap->a_vap->va_blocksize = NFS_DIRFRAGSIZ;
@ -769,9 +769,9 @@ nfs_setattrrpc(vp, vap, cred, procp)
} }
nfsm_request(vp, NFSPROC_SETATTR, procp, cred); nfsm_request(vp, NFSPROC_SETATTR, procp, cred);
if (v3) { if (v3) {
nfsm_wcc_data(vp, wccflag); nfsm_wcc_data(vp, wccflag, 0);
} else } else
nfsm_loadattr(vp, (struct vattr *)0); nfsm_loadattr(vp, (struct vattr *)0, 0);
nfsm_reqdone; nfsm_reqdone;
return (error); return (error);
} }
@ -910,7 +910,7 @@ dorpc:
nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_proc, cnp->cn_cred); nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_proc, cnp->cn_cred);
if (error) { if (error) {
nfsm_postop_attr(dvp, attrflag); nfsm_postop_attr(dvp, attrflag, 0);
m_freem(mrep); m_freem(mrep);
goto nfsmout; goto nfsmout;
} }
@ -931,10 +931,10 @@ dorpc:
} }
newvp = NFSTOV(np); newvp = NFSTOV(np);
if (v3) { if (v3) {
nfsm_postop_attr(newvp, attrflag); nfsm_postop_attr(newvp, attrflag, 0);
nfsm_postop_attr(dvp, attrflag); nfsm_postop_attr(dvp, attrflag, 0);
} else } else
nfsm_loadattr(newvp, (struct vattr *)0); nfsm_loadattr(newvp, (struct vattr *)0, 0);
*vpp = newvp; *vpp = newvp;
m_freem(mrep); m_freem(mrep);
cnp->cn_flags |= SAVENAME; cnp->cn_flags |= SAVENAME;
@ -958,10 +958,10 @@ dorpc:
VREF(dvp); VREF(dvp);
newvp = dvp; newvp = dvp;
if (v3) { if (v3) {
nfsm_postop_attr(newvp, attrflag); nfsm_postop_attr(newvp, attrflag, 0);
nfsm_postop_attr(dvp, attrflag); nfsm_postop_attr(dvp, attrflag, 0);
} else } else
nfsm_loadattr(newvp, (struct vattr *)0); nfsm_loadattr(newvp, (struct vattr *)0, 0);
} else if (flags & ISDOTDOT) { } else if (flags & ISDOTDOT) {
/* /*
* ".." lookup * ".." lookup
@ -979,10 +979,10 @@ dorpc:
newvp = NFSTOV(np); newvp = NFSTOV(np);
if (v3) { if (v3) {
nfsm_postop_attr(newvp, attrflag); nfsm_postop_attr(newvp, attrflag, 0);
nfsm_postop_attr(dvp, attrflag); nfsm_postop_attr(dvp, attrflag, 0);
} else } else
nfsm_loadattr(newvp, (struct vattr *)0); nfsm_loadattr(newvp, (struct vattr *)0, 0);
if (lockparent && (flags & ISLASTCN)) { if (lockparent && (flags & ISLASTCN)) {
if ((error = vn_lock(dvp, LK_EXCLUSIVE))) { if ((error = vn_lock(dvp, LK_EXCLUSIVE))) {
@ -1003,10 +1003,10 @@ dorpc:
} }
newvp = NFSTOV(np); newvp = NFSTOV(np);
if (v3) { if (v3) {
nfsm_postop_attr(newvp, attrflag); nfsm_postop_attr(newvp, attrflag, 0);
nfsm_postop_attr(dvp, attrflag); nfsm_postop_attr(dvp, attrflag, 0);
} else } else
nfsm_loadattr(newvp, (struct vattr *)0); nfsm_loadattr(newvp, (struct vattr *)0, 0);
if (!lockparent || !(flags & ISLASTCN)) { if (!lockparent || !(flags & ISLASTCN)) {
VOP_UNLOCK(dvp, 0); VOP_UNLOCK(dvp, 0);
cnp->cn_flags |= PDIRUNLOCK; cnp->cn_flags |= PDIRUNLOCK;
@ -1118,7 +1118,7 @@ nfs_readlinkrpc(vp, uiop, cred)
nfsm_fhtom(vp, v3); nfsm_fhtom(vp, v3);
nfsm_request(vp, NFSPROC_READLINK, uiop->uio_procp, cred); nfsm_request(vp, NFSPROC_READLINK, uiop->uio_procp, cred);
if (v3) if (v3)
nfsm_postop_attr(vp, attrflag); nfsm_postop_attr(vp, attrflag, 0);
if (!error) { if (!error) {
nfsm_strsiz(len, NFS_MAXPATHLEN); nfsm_strsiz(len, NFS_MAXPATHLEN);
nfsm_mtouio(uiop, len); nfsm_mtouio(uiop, len);
@ -1169,7 +1169,7 @@ nfs_readrpc(vp, uiop)
nfsm_request(vp, NFSPROC_READ, uiop->uio_procp, nfsm_request(vp, NFSPROC_READ, uiop->uio_procp,
VTONFS(vp)->n_rcred); VTONFS(vp)->n_rcred);
if (v3) { if (v3) {
nfsm_postop_attr(vp, attrflag); nfsm_postop_attr(vp, attrflag, NAC_NOTRUNC);
if (error) { if (error) {
m_freem(mrep); m_freem(mrep);
goto nfsmout; goto nfsmout;
@ -1177,7 +1177,7 @@ nfs_readrpc(vp, uiop)
nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
eof = fxdr_unsigned(int, *(tl + 1)); eof = fxdr_unsigned(int, *(tl + 1));
} else } else
nfsm_loadattr(vp, (struct vattr *)0); nfsm_loadattr(vp, (struct vattr *)0, NAC_NOTRUNC);
nfsm_strsiz(retlen, nmp->nm_rsize); nfsm_strsiz(retlen, nmp->nm_rsize);
nfsm_mtouio(uiop, retlen); nfsm_mtouio(uiop, retlen);
m_freem(mrep); m_freem(mrep);
@ -1254,7 +1254,7 @@ nfs_writerpc(vp, uiop, iomode, must_commit)
VTONFS(vp)->n_wcred); VTONFS(vp)->n_wcred);
if (v3) { if (v3) {
wccflag = NFSV3_WCCCHK; wccflag = NFSV3_WCCCHK;
nfsm_wcc_data(vp, wccflag); nfsm_wcc_data(vp, wccflag, NAC_NOTRUNC);
if (!error) { if (!error) {
nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED
+ NFSX_V3WRITEVERF); + NFSX_V3WRITEVERF);
@ -1296,7 +1296,7 @@ nfs_writerpc(vp, uiop, iomode, must_commit)
} }
} }
} else } else
nfsm_loadattr(vp, (struct vattr *)0); nfsm_loadattr(vp, (struct vattr *)0, NAC_NOTRUNC);
if (wccflag) if (wccflag)
VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr->va_mtime.tv_sec; VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr->va_mtime.tv_sec;
m_freem(mrep); m_freem(mrep);
@ -1379,7 +1379,7 @@ nfs_mknodrpc(dvp, vpp, cnp, vap)
} }
} }
if (v3) if (v3)
nfsm_wcc_data(dvp, wccflag); nfsm_wcc_data(dvp, wccflag, 0);
nfsm_reqdone; nfsm_reqdone;
if (error) { if (error) {
if (newvp) if (newvp)
@ -1501,7 +1501,7 @@ again:
} }
} }
if (v3) if (v3)
nfsm_wcc_data(dvp, wccflag); nfsm_wcc_data(dvp, wccflag, 0);
nfsm_reqdone; nfsm_reqdone;
if (error) { if (error) {
if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) { if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) {
@ -1639,7 +1639,7 @@ nfs_removerpc(dvp, name, namelen, cred, proc)
nfsm_strtom(name, namelen, NFS_MAXNAMLEN); nfsm_strtom(name, namelen, NFS_MAXNAMLEN);
nfsm_request(dvp, NFSPROC_REMOVE, proc, cred); nfsm_request(dvp, NFSPROC_REMOVE, proc, cred);
if (v3) if (v3)
nfsm_wcc_data(dvp, wccflag); nfsm_wcc_data(dvp, wccflag, 0);
nfsm_reqdone; nfsm_reqdone;
VTONFS(dvp)->n_flag |= NMODIFIED; VTONFS(dvp)->n_flag |= NMODIFIED;
if (!wccflag) if (!wccflag)
@ -1763,8 +1763,8 @@ nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, proc)
nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN); nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN);
nfsm_request(fdvp, NFSPROC_RENAME, proc, cred); nfsm_request(fdvp, NFSPROC_RENAME, proc, cred);
if (v3) { if (v3) {
nfsm_wcc_data(fdvp, fwccflag); nfsm_wcc_data(fdvp, fwccflag, 0);
nfsm_wcc_data(tdvp, twccflag); nfsm_wcc_data(tdvp, twccflag, 0);
} }
nfsm_reqdone; nfsm_reqdone;
VTONFS(fdvp)->n_flag |= NMODIFIED; VTONFS(fdvp)->n_flag |= NMODIFIED;
@ -1830,8 +1830,8 @@ nfs_link(v)
nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
nfsm_request(vp, NFSPROC_LINK, cnp->cn_proc, cnp->cn_cred); nfsm_request(vp, NFSPROC_LINK, cnp->cn_proc, cnp->cn_cred);
if (v3) { if (v3) {
nfsm_postop_attr(vp, attrflag); nfsm_postop_attr(vp, attrflag, 0);
nfsm_wcc_data(dvp, wccflag); nfsm_wcc_data(dvp, wccflag, 0);
} }
nfsm_reqdone; nfsm_reqdone;
PNBUF_PUT(cnp->cn_pnbuf); PNBUF_PUT(cnp->cn_pnbuf);
@ -1901,7 +1901,7 @@ nfs_symlink(v)
if (v3) { if (v3) {
if (!error) if (!error)
nfsm_mtofh(dvp, newvp, v3, gotvp); nfsm_mtofh(dvp, newvp, v3, gotvp);
nfsm_wcc_data(dvp, wccflag); nfsm_wcc_data(dvp, wccflag, 0);
} }
nfsm_reqdone; nfsm_reqdone;
/* /*
@ -1981,7 +1981,7 @@ nfs_mkdir(v)
if (!error) if (!error)
nfsm_mtofh(dvp, newvp, v3, gotvp); nfsm_mtofh(dvp, newvp, v3, gotvp);
if (v3) if (v3)
nfsm_wcc_data(dvp, wccflag); nfsm_wcc_data(dvp, wccflag, 0);
nfsm_reqdone; nfsm_reqdone;
VTONFS(dvp)->n_flag |= NMODIFIED; VTONFS(dvp)->n_flag |= NMODIFIED;
if (!wccflag) if (!wccflag)
@ -2052,7 +2052,7 @@ nfs_rmdir(v)
nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_proc, cnp->cn_cred); nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_proc, cnp->cn_cred);
if (v3) if (v3)
nfsm_wcc_data(dvp, wccflag); nfsm_wcc_data(dvp, wccflag, 0);
nfsm_reqdone; nfsm_reqdone;
PNBUF_PUT(cnp->cn_pnbuf); PNBUF_PUT(cnp->cn_pnbuf);
VTONFS(dvp)->n_flag |= NMODIFIED; VTONFS(dvp)->n_flag |= NMODIFIED;
@ -2228,7 +2228,7 @@ nfs_readdirrpc(vp, uiop, cred)
nfsm_request(vp, NFSPROC_READDIR, uiop->uio_procp, cred); nfsm_request(vp, NFSPROC_READDIR, uiop->uio_procp, cred);
nrpcs++; nrpcs++;
if (v3) { if (v3) {
nfsm_postop_attr(vp, attrflag); nfsm_postop_attr(vp, attrflag, 0);
if (!error) { if (!error) {
nfsm_dissect(tl, u_int32_t *, nfsm_dissect(tl, u_int32_t *,
2 * NFSX_UNSIGNED); 2 * NFSX_UNSIGNED);
@ -2422,7 +2422,7 @@ nfs_readdirplusrpc(vp, uiop, cred)
*tl++ = txdr_unsigned(nmp->nm_readdirsize); *tl++ = txdr_unsigned(nmp->nm_readdirsize);
*tl = txdr_unsigned(nmp->nm_rsize); *tl = txdr_unsigned(nmp->nm_rsize);
nfsm_request(vp, NFSPROC_READDIRPLUS, uiop->uio_procp, cred); nfsm_request(vp, NFSPROC_READDIRPLUS, uiop->uio_procp, cred);
nfsm_postop_attr(vp, attrflag); nfsm_postop_attr(vp, attrflag, 0);
if (error) { if (error) {
m_freem(mrep); m_freem(mrep);
goto nfsmout; goto nfsmout;
@ -2529,7 +2529,7 @@ nfs_readdirplusrpc(vp, uiop, cred)
if (!error) { if (!error) {
const char *cp; const char *cp;
nfs_loadattrcache(&newvp, &fattr, 0); nfs_loadattrcache(&newvp, &fattr, 0, 0);
dp->d_type = dp->d_type =
IFTODT(VTTOIF(np->n_vattr->va_type)); IFTODT(VTTOIF(np->n_vattr->va_type));
ndp->ni_vp = newvp; ndp->ni_vp = newvp;
@ -2717,14 +2717,14 @@ nfs_lookitup(dvp, name, len, cred, procp, npp)
newvp = NFSTOV(np); newvp = NFSTOV(np);
} }
if (v3) { if (v3) {
nfsm_postop_attr(newvp, attrflag); nfsm_postop_attr(newvp, attrflag, 0);
if (!attrflag && *npp == NULL) { if (!attrflag && *npp == NULL) {
m_freem(mrep); m_freem(mrep);
vput(newvp); vput(newvp);
return (ENOENT); return (ENOENT);
} }
} else } else
nfsm_loadattr(newvp, (struct vattr *)0); nfsm_loadattr(newvp, (struct vattr *)0, 0);
} }
nfsm_reqdone; nfsm_reqdone;
if (npp && *npp == NULL) { if (npp && *npp == NULL) {
@ -2770,7 +2770,7 @@ nfs_commit(vp, offset, cnt, procp)
tl += 2; tl += 2;
*tl = txdr_unsigned(cnt); *tl = txdr_unsigned(cnt);
nfsm_request(vp, NFSPROC_COMMIT, procp, VTONFS(vp)->n_wcred); nfsm_request(vp, NFSPROC_COMMIT, procp, VTONFS(vp)->n_wcred);
nfsm_wcc_data(vp, wccflag); nfsm_wcc_data(vp, wccflag, 0);
if (!error) { if (!error) {
nfsm_dissect(tl, u_int32_t *, NFSX_V3WRITEVERF); nfsm_dissect(tl, u_int32_t *, NFSX_V3WRITEVERF);
if (memcmp((caddr_t)nmp->nm_verf, (caddr_t)tl, if (memcmp((caddr_t)nmp->nm_verf, (caddr_t)tl,
@ -2949,7 +2949,7 @@ nfs_pathconf(v)
nfsm_fhtom(vp, 1); nfsm_fhtom(vp, 1);
nfsm_request(vp, NFSPROC_PATHCONF, nfsm_request(vp, NFSPROC_PATHCONF,
curproc, curproc->p_ucred); /* XXX */ curproc, curproc->p_ucred); /* XXX */
nfsm_postop_attr(vp, attrflag); nfsm_postop_attr(vp, attrflag, 0);
if (!error) { if (!error) {
nfsm_dissect(pcp, struct nfsv3_pathconf *, nfsm_dissect(pcp, struct nfsv3_pathconf *,
NFSX_V3PATHCONF); NFSX_V3PATHCONF);
@ -3095,6 +3095,23 @@ nfs_bwrite(v)
return (bwrite(ap->a_bp)); return (bwrite(ap->a_bp));
} }
/*
* nfs unlock wrapper.
*/
int
nfs_unlock(void *v)
{
struct vop_unlock_args /* {
struct vnode *a_vp;
int a_flags;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
nfs_delayedtruncate(vp);
return genfs_unlock(v);
}
/* /*
* nfs special file access vnode op. * nfs special file access vnode op.
* Essentially just get vattr and then imitate iaccess() since the device is * Essentially just get vattr and then imitate iaccess() since the device is

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsm_subs.h,v 1.21 2002/04/03 00:20:15 wrstuden Exp $ */ /* $NetBSD: nfsm_subs.h,v 1.22 2002/10/21 12:52:36 yamt Exp $ */
/* /*
* Copyright (c) 1989, 1993 * Copyright (c) 1989, 1993
@ -170,7 +170,7 @@
nfsm_adv(NFSX_V3FATTR); \ nfsm_adv(NFSX_V3FATTR); \
} \ } \
if (f) \ if (f) \
nfsm_loadattr((v), (struct vattr *)0); \ nfsm_loadattr((v), (struct vattr *)0, 0); \
} }
#define nfsm_getfh(f, s, v3) \ #define nfsm_getfh(f, s, v3) \
@ -186,21 +186,22 @@
(s) = NFSX_V2FH; \ (s) = NFSX_V2FH; \
nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); } nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); }
#define nfsm_loadattr(v, a) \ #define nfsm_loadattr(v, a, flags) \
{ struct vnode *ttvp = (v); \ { struct vnode *ttvp = (v); \
if ((t1 = nfsm_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \ if ((t1 = nfsm_loadattrcache(&ttvp, &md, &dpos, (a), (flags))) \
!= 0) { \
error = t1; \ error = t1; \
m_freem(mrep); \ m_freem(mrep); \
goto nfsmout; \ goto nfsmout; \
} \ } \
(v) = ttvp; } (v) = ttvp; }
#define nfsm_postop_attr(v, f) \ #define nfsm_postop_attr(v, f, flags) \
{ struct vnode *ttvp = (v); \ { struct vnode *ttvp = (v); \
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
if (((f) = fxdr_unsigned(int, *tl)) != 0) { \ if (((f) = fxdr_unsigned(int, *tl)) != 0) { \
if ((t1 = nfsm_loadattrcache(&ttvp, &md, &dpos, \ if ((t1 = nfsm_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) != 0) { \ (struct vattr *)0, (flags))) != 0) { \
error = t1; \ error = t1; \
(f) = 0; \ (f) = 0; \
m_freem(mrep); \ m_freem(mrep); \
@ -213,7 +214,7 @@
#define NFSV3_WCCRATTR 0 #define NFSV3_WCCRATTR 0
#define NFSV3_WCCCHK 1 #define NFSV3_WCCCHK 1
#define nfsm_wcc_data(v, f) \ #define nfsm_wcc_data(v, f, flags) \
{ int ttattrf, ttretf = 0; \ { int ttattrf, ttretf = 0; \
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
if (*tl == nfs_true) { \ if (*tl == nfs_true) { \
@ -222,7 +223,7 @@
ttretf = (VTONFS(v)->n_mtime == \ ttretf = (VTONFS(v)->n_mtime == \
fxdr_unsigned(u_int32_t, *(tl + 2))); \ fxdr_unsigned(u_int32_t, *(tl + 2))); \
} \ } \
nfsm_postop_attr((v), ttattrf); \ nfsm_postop_attr((v), ttattrf, (flags)); \
if (f) { \ if (f) { \
(f) = ttretf; \ (f) = ttretf; \
} else { \ } else { \

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsnode.h,v 1.34 2001/09/15 20:36:40 chs Exp $ */ /* $NetBSD: nfsnode.h,v 1.35 2002/10/21 12:52:36 yamt Exp $ */
/* /*
* Copyright (c) 1989, 1993 * Copyright (c) 1989, 1993
@ -173,6 +173,7 @@ struct nfsnode {
#define NACC 0x0100 /* Special file accessed */ #define NACC 0x0100 /* Special file accessed */
#define NUPD 0x0200 /* Special file updated */ #define NUPD 0x0200 /* Special file updated */
#define NCHG 0x0400 /* Special file times changed */ #define NCHG 0x0400 /* Special file times changed */
#define NTRUNCDELAYED 0x1000 /* Should be truncated later */
/* /*
* Convert between nfsnode pointers and vnode pointers * Convert between nfsnode pointers and vnode pointers
@ -226,7 +227,7 @@ int nfs_readlink __P((void *));
int nfs_inactive __P((void *)); int nfs_inactive __P((void *));
int nfs_reclaim __P((void *)); int nfs_reclaim __P((void *));
#define nfs_lock genfs_lock #define nfs_lock genfs_lock
#define nfs_unlock genfs_unlock int nfs_unlock __P((void *));
#define nfs_islocked genfs_islocked #define nfs_islocked genfs_islocked
int nfs_bmap __P((void *)); int nfs_bmap __P((void *));
int nfs_strategy __P((void *)); int nfs_strategy __P((void *));