Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/nfsclient/nfs_clrpcops.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 940 Lines • ▼ Show 20 Lines | nfsrpc_setclient(struct nfsmount *nmp, struct nfsclclient *clp, int reclaim, | ||||
u_short port; | u_short port; | ||||
int error, isinet6 = 0, callblen; | int error, isinet6 = 0, callblen; | ||||
nfsquad_t confirm; | nfsquad_t confirm; | ||||
u_int32_t lease; | u_int32_t lease; | ||||
static u_int32_t rev = 0; | static u_int32_t rev = 0; | ||||
struct nfsclds *dsp, *odsp; | struct nfsclds *dsp, *odsp; | ||||
struct in6_addr a6; | struct in6_addr a6; | ||||
struct nfsclsession *tsep; | struct nfsclsession *tsep; | ||||
struct rpc_reconupcall recon; | |||||
struct nfscl_reconarg *rcp; | |||||
if (nfsboottime.tv_sec == 0) | if (nfsboottime.tv_sec == 0) | ||||
NFSSETBOOTTIME(nfsboottime); | NFSSETBOOTTIME(nfsboottime); | ||||
if (NFSHASNFSV4N(nmp)) { | if (NFSHASNFSV4N(nmp)) { | ||||
error = NFSERR_BADSESSION; | error = NFSERR_BADSESSION; | ||||
odsp = dsp = NULL; | odsp = dsp = NULL; | ||||
if (retokp != NULL) { | if (retokp != NULL) { | ||||
NFSLOCKMNT(nmp); | NFSLOCKMNT(nmp); | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | if (error != 0) { | ||||
if (error == 0) | if (error == 0) | ||||
error = nfsrpc_createsession(nmp, | error = nfsrpc_createsession(nmp, | ||||
&dsp->nfsclds_sess, &nmp->nm_sockreq, NULL, | &dsp->nfsclds_sess, &nmp->nm_sockreq, NULL, | ||||
dsp->nfsclds_sess.nfsess_sequenceid, 1, | dsp->nfsclds_sess.nfsess_sequenceid, 1, | ||||
cred, p); | cred, p); | ||||
NFSCL_DEBUG(1, "aft createsess=%d\n", error); | NFSCL_DEBUG(1, "aft createsess=%d\n", error); | ||||
} | } | ||||
if (error == 0) { | if (error == 0) { | ||||
/* | |||||
* If the session supports a backchannel, set up | |||||
* the BindConnectionToSession call in the krpc | |||||
* so that it is done on a reconnection. | |||||
*/ | |||||
if (nfscl_enablecallb != 0 && nfs_numnfscbd > 0) { | |||||
rcp = mem_alloc(sizeof(*rcp)); | |||||
rcp->minorvers = nmp->nm_minorvers; | |||||
memcpy(rcp->sessionid, | |||||
dsp->nfsclds_sess.nfsess_sessionid, | |||||
NFSX_V4SESSIONID); | |||||
recon.call = nfsrpc_bindconnsess; | |||||
recon.arg = rcp; | |||||
CLNT_CONTROL(nmp->nm_client, CLSET_RECONUPCALL, | |||||
&recon); | |||||
} | |||||
NFSLOCKMNT(nmp); | NFSLOCKMNT(nmp); | ||||
/* | /* | ||||
* The old sessions cannot be safely free'd | * The old sessions cannot be safely free'd | ||||
* here, since they may still be used by | * here, since they may still be used by | ||||
* in-progress RPCs. | * in-progress RPCs. | ||||
*/ | */ | ||||
tsep = NULL; | tsep = NULL; | ||||
if (TAILQ_FIRST(&nmp->nm_sess) != NULL) | if (TAILQ_FIRST(&nmp->nm_sess) != NULL) | ||||
▲ Show 20 Lines • Show All 7,673 Lines • ▼ Show 20 Lines | nfsm_split(struct mbuf *mp, uint64_t xfer) | ||||
m2->m_epg_npgs = j; | m2->m_epg_npgs = j; | ||||
m->m_epg_npgs = pgno + 1; | m->m_epg_npgs = pgno + 1; | ||||
m->m_epg_last_len = left; | m->m_epg_last_len = left; | ||||
m->m_len = xfer; | m->m_len = xfer; | ||||
m2->m_next = m->m_next; | m2->m_next = m->m_next; | ||||
m->m_next = NULL; | m->m_next = NULL; | ||||
return (m2); | return (m2); | ||||
} | |||||
/* | |||||
* Do the NFSv4.1 Bind Connection to Session. | |||||
* Called from the reconnect layer of the krpc (sys/rpc/clnt_rc.c). | |||||
*/ | |||||
void | |||||
nfsrpc_bindconnsess(CLIENT *cl, void *arg, struct ucred *cr) | |||||
{ | |||||
struct nfscl_reconarg *rcp = (struct nfscl_reconarg *)arg; | |||||
uint32_t res, *tl; | |||||
struct nfsrv_descript nfsd; | |||||
struct nfsrv_descript *nd = &nfsd; | |||||
struct rpc_callextra ext; | |||||
struct timeval utimeout; | |||||
enum clnt_stat stat; | |||||
int error; | |||||
nfscl_reqstart(nd, NFSPROC_BINDCONNTOSESS, NULL, NULL, 0, NULL, NULL, | |||||
NFS_VER4, rcp->minorvers); | |||||
NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID + 2 * NFSX_UNSIGNED); | |||||
memcpy(tl, rcp->sessionid, NFSX_V4SESSIONID); | |||||
tl += NFSX_V4SESSIONID / NFSX_UNSIGNED; | |||||
*tl++ = txdr_unsigned(NFSCDFC4_FORE_OR_BOTH); | |||||
*tl = newnfs_false; | |||||
memset(&ext, 0, sizeof(ext)); | |||||
utimeout.tv_sec = 30; | |||||
utimeout.tv_usec = 0; | |||||
ext.rc_auth = authunix_create(cr); | |||||
nd->nd_mrep = NULL; | |||||
stat = CLNT_CALL_MBUF(cl, &ext, NFSV4PROC_COMPOUND, nd->nd_mreq, | |||||
&nd->nd_mrep, utimeout); | |||||
AUTH_DESTROY(ext.rc_auth); | |||||
if (stat != RPC_SUCCESS) { | |||||
printf("nfsrpc_bindconnsess: call failed stat=%d\n", stat); | |||||
return; | |||||
} | |||||
if (nd->nd_mrep == NULL) { | |||||
printf("nfsrpc_bindconnsess: no reply args\n"); | |||||
return; | |||||
} | |||||
error = 0; | |||||
newnfs_realign(&nd->nd_mrep, M_WAITOK); | |||||
nd->nd_md = nd->nd_mrep; | |||||
nd->nd_dpos = mtod(nd->nd_md, char *); | |||||
NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); | |||||
nd->nd_repstat = fxdr_unsigned(uint32_t, *tl++); | |||||
if (nd->nd_repstat == NFSERR_OK) { | |||||
res = fxdr_unsigned(uint32_t, *tl); | |||||
if (res > 0 && (error = nfsm_advance(nd, NFSM_RNDUP(res), | |||||
-1)) != 0) | |||||
goto nfsmout; | |||||
NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID + | |||||
4 * NFSX_UNSIGNED); | |||||
tl += 3; | |||||
if (!NFSBCMP(tl, rcp->sessionid, NFSX_V4SESSIONID)) { | |||||
tl += NFSX_V4SESSIONID / NFSX_UNSIGNED; | |||||
res = fxdr_unsigned(uint32_t, *tl); | |||||
if (res != NFSCDFS4_BOTH) | |||||
printf("nfsrpc_bindconnsess: did not " | |||||
"return FS4_BOTH\n"); | |||||
} else | |||||
printf("nfsrpc_bindconnsess: not same " | |||||
"sessionid\n"); | |||||
} else if (nd->nd_repstat != NFSERR_BADSESSION) | |||||
printf("nfsrpc_bindconnsess: returned %d\n", nd->nd_repstat); | |||||
nfsmout: | |||||
if (error != 0) | |||||
printf("nfsrpc_bindconnsess: reply bad xdr\n"); | |||||
m_freem(nd->nd_mrep); | |||||
} | } |