|
Lines 41-46
extern struct nfsstatsv1 nfsstatsv1;
Link Here
|
| 41 |
extern int nfsrv_lease; |
41 |
extern int nfsrv_lease; |
| 42 |
extern struct timeval nfsboottime; |
42 |
extern struct timeval nfsboottime; |
| 43 |
extern u_int32_t newnfs_true, newnfs_false; |
43 |
extern u_int32_t newnfs_true, newnfs_false; |
|
|
44 |
extern int nfsd_debuglevel; |
| 44 |
NFSV4ROOTLOCKMUTEX; |
45 |
NFSV4ROOTLOCKMUTEX; |
| 45 |
NFSSTATESPINLOCK; |
46 |
NFSSTATESPINLOCK; |
| 46 |
|
47 |
|
|
Lines 582-587
nfsrv_getclient(nfsquad_t clientid, int
Link Here
|
| 582 |
error = NFSERR_STALECLIENTID; |
583 |
error = NFSERR_STALECLIENTID; |
| 583 |
else if (nfsrv_notsamecredname(nd, clp)) |
584 |
else if (nfsrv_notsamecredname(nd, clp)) |
| 584 |
error = NFSERR_CLIDINUSE; |
585 |
error = NFSERR_CLIDINUSE; |
|
|
586 |
else if ((nd->nd_flag & ND_NFSV41) != 0 && nsep != NULL && |
| 587 |
clp->lc_sesscnt > NFSRV_MAXCLIENTSESS) { |
| 588 |
NFSD_DEBUG(2, "nfsrv_getclient: too many sessions\n"); |
| 589 |
error = NFSERR_RESOURCE; |
| 590 |
} |
| 585 |
|
591 |
|
| 586 |
if (!error) { |
592 |
if (!error) { |
| 587 |
if ((clp->lc_flags & (LCL_NEEDSCONFIRM | LCL_DONTCLEAN)) == |
593 |
if ((clp->lc_flags & (LCL_NEEDSCONFIRM | LCL_DONTCLEAN)) == |
|
Lines 614-623
nfsrv_getclient(nfsquad_t clientid, int
Link Here
|
| 614 |
if (nsep != NULL) { |
620 |
if (nsep != NULL) { |
| 615 |
/* Hold a reference on the xprt for a backchannel. */ |
621 |
/* Hold a reference on the xprt for a backchannel. */ |
| 616 |
if ((nsep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN) |
622 |
if ((nsep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN) |
| 617 |
!= 0 && clp->lc_req.nr_client == NULL) { |
623 |
!= 0) { |
| 618 |
clp->lc_req.nr_client = (struct __rpc_client *) |
624 |
if (clp->lc_req.nr_client == NULL) |
| 619 |
clnt_bck_create(nd->nd_xprt->xp_socket, |
625 |
clp->lc_req.nr_client = (struct __rpc_client *) |
| 620 |
cbprogram, NFSV4_CBVERS); |
626 |
clnt_bck_create(nd->nd_xprt->xp_socket, |
|
|
627 |
cbprogram, NFSV4_CBVERS); |
| 621 |
if (clp->lc_req.nr_client != NULL) { |
628 |
if (clp->lc_req.nr_client != NULL) { |
| 622 |
SVC_ACQUIRE(nd->nd_xprt); |
629 |
SVC_ACQUIRE(nd->nd_xprt); |
| 623 |
nd->nd_xprt->xp_p2 = |
630 |
nd->nd_xprt->xp_p2 = |
|
Lines 638-643
nfsrv_getclient(nfsquad_t clientid, int
Link Here
|
| 638 |
LIST_INSERT_HEAD(&shp->list, nsep, sess_hash); |
645 |
LIST_INSERT_HEAD(&shp->list, nsep, sess_hash); |
| 639 |
LIST_INSERT_HEAD(&clp->lc_session, nsep, sess_list); |
646 |
LIST_INSERT_HEAD(&clp->lc_session, nsep, sess_list); |
| 640 |
nsep->sess_clp = clp; |
647 |
nsep->sess_clp = clp; |
|
|
648 |
clp->lc_sesscnt++; |
| 641 |
NFSUNLOCKSESSION(shp); |
649 |
NFSUNLOCKSESSION(shp); |
| 642 |
NFSUNLOCKSTATE(); |
650 |
NFSUNLOCKSTATE(); |
| 643 |
} |
651 |
} |
|
Lines 4213-4221
nfsrv_docallback(struct nfsclient *clp,
Link Here
|
| 4213 |
*/ |
4221 |
*/ |
| 4214 |
(void) newnfs_sndlock(&clp->lc_req.nr_lock); |
4222 |
(void) newnfs_sndlock(&clp->lc_req.nr_lock); |
| 4215 |
if (clp->lc_req.nr_client == NULL) { |
4223 |
if (clp->lc_req.nr_client == NULL) { |
| 4216 |
if ((clp->lc_flags & LCL_NFSV41) != 0) |
4224 |
if ((clp->lc_flags & LCL_NFSV41) != 0) { |
| 4217 |
error = ECONNREFUSED; |
4225 |
error = ECONNREFUSED; |
| 4218 |
else if (nd->nd_procnum == NFSV4PROC_CBNULL) |
4226 |
nfsrv_freesession(sep, NULL); |
|
|
4227 |
} else if (nd->nd_procnum == NFSV4PROC_CBNULL) |
| 4219 |
error = newnfs_connect(NULL, &clp->lc_req, cred, |
4228 |
error = newnfs_connect(NULL, &clp->lc_req, cred, |
| 4220 |
NULL, 1); |
4229 |
NULL, 1); |
| 4221 |
else |
4230 |
else |
|
Lines 5831-5839
nfsrv_checksequence(struct nfsrv_descrip
Link Here
|
| 5831 |
/* |
5840 |
/* |
| 5832 |
* If this session handles the backchannel, save the nd_xprt for this |
5841 |
* If this session handles the backchannel, save the nd_xprt for this |
| 5833 |
* RPC, since this is the one being used. |
5842 |
* RPC, since this is the one being used. |
|
|
5843 |
* RFC-5661 specifies that the fore channel will be implicitly |
| 5844 |
* bound by a Sequence operation. However, since some NFSv4.1 clients |
| 5845 |
* erroneously assumed that the back channel would be implicitly |
| 5846 |
* bound as well, do the implicit binding unless a |
| 5847 |
* BindConnectiontoSession has already been done on the session. |
| 5834 |
*/ |
5848 |
*/ |
| 5835 |
if (sep->sess_clp->lc_req.nr_client != NULL && |
5849 |
if (sep->sess_clp->lc_req.nr_client != NULL && |
| 5836 |
(sep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN) != 0) { |
5850 |
sep->sess_cbsess.nfsess_xprt != nd->nd_xprt && |
|
|
5851 |
(sep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN) != 0 && |
| 5852 |
(sep->sess_clp->lc_flags & LCL_DONEBINDCONN) == 0) { |
| 5853 |
NFSD_DEBUG(2, |
| 5854 |
"nfsrv_checksequence: implicit back channel bind\n"); |
| 5837 |
savxprt = sep->sess_cbsess.nfsess_xprt; |
5855 |
savxprt = sep->sess_cbsess.nfsess_xprt; |
| 5838 |
SVC_ACQUIRE(nd->nd_xprt); |
5856 |
SVC_ACQUIRE(nd->nd_xprt); |
| 5839 |
nd->nd_xprt->xp_p2 = |
5857 |
nd->nd_xprt->xp_p2 = |
|
Lines 5950-5955
nfsrv_destroysession(struct nfsrv_descri
Link Here
|
| 5950 |
} |
5968 |
} |
| 5951 |
|
5969 |
|
| 5952 |
/* |
5970 |
/* |
|
|
5971 |
* Bind a connection to a session. |
| 5972 |
* For now, only certain variants are supported, since the current session |
| 5973 |
* structure can only handle a single backchannel entry, which will be |
| 5974 |
* applied to all connections if it is set. |
| 5975 |
*/ |
| 5976 |
int |
| 5977 |
nfsrv_bindconnsess(struct nfsrv_descript *nd, uint8_t *sessionid, int *foreaftp) |
| 5978 |
{ |
| 5979 |
struct nfssessionhash *shp; |
| 5980 |
struct nfsdsession *sep; |
| 5981 |
struct nfsclient *clp; |
| 5982 |
SVCXPRT *savxprt; |
| 5983 |
int error; |
| 5984 |
|
| 5985 |
error = 0; |
| 5986 |
shp = NFSSESSIONHASH(sessionid); |
| 5987 |
NFSLOCKSTATE(); |
| 5988 |
NFSLOCKSESSION(shp); |
| 5989 |
sep = nfsrv_findsession(sessionid); |
| 5990 |
if (sep != NULL) { |
| 5991 |
clp = sep->sess_clp; |
| 5992 |
if (*foreaftp == NFSCDFC4_BACK || |
| 5993 |
*foreaftp == NFSCDFC4_BACK_OR_BOTH || |
| 5994 |
*foreaftp == NFSCDFC4_FORE_OR_BOTH) { |
| 5995 |
/* Try to set up a backchannel. */ |
| 5996 |
if (clp->lc_req.nr_client == NULL) { |
| 5997 |
NFSD_DEBUG(2, "nfsrv_bindconnsess: acquire " |
| 5998 |
"backchannel\n"); |
| 5999 |
clp->lc_req.nr_client = (struct __rpc_client *) |
| 6000 |
clnt_bck_create(nd->nd_xprt->xp_socket, |
| 6001 |
sep->sess_cbprogram, NFSV4_CBVERS); |
| 6002 |
} |
| 6003 |
if (clp->lc_req.nr_client != NULL) { |
| 6004 |
NFSD_DEBUG(2, "nfsrv_bindconnsess: set up " |
| 6005 |
"backchannel\n"); |
| 6006 |
savxprt = sep->sess_cbsess.nfsess_xprt; |
| 6007 |
SVC_ACQUIRE(nd->nd_xprt); |
| 6008 |
nd->nd_xprt->xp_p2 = |
| 6009 |
clp->lc_req.nr_client->cl_private; |
| 6010 |
/* Disable idle timeout. */ |
| 6011 |
nd->nd_xprt->xp_idletimeout = 0; |
| 6012 |
sep->sess_cbsess.nfsess_xprt = nd->nd_xprt; |
| 6013 |
if (savxprt != NULL) |
| 6014 |
SVC_RELEASE(savxprt); |
| 6015 |
sep->sess_crflags |= NFSV4CRSESS_CONNBACKCHAN; |
| 6016 |
clp->lc_flags |= LCL_DONEBINDCONN; |
| 6017 |
if (*foreaftp == NFSCDFS4_BACK) |
| 6018 |
*foreaftp = NFSCDFS4_BACK; |
| 6019 |
else |
| 6020 |
*foreaftp = NFSCDFS4_BOTH; |
| 6021 |
} else if (*foreaftp != NFSCDFC4_BACK) { |
| 6022 |
NFSD_DEBUG(2, "nfsrv_bindconnsess: can't set " |
| 6023 |
"up backchannel\n"); |
| 6024 |
sep->sess_crflags &= ~NFSV4CRSESS_CONNBACKCHAN; |
| 6025 |
clp->lc_flags |= LCL_DONEBINDCONN; |
| 6026 |
*foreaftp = NFSCDFS4_FORE; |
| 6027 |
} else { |
| 6028 |
error = NFSERR_NOTSUPP; |
| 6029 |
printf("nfsrv_bindconnsess: Can't add " |
| 6030 |
"backchannel\n"); |
| 6031 |
} |
| 6032 |
} else { |
| 6033 |
NFSD_DEBUG(2, "nfsrv_bindconnsess: Set forechannel\n"); |
| 6034 |
clp->lc_flags |= LCL_DONEBINDCONN; |
| 6035 |
*foreaftp = NFSCDFS4_FORE; |
| 6036 |
} |
| 6037 |
} else |
| 6038 |
error = NFSERR_BADSESSION; |
| 6039 |
NFSUNLOCKSESSION(shp); |
| 6040 |
NFSUNLOCKSTATE(); |
| 6041 |
return (error); |
| 6042 |
} |
| 6043 |
|
| 6044 |
/* |
| 5953 |
* Free up a session structure. |
6045 |
* Free up a session structure. |
| 5954 |
*/ |
6046 |
*/ |
| 5955 |
static int |
6047 |
static int |
|
Lines 5976-5981
nfsrv_freesession(struct nfsdsession *se
Link Here
|
| 5976 |
} |
6068 |
} |
| 5977 |
LIST_REMOVE(sep, sess_hash); |
6069 |
LIST_REMOVE(sep, sess_hash); |
| 5978 |
LIST_REMOVE(sep, sess_list); |
6070 |
LIST_REMOVE(sep, sess_list); |
|
|
6071 |
sep->sess_clp->lc_sesscnt--; |
| 5979 |
} |
6072 |
} |
| 5980 |
NFSUNLOCKSESSION(shp); |
6073 |
NFSUNLOCKSESSION(shp); |
| 5981 |
NFSUNLOCKSTATE(); |
6074 |
NFSUNLOCKSTATE(); |