Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

some locking changes

  • Loading branch information...
commit 6ec6138e717465d1a3275b68a160016858f795f4 1 parent 043d3fe
yamt authored
View
25 sys/nfs/nfs_bio.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_bio.c,v 1.175.2.3 2010/09/26 03:58:54 yamt Exp $ */
+/* $NetBSD: nfs_bio.c,v 1.175.2.4 2010/10/10 08:29:39 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.175.2.3 2010/09/26 03:58:54 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.175.2.4 2010/10/10 08:29:39 yamt Exp $");
#ifdef _KERNEL_OPT
#include "opt_nfs.h"
@@ -93,6 +93,7 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag,
int advice;
struct lwp *l = curlwp;
+ KASSERT(VOP_ISLOCKED(vp));
#ifdef DIAGNOSTIC
if (uio->uio_rw != UIO_READ)
panic("nfs_read mode");
@@ -215,12 +216,15 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag,
uio->uio_offset, 0, 0);
}
- if (NFS_EOFVALID(np) &&
+ mutex_enter(&np->n_attrlock);
+ if (np->n_direofvalid &&
ndp->dc_cookie == np->n_direofoffset) {
+ mutex_exit(&np->n_attrlock);
nfs_putdircache(np, ndp);
nfsstats.direofcache_hits++;
return (0);
}
+ mutex_exit(&np->n_attrlock);
bp = nfs_getcacheblk(vp, NFSDC_BLKNO(ndp), NFS_DIRBLKSIZ, l);
if (!bp)
@@ -257,15 +261,18 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag,
* also, empty block implies EOF.
*/
+ mutex_enter(&np->n_attrlock);
if (bp->b_bcount == bp->b_resid ||
- (NFS_EOFVALID(np) &&
+ (np->n_direofvalid &&
ndp->dc_blkcookie == np->n_direofoffset)) {
+ mutex_exit(&np->n_attrlock);
KASSERT(bp->b_bcount != bp->b_resid ||
ndp->dc_blkcookie == bp->b_dcookie);
nfs_putdircache(np, ndp);
brelse(bp, BC_NOCACHE);
return 0;
}
+ mutex_exit(&np->n_attrlock);
/*
* Find the entry we were looking for in the block.
@@ -386,8 +393,10 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag,
* (You need the current block first, so that you have the
* directory offset cookie of the next block.)
*/
+ mutex_enter(&np->n_attrlock);
if (nfs_numasync > 0 && nmp->nm_readahead > 0 &&
- !NFS_EOFVALID(np)) {
+ !np->n_direofvalid) {
+ mutex_exit(&np->n_attrlock);
rabp = nfs_getcacheblk(vp, NFSDC_BLKNO(nndp),
NFS_DIRBLKSIZ, l);
if (rabp) {
@@ -400,6 +409,8 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag,
} else
brelse(rabp, 0);
}
+ } else {
+ mutex_exit(&np->n_attrlock);
}
nfs_putdircache(np, nndp);
got_buf = 1;
@@ -705,6 +716,10 @@ nfs_flushstalebuf(struct vnode *vp, kauth_cred_t cred, struct lwp *l,
if (error)
return error;
if (timespeccmp(&np->n_mtime, &vattr.va_mtime, !=)) {
+ /*
+ * the file seems modified on the server.
+ * flush our cache.
+ */
if (vp->v_type == VDIR) {
nfs_invaldircache(vp, 0);
}
View
5 sys/nfs/nfs_clntsubs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_clntsubs.c,v 1.1.2.3 2010/09/26 03:58:55 yamt Exp $ */
+/* $NetBSD: nfs_clntsubs.c,v 1.1.2.4 2010/10/10 08:29:39 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_clntsubs.c,v 1.1.2.3 2010/09/26 03:58:55 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_clntsubs.c,v 1.1.2.4 2010/10/10 08:29:39 yamt Exp $");
#ifdef _KERNEL_OPT
#include "opt_nfs.h"
@@ -370,6 +370,7 @@ nfs_delayedtruncate(struct vnode *vp)
{
struct nfsnode *np = VTONFS(vp);
+ KASSERT(VOP_ISLOCKED(vp));
if (np->n_flag & NTRUNCDELAYED) {
np->n_flag &= ~NTRUNCDELAYED;
genfs_node_wrlock(vp);
View
6 sys/nfs/nfs_node.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_node.c,v 1.101.10.5 2010/10/09 03:32:39 yamt Exp $ */
+/* $NetBSD: nfs_node.c,v 1.101.10.6 2010/10/10 08:29:39 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.101.10.5 2010/10/09 03:32:39 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.101.10.6 2010/10/10 08:29:39 yamt Exp $");
#ifdef _KERNEL_OPT
#include "opt_nfs.h"
@@ -261,7 +261,7 @@ nfs_inactive(void *v)
nfs_vinvalbuf(vp, 0, sp->s_cred, curlwp, 1);
*ap->a_recycle = (np->n_flag & NREMOVED) != 0;
np->n_flag &=
- (NMODIFIED | NFLUSHINPROG | NFLUSHWANT | NEOFVALID | NTRUNCDELAYED);
+ (NMODIFIED | NFLUSHINPROG | NFLUSHWANT | NTRUNCDELAYED);
if (vp->v_type == VDIR && np->n_dircache)
nfs_invaldircache(vp,
View
8 sys/nfs/nfs_subs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_subs.c,v 1.201.4.6 2010/09/26 03:58:55 yamt Exp $ */
+/* $NetBSD: nfs_subs.c,v 1.201.4.7 2010/10/10 08:29:39 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.201.4.6 2010/09/26 03:58:55 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.201.4.7 2010/10/10 08:29:39 yamt Exp $");
#ifdef _KERNEL_OPT
#include "opt_nfs.h"
@@ -1152,7 +1152,7 @@ nfs_dirhash(off_t off)
return sum;
}
-#define _NFSDC_MTX(np) (&NFSTOV(np)->v_interlock)
+#define _NFSDC_MTX(np) (&(np)->n_attrlock)
#define NFSDC_LOCK(np) mutex_enter(_NFSDC_MTX(np))
#define NFSDC_UNLOCK(np) mutex_exit(_NFSDC_MTX(np))
#define NFSDC_ASSERT_LOCKED(np) KASSERT(mutex_owned(_NFSDC_MTX(np)))
@@ -1438,7 +1438,7 @@ nfs_invaldircache(struct vnode *vp, int flags)
#endif
if ((flags & NFS_INVALDIRCACHE_KEEPEOF) == 0)
- np->n_flag &= ~NEOFVALID;
+ np->n_direofvalid = 0;
if (!np->n_dircache)
return;
View
20 sys/nfs/nfs_vnops.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_vnops.c,v 1.266.10.8 2010/09/26 03:58:55 yamt Exp $ */
+/* $NetBSD: nfs_vnops.c,v 1.266.10.9 2010/10/10 08:29:39 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.266.10.8 2010/09/26 03:58:55 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.266.10.9 2010/10/10 08:29:39 yamt Exp $");
#ifdef _KERNEL_OPT
#include "opt_nfs.h"
@@ -2553,8 +2553,10 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, kauth_cred_t cred)
txdr_cookie3(uiop->uio_offset, tl);
}
tl += 2;
+ mutex_enter(&dnp->n_attrlock);
*tl++ = dnp->n_cookieverf.nfsuquad[0];
*tl++ = dnp->n_cookieverf.nfsuquad[1];
+ mutex_exit(&dnp->n_attrlock);
} else
#endif
{
@@ -2570,8 +2572,10 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, kauth_cred_t cred)
if (!error) {
nfsm_dissect(tl, u_int32_t *,
2 * NFSX_UNSIGNED);
+ mutex_enter(&dnp->n_attrlock);
dnp->n_cookieverf.nfsuquad[0] = *tl++;
dnp->n_cookieverf.nfsuquad[1] = *tl;
+ mutex_exit(&dnp->n_attrlock);
} else {
m_freem(mrep);
goto nfsmout;
@@ -2703,8 +2707,10 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, kauth_cred_t cred)
* block.
*/
if (bigenough) {
+ mutex_enter(&dnp->n_attrlock);
dnp->n_direofoffset = uiop->uio_offset;
- dnp->n_flag |= NEOFVALID;
+ dnp->n_direofvalid = 1;
+ mutex_exit(&dnp->n_attrlock);
}
nfsmout:
return (error);
@@ -2763,8 +2769,10 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, kauth_cred_t cred)
txdr_cookie3(uiop->uio_offset, tl);
}
tl += 2;
+ mutex_enter(&dnp->n_attrlock);
*tl++ = dnp->n_cookieverf.nfsuquad[0];
*tl++ = dnp->n_cookieverf.nfsuquad[1];
+ mutex_exit(&dnp->n_attrlock);
*tl++ = txdr_unsigned(nmp->nm_readdirsize);
*tl = txdr_unsigned(nmp->nm_rsize);
nfsm_request(dnp, NFSPROC_READDIRPLUS, curlwp, cred);
@@ -2775,8 +2783,10 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, kauth_cred_t cred)
}
nrpcs++;
nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
+ mutex_enter(&dnp->n_attrlock);
dnp->n_cookieverf.nfsuquad[0] = *tl++;
dnp->n_cookieverf.nfsuquad[1] = *tl++;
+ mutex_exit(&dnp->n_attrlock);
more_dirs = fxdr_unsigned(int, *tl);
/* loop thru the dir entries, doctoring them to 4bsd form */
@@ -2929,8 +2939,10 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, kauth_cred_t cred)
* block.
*/
if (bigenough) {
+ mutex_enter(&dnp->n_attrlock);
dnp->n_direofoffset = uiop->uio_offset;
- dnp->n_flag |= NEOFVALID;
+ dnp->n_direofvalid = 1;
+ mutex_exit(&dnp->n_attrlock);
}
nfsmout:
if (newvp != NULLVP) {
View
9 sys/nfs/nfsnode.h
@@ -1,4 +1,4 @@
-/* $NetBSD: nfsnode.h,v 1.67.10.4 2010/10/09 03:32:40 yamt Exp $ */
+/* $NetBSD: nfsnode.h,v 1.67.10.5 2010/10/10 08:29:40 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -116,12 +116,13 @@ struct nfsnode_reg {
};
struct nfsnode_dir {
- off_t ndir_direof; /* EOF offset cache */
+ off_t ndir_direof; /* a: EOF offset cache */
nfsuint64 ndir_cookieverf; /* Cookie verifier */
struct nfsdirhashhead *ndir_dircache; /* offset -> cache hash heads */
struct nfsdirchainhead ndir_dirchain; /* Chain of dir cookies */
struct timespec ndir_nctime; /* Last name cache entry */
unsigned ndir_dircachesize; /* Size of dir cookie cache */
+ unsigned int ndir_eofvalid; /* a: ndir_direof is valid */
};
struct nfsnode {
@@ -146,6 +147,7 @@ struct nfsnode {
#define n_error n_un1.nu_reg.nreg_error
#define n_direofoffset n_un1.nu_dir.ndir_direof
+#define n_direofvalid n_un1.nu_dir.ndir_eofvalid
#define n_cookieverf n_un1.nu_dir.ndir_cookieverf
#define n_dircache n_un1.nu_dir.ndir_dircache
#define n_dirchain n_un1.nu_dir.ndir_dirchain
@@ -198,9 +200,6 @@ struct nfsnode {
implies stale cache */
#define NREMOVED 0x2000 /* Has been removed */
#define NUSEOPENCRED 0x4000 /* Try open cred first rather than owner's */
-#define NEOFVALID 0x8000 /* dir: n_direofoffset is valid */
-
-#define NFS_EOFVALID(ndp) ((ndp)->n_flag & NEOFVALID)
/*
* n_specflags
Please sign in to comment.
Something went wrong with that request. Please try again.