summaryrefslogtreecommitdiffstats
path: root/sys/nfsclient
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2005-07-21 22:46:56 +0000
committerps <ps@FreeBSD.org>2005-07-21 22:46:56 +0000
commit3c7af06c7a1c20bf7ef7746f33bfd8f7309e43c0 (patch)
treea908ad2d58843a0c95ec870ea4b7b18c818defb7 /sys/nfsclient
parentc0016138302575371346a4f1f21c21640b64ef0e (diff)
downloadFreeBSD-src-3c7af06c7a1c20bf7ef7746f33bfd8f7309e43c0.zip
FreeBSD-src-3c7af06c7a1c20bf7ef7746f33bfd8f7309e43c0.tar.gz
Remove the NFS client rslock. The rslock was used to serialize
writers that want to extend the file. It was also used to serialize readers that might want to read the last block of the file (with a writer extending the file). Now that we support vnode locking for NFS, the rslock is unnecessary. Writers grab the exclusive vnode lock before writing and readers grab the shared (or in some cases the exclusive) lock. Submitted by: Mohan Srinivasan
Diffstat (limited to 'sys/nfsclient')
-rw-r--r--sys/nfsclient/nfs_bio.c78
-rw-r--r--sys/nfsclient/nfs_node.c12
-rw-r--r--sys/nfsclient/nfsnode.h26
3 files changed, 2 insertions, 114 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c
index 35bf6c2..3018dda 100644
--- a/sys/nfsclient/nfs_bio.c
+++ b/sys/nfsclient/nfs_bio.c
@@ -474,45 +474,15 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
np->ra_expect_lbn = lbn + 1;
}
- /*
- * Obtain the buffer cache block. Figure out the buffer size
- * when we are at EOF. If we are modifying the size of the
- * buffer based on an EOF condition we need to hold
- * nfs_rslock() through obtaining the buffer to prevent
- * a potential writer-appender from messing with n_size.
- * Otherwise we may accidently truncate the buffer and
- * lose dirty data.
- *
- * Note that bcount is *not* DEV_BSIZE aligned.
- */
-
-again:
+ /* Note that bcount is *not* DEV_BSIZE aligned. */
bcount = biosize;
if ((off_t)lbn * biosize >= np->n_size) {
bcount = 0;
} else if ((off_t)(lbn + 1) * biosize > np->n_size) {
bcount = np->n_size - (off_t)lbn * biosize;
}
- if (bcount != biosize) {
- switch(nfs_rslock(np, td)) {
- case ENOLCK:
- goto again;
- /* not reached */
- case EIO:
- return (EIO);
- case EINTR:
- case ERESTART:
- return(EINTR);
- /* not reached */
- default:
- break;
- }
- }
-
bp = nfs_getcacheblk(vp, lbn, bcount, td);
- if (bcount != biosize)
- nfs_rsunlock(np, td);
if (!bp) {
error = nfs_sigintr(nmp, NULL, td);
return (error ? error : EINTR);
@@ -846,7 +816,6 @@ nfs_write(struct vop_write_args *ap)
daddr_t lbn;
int bcount;
int n, on, error = 0;
- int haverslock = 0;
struct proc *p = td?td->td_proc:NULL;
GIANT_REQUIRED;
@@ -894,7 +863,6 @@ flush_and_restart:
* If IO_APPEND then load uio_offset. We restart here if we cannot
* get the append lock.
*/
-restart:
if (ioflag & IO_APPEND) {
np->n_attrstamp = 0;
error = VOP_GETATTR(vp, &vattr, cred, td);
@@ -914,38 +882,6 @@ restart:
return nfs_directio_write(vp, uio, cred, ioflag);
/*
- * We need to obtain the rslock if we intend to modify np->n_size
- * in order to guarentee the append point with multiple contending
- * writers, to guarentee that no other appenders modify n_size
- * while we are trying to obtain a truncated buffer (i.e. to avoid
- * accidently truncating data written by another appender due to
- * the race), and to ensure that the buffer is populated prior to
- * our extending of the file. We hold rslock through the entire
- * operation.
- *
- * Note that we do not synchronize the case where someone truncates
- * the file while we are appending to it because attempting to lock
- * this case may deadlock other parts of the system unexpectedly.
- */
- if ((ioflag & IO_APPEND) ||
- uio->uio_offset + uio->uio_resid > np->n_size) {
- switch(nfs_rslock(np, td)) {
- case ENOLCK:
- goto restart;
- /* not reached */
- case EIO:
- return (EIO);
- case EINTR:
- case ERESTART:
- return(EINTR);
- /* not reached */
- default:
- break;
- }
- haverslock = 1;
- }
-
- /*
* Maybe this should be above the vnode op call, but so long as
* file servers have no limits, i don't think it matters
*/
@@ -955,8 +891,6 @@ restart:
lim_cur(p, RLIMIT_FSIZE)) {
psignal(p, SIGXFSZ);
PROC_UNLOCK(p);
- if (haverslock)
- nfs_rsunlock(np, td);
return (EFBIG);
}
PROC_UNLOCK(p);
@@ -1012,13 +946,8 @@ restart:
if (wouldcommit > nmp->nm_wcommitsize)
needrestart = 1;
}
- if (needrestart) {
- if (haverslock) {
- nfs_rsunlock(np, td);
- haverslock = 0;
- }
+ if (needrestart)
goto flush_and_restart;
- }
}
do {
@@ -1215,9 +1144,6 @@ again:
}
} while (uio->uio_resid > 0 && n > 0);
- if (haverslock)
- nfs_rsunlock(np, td);
-
return (error);
}
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c
index 9342142..f8621ae 100644
--- a/sys/nfsclient/nfs_node.c
+++ b/sys/nfsclient/nfs_node.c
@@ -107,20 +107,10 @@ nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp)
struct vnode *nvp;
int error;
u_int hash;
- int rsflags;
struct nfsmount *nmp;
struct nfs_vncmp ncmp;
- /*
- * Calculate nfs mount point and figure out whether the rslock should
- * be interruptible or not.
- */
nmp = VFSTONFS(mntp);
- if (nmp->nm_flag & NFSMNT_INT)
- rsflags = PCATCH;
- else
- rsflags = 0;
-
*npp = NULL;
hash = fnv_32_buf(fhp->fh_bytes, fhsize, FNV1_32_INIT);
@@ -173,7 +163,6 @@ nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp)
np->n_fhp = &np->n_fh;
bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize);
np->n_fhsize = fhsize;
- lockinit(&np->n_rslock, PVFS | rsflags, "nfrslk", 0, 0);
*npp = np;
return (0);
@@ -240,7 +229,6 @@ nfs_reclaim(struct vop_reclaim_args *ap)
FREE((caddr_t)np->n_fhp, M_NFSBIGFH);
}
- lockdestroy(&np->n_rslock);
uma_zfree(nfsnode_zone, vp->v_data);
vp->v_data = NULL;
vnode_destroy_vobject(vp);
diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h
index b9a2caf..0c5817f 100644
--- a/sys/nfsclient/nfsnode.h
+++ b/sys/nfsclient/nfsnode.h
@@ -120,7 +120,6 @@ struct nfsnode {
short n_fhsize; /* size in bytes, of fh */
short n_flag; /* Flag for locking.. */
nfsfh_t n_fh; /* Small File Handle */
- struct lock n_rslock;
struct nfs4_fctx n_rfc;
struct nfs4_fctx n_wfc;
u_char *n_name; /* leaf name, for v4 OPEN op */
@@ -168,31 +167,6 @@ extern struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON];
#if defined(_KERNEL)
-/*
- * nfs_rslock - Attempt to obtain lock on nfsnode
- *
- * Attempt to obtain a lock on the passed nfsnode, returning ENOLCK
- * if the lock could not be obtained due to our having to sleep. This
- * function is generally used to lock around code that modifies an
- * NFS file's size. In order to avoid deadlocks the lock
- * should not be obtained while other locks are being held.
- */
-
-static __inline int
-nfs_rslock(struct nfsnode *np, struct thread *td)
-{
-
- return(lockmgr(&np->n_rslock,
- LK_EXCLUSIVE | LK_CANRECURSE | LK_SLEEPFAIL, NULL, td));
-}
-
-static __inline void
-nfs_rsunlock(struct nfsnode *np, struct thread *td)
-{
-
- (void)lockmgr(&np->n_rslock, LK_RELEASE, NULL, td);
-}
-
extern struct vop_vector nfs_fifoops;
extern struct vop_vector nfs_vnodeops;
extern struct vop_vector nfs4_vnodeops;
OpenPOWER on IntegriCloud