Index: nfs_syscalls.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_syscalls.c,v retrieving revision 1.158 diff -p -u -r1.158 nfs_syscalls.c --- nfs_syscalls.c 12 Feb 2017 18:24:31 -0000 1.158 +++ nfs_syscalls.c 24 Jan 2018 10:41:18 -0000 @@ -488,6 +488,7 @@ nfssvc_nfsd(struct nfssvc_copy_ops *ops, int error = 0, cacherep, siz, sotype, writes_todo; struct proc *p = l->l_proc; bool doreinit; + size_t nfsd_idx; #ifndef nolint cacherep = RC_DOIT; @@ -505,8 +506,33 @@ nfssvc_nfsd(struct nfssvc_copy_ops *ops, } TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain); nfs_numnfsd++; + nfsd_idx = nfs_numnfsd; mutex_exit(&nfsd_lock); + } else { + /* + * idx == 0 => NULL above + * idx == 1 -> first entry + */ + size_t count = 0; + struct nfsd *entry; + + nfsd_idx = (uintptr)nfsd; + + mutex_enter(&nfsd_lock); + if (idx > nfs_numnfsd) { + mutex_exit(&nfsd_lock); + return EINVAL; + } + TAILQ_FOREACH(&nfsd_head, entry, nfsd_chain) { + if (++count == idx) + break; + } + KASSERT(count <= nfs_numnfsd); + mutex_exit(&nfsd_lock); + + nsd->nsd_nfsd = nfsd = entry; } + /* * Loop getting rpc requests until SIGKILL. */ @@ -620,6 +646,10 @@ nfssvc_nfsd(struct nfssvc_copy_ops *ops, struct sockaddr_in *)->sin_addr.s_addr; nsd->nsd_authlen = nfsd->nfsd_authlen; nsd->nsd_verflen = nfsd->nfsd_verflen; + /* + * Put the nfsd index in place for the copyout. + */ + nsd->nsd_nfsd = (uintptr_t)nfsd_idx; if (!copyout(nfsd->nfsd_authstr, nsd->nsd_authstr, nfsd->nfsd_authlen) && !copyout(nfsd->nfsd_verfstr, @@ -627,6 +657,7 @@ nfssvc_nfsd(struct nfssvc_copy_ops *ops, !ops->nsd_out(argp, nsd)) { return (ENEEDAUTH); } + nsd->nsd_nfsd = nfsd; cacherep = RC_DROPIT; } else cacherep = nfsrv_getcache(nd, slp, &mreq);