The previous revision broke the case of reconnecting to a TCP NFS server

via a new socket during an NFS operation as that reconnect takes place in
the context of an arbitrary thread with an arbitrary credential.  Ideally
we would like to use the mount point's credential for the entire process
of setting up the socket to connect to the NFS server.  Since some of the
APIs (sobind(), etc.) only take a thread pointer and infer the credential
from that instead of a direct credential, work around the problem by
temporarily changing the current thread's credential to that of the mount
point while connecting the socket and then reverting back to the original
credential when we are done.

Reviewed by:	rwatson
Tested on:	UDP, TCP, TCP with forced reconnect
This commit is contained in:
John Baldwin 2008-01-11 23:57:39 +00:00
parent d207e3a35c
commit b3c56ffc39
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=175237

View File

@ -264,7 +264,22 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep)
int error, rcvreserve, sndreserve;
int pktscale;
struct sockaddr *saddr;
struct thread *td = curthread; /* only used for socreate and sobind */
struct ucred *origcred;
struct thread *td = curthread;
/*
* We need to establish the socket using the credentials of
* the mountpoint. Some parts of this process (such as
* sobind() and soconnect()) will use the curent thread's
* credential instead of the socket credential. To work
* around this, temporarily change the current thread's
* credential to that of the mountpoint.
*
* XXX: It would be better to explicitly pass the correct
* credential to sobind() and soconnect().
*/
origcred = td->td_ucred;
td->td_ucred = nmp->nm_mountp->mnt_cred;
if (nmp->nm_sotype == SOCK_STREAM) {
mtx_lock(&nmp->nm_mtx);
@ -453,6 +468,9 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep)
so->so_snd.sb_flags |= SB_NOINTR;
SOCKBUF_UNLOCK(&so->so_snd);
/* Restore current thread's credentials. */
td->td_ucred = origcred;
mtx_lock(&nmp->nm_mtx);
/* Initialize other non-zero congestion variables */
nfs_init_rtt(nmp);
@ -463,6 +481,9 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep)
return (0);
bad:
/* Restore current thread's credentials. */
td->td_ucred = origcred;
nfs_disconnect(nmp);
return (error);
}