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(); |