Only take the receive lock before disconnecting when doing it from

nfs_decode_args. Otherwise we might just end up locking against ourselves.

XXX workaround, will do ok for now. Proper fix forthcoming.
This commit is contained in:
fvdl 1998-01-30 22:44:13 +00:00
parent 6786eca4a0
commit 0c8ab9044c
3 changed files with 28 additions and 15 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_socket.c,v 1.40 1997/11/16 23:23:20 fvdl Exp $ */
/* $NetBSD: nfs_socket.c,v 1.41 1998/01/30 22:44:13 fvdl Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1995
@ -321,21 +321,26 @@ nfs_disconnect(nmp)
register struct socket *so;
if (nmp->nm_so) {
struct nfsreq dummyreq;
bzero(&dummyreq, sizeof(dummyreq));
dummyreq.r_nmp = nmp;
nfs_rcvlock(&dummyreq);
so = nmp->nm_so;
nmp->nm_so = (struct socket *)0;
soshutdown(so, 2);
soclose(so);
nfs_rcvunlock(&nmp->nm_iflag);
}
}
void
nfs_safedisconnect(nmp)
struct nfsmount *nmp;
{
struct nfsreq dummyreq;
bzero(&dummyreq, sizeof(dummyreq));
dummyreq.r_nmp = nmp;
nfs_rcvlock(&dummyreq);
nfs_disconnect(nmp);
nfs_rcvunlock(&nmp->nm_iflag);
}
/*
* This is the nfs send routine. For connection based socket types, it
* must be called with an nfs_sndlock() on the socket.
@ -510,7 +515,14 @@ tryagain:
}
} while (error == EWOULDBLOCK);
if (!error && auio.uio_resid > 0) {
log(LOG_INFO,
/*
* Don't log a 0 byte receive; it means
* that the socket has been closed, and
* can happen during normal operation
* (forcible unmount or Solaris server).
*/
if (auio.uio_resid != sizeof (u_int32_t))
log(LOG_INFO,
"short receive (%d/%d) from nfs server %s\n",
sizeof(u_int32_t) - auio.uio_resid,
sizeof(u_int32_t),
@ -540,7 +552,8 @@ tryagain:
} while (error == EWOULDBLOCK || error == EINTR ||
error == ERESTART);
if (!error && auio.uio_resid > 0) {
log(LOG_INFO,
if (len != auio.uio_resid)
log(LOG_INFO,
"short receive (%d/%d) from nfs server %s\n",
len - auio.uio_resid, len,
rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_var.h,v 1.11 1997/10/19 01:46:36 fvdl Exp $ */
/* $NetBSD: nfs_var.h,v 1.12 1998/01/30 22:44:14 fvdl Exp $ */
/*
* Copyright (c) 1996 Christos Zoulas. All rights reserved.
@ -189,6 +189,7 @@ int nfsrv_access __P((struct vnode *, int, struct ucred *, int, struct proc *,
int nfs_connect __P((struct nfsmount *, struct nfsreq *));
int nfs_reconnect __P((struct nfsreq *));
void nfs_disconnect __P((struct nfsmount *));
void nfs_safedisconnect __P((struct nfsmount *));
int nfs_send __P((struct socket *, struct mbuf *, struct mbuf *,
struct nfsreq *));
int nfs_receive __P((struct nfsreq *, struct mbuf **, struct mbuf **));
@ -204,7 +205,6 @@ int nfs_sndlock __P((int *, struct nfsreq *));
void nfs_sndunlock __P((int *));
int nfs_rcvlock __P((struct nfsreq *));
void nfs_rcvunlock __P((int *));
void nfs_realign __P((struct mbuf *, int));
int nfs_getreq __P((struct nfsrv_descript *, struct nfsd *, int));
int nfs_msg __P((struct proc *, char *, char *));
void nfsrv_rcv __P((struct socket *, caddr_t, int));

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_vfsops.c,v 1.66 1997/10/19 01:46:40 fvdl Exp $ */
/* $NetBSD: nfs_vfsops.c,v 1.67 1998/01/30 22:44:15 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993, 1995
@ -573,7 +573,7 @@ nfs_decode_args(nmp, argp)
nmp->nm_soproto = argp->proto;
if (nmp->nm_so && adjsock) {
nfs_disconnect(nmp);
nfs_safedisconnect(nmp);
if (nmp->nm_sotype == SOCK_DGRAM)
while (nfs_connect(nmp, (struct nfsreq *)0)) {
printf("nfs_args: retrying connect\n");