Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-4]: src/sys/nfs pull up rev 1.51 from trunk (requested by fvdl):
details: https://anonhg.NetBSD.org/src/rev/7b3ef6323415
branches: netbsd-1-4
changeset: 469661:7b3ef6323415
user: cgd <cgd%NetBSD.org@localhost>
date: Fri Nov 05 07:13:16 1999 +0000
description:
pull up rev 1.51 from trunk (requested by fvdl):
Avoid a panic when forcibly unmounting a hung NFS mount, e.g. at
reboot.
diffstat:
sys/nfs/nfs_socket.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 43 insertions(+), 3 deletions(-)
diffs (112 lines):
diff -r 7d3fe523f901 -r 7b3ef6323415 sys/nfs/nfs_socket.c
--- a/sys/nfs/nfs_socket.c Fri Nov 05 07:07:26 1999 +0000
+++ b/sys/nfs/nfs_socket.c Fri Nov 05 07:13:16 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_socket.c,v 1.50 1999/03/06 05:34:41 fair Exp $ */
+/* $NetBSD: nfs_socket.c,v 1.50.2.1 1999/11/05 07:13:16 cgd Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1995
@@ -329,8 +329,25 @@
so = nmp->nm_so;
nmp->nm_so = (struct socket *)0;
soshutdown(so, 2);
+ if (nmp->nm_iflag & NFSMNT_DISMNT) {
+ /*
+ * soshutdown() above should wake up the current
+ * listener.
+ * Now wake up those waiting for the recive lock, and
+ * wait for them to go away unhappy, to prevent *nmp
+ * from evaporating while they're sleeping.
+ */
+ while (nmp->nm_waiters > 0) {
+ wakeup (&nmp->nm_iflag);
+ sleep(&nmp->nm_waiters, PVFS);
+ }
+ }
soclose(so);
}
+#ifdef DIAGNOSTIC
+ if (nmp->nm_waiters > 0)
+ panic("nfs_disconnect: waiters left after drain?\n");
+#endif
}
void
@@ -341,7 +358,7 @@
memset(&dummyreq, 0, sizeof(dummyreq));
dummyreq.r_nmp = nmp;
- nfs_rcvlock(&dummyreq);
+ nfs_rcvlock(&dummyreq); /* XXX ignored error return */
nfs_disconnect(nmp);
nfs_rcvunlock(&nmp->nm_iflag);
}
@@ -628,6 +645,8 @@
return (EINTR);
} while (error == EWOULDBLOCK);
len -= auio.uio_resid;
+ if (!error && *mp == NULL)
+ error = EPIPE;
}
if (error) {
m_freem(*mp);
@@ -672,10 +691,20 @@
/*
* Get the next Rpc reply off the socket
*/
+ nmp->nm_waiters++;
error = nfs_receive(myrep, &nam, &mrep);
nfs_rcvunlock(&nmp->nm_iflag);
if (error) {
+ if (nmp->nm_iflag & NFSMNT_DISMNT) {
+ /*
+ * Oops, we're going away now..
+ */
+ nmp->nm_waiters--;
+ wakeup (&nmp->nm_waiters);
+ return error;
+ }
+ nmp->nm_waiters--;
/*
* Ignore routing errors on connectionless protocols??
*/
@@ -690,6 +719,7 @@
}
return (error);
}
+ nmp->nm_waiters--;
if (nam)
m_freem(nam);
@@ -1466,9 +1496,13 @@
nfs_rcvlock(rep)
register struct nfsreq *rep;
{
- register int *flagp = &rep->r_nmp->nm_iflag;
+ struct nfsmount *nmp = rep->r_nmp;
+ register int *flagp = &nmp->nm_iflag;
int slpflag, slptimeo = 0;
+ if (*flagp & NFSMNT_DISMNT)
+ return EIO;
+
if (*flagp & NFSMNT_INT)
slpflag = PCATCH;
else
@@ -1477,8 +1511,14 @@
if (nfs_sigintr(rep->r_nmp, rep, rep->r_procp))
return (EINTR);
*flagp |= NFSMNT_WANTRCV;
+ nmp->nm_waiters++;
(void) tsleep((caddr_t)flagp, slpflag | (PZERO - 1), "nfsrcvlk",
slptimeo);
+ nmp->nm_waiters--;
+ if (*flagp & NFSMNT_DISMNT) {
+ wakeup(&nmp->nm_waiters);
+ return EIO;
+ }
/* If our reply was received while we were sleeping,
* then just return without taking the lock to avoid a
* situation where a single iod could 'capture' the
Home |
Main Index |
Thread Index |
Old Index