Page MenuHomeFreeBSD

D22377.diff
No OneTemporary

D22377.diff

Index: head/sys/fs/nfs/nfs.h
===================================================================
--- head/sys/fs/nfs/nfs.h
+++ head/sys/fs/nfs/nfs.h
@@ -797,6 +797,9 @@
struct mbuf *nfssl_reply;
};
+/* Enumerated type for nfsuserd state. */
+typedef enum { NOTRUNNING=0, STARTSTOP=1, RUNNING=2 } nfsuserd_state;
+
#endif /* _KERNEL */
#endif /* _NFS_NFS_H */
Index: head/sys/fs/nfs/nfs_commonport.c
===================================================================
--- head/sys/fs/nfs/nfs_commonport.c
+++ head/sys/fs/nfs/nfs_commonport.c
@@ -56,7 +56,7 @@
#include <vm/uma.h>
extern int nfscl_ticks;
-extern int nfsrv_nfsuserd;
+extern nfsuserd_state nfsrv_nfsuserd;
extern struct nfssockreq nfsrv_nfsuserdsock;
extern void (*nfsd_call_recall)(struct vnode *, int, struct ucred *,
struct thread *);
@@ -774,7 +774,7 @@
break;
case MOD_UNLOAD:
- if (newnfs_numnfsd != 0 || nfsrv_nfsuserd != 0 ||
+ if (newnfs_numnfsd != 0 || nfsrv_nfsuserd != NOTRUNNING ||
nfs_numnfscbd != 0) {
error = EBUSY;
break;
Index: head/sys/fs/nfs/nfs_commonsubs.c
===================================================================
--- head/sys/fs/nfs/nfs_commonsubs.c
+++ head/sys/fs/nfs/nfs_commonsubs.c
@@ -64,7 +64,8 @@
int nfscl_ticks;
int nfsrv_useacl = 1;
struct nfssockreq nfsrv_nfsuserdsock;
-int nfsrv_nfsuserd = 0;
+nfsuserd_state nfsrv_nfsuserd = NOTRUNNING;
+static int nfsrv_userdupcalls = 0;
struct nfsreqhead nfsd_reqq;
uid_t nfsrv_defaultuid = UID_NOBODY;
gid_t nfsrv_defaultgid = GID_NOGROUP;
@@ -3522,18 +3523,22 @@
int error;
NFSLOCKNAMEID();
- if (nfsrv_nfsuserd) {
+ if (nfsrv_nfsuserd != NOTRUNNING) {
NFSUNLOCKNAMEID();
error = EPERM;
goto out;
}
- nfsrv_nfsuserd = 1;
- NFSUNLOCKNAMEID();
+ nfsrv_nfsuserd = STARTSTOP;
/*
* Set up the socket record and connect.
+ * Set nr_client NULL before unlocking, just to ensure that no other
+ * process/thread/core will use a bogus old value. This could only
+ * occur if the use of the nameid lock to protect nfsrv_nfsuserd is
+ * broken.
*/
rp = &nfsrv_nfsuserdsock;
rp->nr_client = NULL;
+ NFSUNLOCKNAMEID();
rp->nr_sotype = SOCK_DGRAM;
rp->nr_soproto = IPPROTO_UDP;
rp->nr_lock = (NFSR_RESERVEDPORT | NFSR_LOCALHOST);
@@ -3569,9 +3574,15 @@
rp->nr_vers = RPCNFSUSERD_VERS;
if (error == 0)
error = newnfs_connect(NULL, rp, NFSPROCCRED(p), p, 0);
- if (error) {
+ if (error == 0) {
+ NFSLOCKNAMEID();
+ nfsrv_nfsuserd = RUNNING;
+ NFSUNLOCKNAMEID();
+ } else {
free(rp->nr_nam, M_SONAME);
- nfsrv_nfsuserd = 0;
+ NFSLOCKNAMEID();
+ nfsrv_nfsuserd = NOTRUNNING;
+ NFSUNLOCKNAMEID();
}
out:
NFSEXITCODE(error);
@@ -3586,14 +3597,21 @@
{
NFSLOCKNAMEID();
- if (nfsrv_nfsuserd == 0) {
+ if (nfsrv_nfsuserd != RUNNING) {
NFSUNLOCKNAMEID();
return;
}
- nfsrv_nfsuserd = 0;
+ nfsrv_nfsuserd = STARTSTOP;
+ /* Wait for all upcalls to complete. */
+ while (nfsrv_userdupcalls > 0)
+ msleep(&nfsrv_userdupcalls, NFSNAMEIDMUTEXPTR, PVFS,
+ "nfsupcalls", 0);
NFSUNLOCKNAMEID();
newnfs_disconnect(&nfsrv_nfsuserdsock);
free(nfsrv_nfsuserdsock.nr_nam, M_SONAME);
+ NFSLOCKNAMEID();
+ nfsrv_nfsuserd = NOTRUNNING;
+ NFSUNLOCKNAMEID();
}
/*
@@ -3612,12 +3630,19 @@
int error;
NFSLOCKNAMEID();
- if (nfsrv_nfsuserd == 0) {
+ if (nfsrv_nfsuserd != RUNNING) {
NFSUNLOCKNAMEID();
error = EPERM;
goto out;
}
+ /*
+ * Maintain a count of upcalls in progress, so that nfsrv_X()
+ * can wait until no upcalls are in progress.
+ */
+ nfsrv_userdupcalls++;
NFSUNLOCKNAMEID();
+ KASSERT(nfsrv_userdupcalls > 0,
+ ("nfsrv_getuser: non-positive upcalls"));
nd = &nfsd;
cred = newnfs_getcred();
nd->nd_flag = ND_GSSINITREPLY;
@@ -3636,6 +3661,10 @@
}
error = newnfs_request(nd, NULL, NULL, &nfsrv_nfsuserdsock, NULL, NULL,
cred, RPCPROG_NFSUSERD, RPCNFSUSERD_VERS, NULL, 0, NULL, NULL);
+ NFSLOCKNAMEID();
+ if (--nfsrv_userdupcalls == 0 && nfsrv_nfsuserd == STARTSTOP)
+ wakeup(&nfsrv_userdupcalls);
+ NFSUNLOCKNAMEID();
NFSFREECRED(cred);
if (!error) {
mbuf_freem(nd->nd_mrep);
Index: head/sys/fs/nfs/nfsport.h
===================================================================
--- head/sys/fs/nfs/nfsport.h
+++ head/sys/fs/nfs/nfsport.h
@@ -669,6 +669,7 @@
#define NFSLOCKSOCK() mtx_lock(&nfs_slock_mutex)
#define NFSUNLOCKSOCK() mtx_unlock(&nfs_slock_mutex)
#define NFSNAMEIDMUTEX extern struct mtx nfs_nameid_mutex
+#define NFSNAMEIDMUTEXPTR (&nfs_nameid_mutex)
#define NFSLOCKNAMEID() mtx_lock(&nfs_nameid_mutex)
#define NFSUNLOCKNAMEID() mtx_unlock(&nfs_nameid_mutex)
#define NFSNAMEIDREQUIRED() mtx_assert(&nfs_nameid_mutex, MA_OWNED)

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 21, 9:07 PM (21 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37055535
Default Alt Text
D22377.diff (4 KB)

Event Timeline