View | Details | Raw Unified | Return to bug 226493 | Differences between
and this patch

Collapse All | Expand All

(-)fs/nfs/nfsrvstate.h (+1 lines)
Lines 101-106 struct nfsclient { Link Here
101
	u_char		*lc_name;
101
	u_char		*lc_name;
102
	struct nfssockreq lc_req;		/* Callback info */
102
	struct nfssockreq lc_req;		/* Callback info */
103
	u_int32_t	lc_flags;		/* LCL_ flag bits */
103
	u_int32_t	lc_flags;		/* LCL_ flag bits */
104
	u_int32_t	lc_sesscnt;		/* Count of sessions. */
104
	u_char		lc_verf[NFSX_VERF];	 /* client verifier */
105
	u_char		lc_verf[NFSX_VERF];	 /* client verifier */
105
	u_char		lc_id[1];		/* Malloc'd correct size */
106
	u_char		lc_id[1];		/* Malloc'd correct size */
106
};
107
};
(-)fs/nfs/nfs.h (+3 lines)
Lines 128-133 Link Here
128
#ifndef NFS_ACCESSCACHESIZE
128
#ifndef NFS_ACCESSCACHESIZE
129
#define	NFS_ACCESSCACHESIZE	8
129
#define	NFS_ACCESSCACHESIZE	8
130
#endif
130
#endif
131
#ifndef	NFSRV_MAXCLIENTSESS
132
#define	NFSRV_MAXCLIENTSESS	32
133
#endif
131
#define	NFSV4_CBPORT	7745		/* Callback port for testing */
134
#define	NFSV4_CBPORT	7745		/* Callback port for testing */
132
135
133
/*
136
/*
(-)fs/nfs/nfsproto.h (+12 lines)
Lines 614-619 Link Here
614
#define	NFSV4CRSESS_CONNBACKCHAN	0x00000002
614
#define	NFSV4CRSESS_CONNBACKCHAN	0x00000002
615
#define	NFSV4CRSESS_CONNRDMA		0x00000004
615
#define	NFSV4CRSESS_CONNRDMA		0x00000004
616
616
617
/* Local flags for sess_crflags (never on wire). */
618
#define	NFSV4CRSESS_DONEBINDCONN	0x80000000
619
617
/* Flags for Sequence */
620
/* Flags for Sequence */
618
#define	NFSV4SEQ_CBPATHDOWN		0x00000001
621
#define	NFSV4SEQ_CBPATHDOWN		0x00000001
619
#define	NFSV4SEQ_CBGSSCONTEXPIRING	0x00000002
622
#define	NFSV4SEQ_CBGSSCONTEXPIRING	0x00000002
Lines 650-655 Link Here
650
#define	NFSFLAYUTIL_DENSE		0x1
653
#define	NFSFLAYUTIL_DENSE		0x1
651
#define	NFSFLAYUTIL_COMMIT_THRU_MDS	0x2
654
#define	NFSFLAYUTIL_COMMIT_THRU_MDS	0x2
652
655
656
/* Enum values for Bind Connection to Session. */
657
#define	NFSCDFC4_FORE		0x1
658
#define	NFSCDFC4_BACK		0x2
659
#define	NFSCDFC4_FORE_OR_BOTH	0x3
660
#define	NFSCDFC4_BACK_OR_BOTH	0x7
661
#define	NFSCDFS4_FORE		0x1
662
#define	NFSCDFS4_BACK		0x2
663
#define	NFSCDFS4_BOTH		0x3
664
653
/* Conversion macros */
665
/* Conversion macros */
654
#define	vtonfsv2_mode(t,m) 						\
666
#define	vtonfsv2_mode(t,m) 						\
655
		txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : 	\
667
		txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : 	\
(-)fs/nfs/nfs_var.h (+3 lines)
Lines 95-100 int nfsrv_getclient(nfsquad_t, int, stru Link Here
95
    nfsquad_t, uint32_t, struct nfsrv_descript *, NFSPROC_T *);
95
    nfsquad_t, uint32_t, struct nfsrv_descript *, NFSPROC_T *);
96
int nfsrv_destroyclient(nfsquad_t, NFSPROC_T *);
96
int nfsrv_destroyclient(nfsquad_t, NFSPROC_T *);
97
int nfsrv_destroysession(struct nfsrv_descript *, uint8_t *);
97
int nfsrv_destroysession(struct nfsrv_descript *, uint8_t *);
98
int nfsrv_bindconnsess(struct nfsrv_descript *, uint8_t *, int *);
98
int nfsrv_freestateid(struct nfsrv_descript *, nfsv4stateid_t *, NFSPROC_T *);
99
int nfsrv_freestateid(struct nfsrv_descript *, nfsv4stateid_t *, NFSPROC_T *);
99
int nfsrv_adminrevoke(struct nfsd_clid *, NFSPROC_T *);
100
int nfsrv_adminrevoke(struct nfsd_clid *, NFSPROC_T *);
100
void nfsrv_dumpclients(struct nfsd_dumpclients *, int);
101
void nfsrv_dumpclients(struct nfsd_dumpclients *, int);
Lines 230-235 int nfsrvd_reclaimcomplete(struct nfsrv_ Link Here
230
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
231
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
231
int nfsrvd_destroyclientid(struct nfsrv_descript *, int,
232
int nfsrvd_destroyclientid(struct nfsrv_descript *, int,
232
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
233
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
234
int nfsrvd_bindconnsess(struct nfsrv_descript *, int,
235
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
233
int nfsrvd_destroysession(struct nfsrv_descript *, int,
236
int nfsrvd_destroysession(struct nfsrv_descript *, int,
234
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
237
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
235
int nfsrvd_freestateid(struct nfsrv_descript *, int,
238
int nfsrvd_freestateid(struct nfsrv_descript *, int,
(-)fs/nfs/nfs_commonsubs.c (-1 / +1 lines)
Lines 136-142 struct nfsv4_opflag nfsv4_opflag[NFSV41_ Link Here
136
	{ 0, 2, 1, 1, LK_EXCLUSIVE, 1, 0 },		/* Write */
136
	{ 0, 2, 1, 1, LK_EXCLUSIVE, 1, 0 },		/* Write */
137
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 0 },		/* ReleaseLockOwner */
137
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 0 },		/* ReleaseLockOwner */
138
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Backchannel Ctrl */
138
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Backchannel Ctrl */
139
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Bind Conn to Sess */
139
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Bind Conn to Sess */
140
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Exchange ID */
140
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Exchange ID */
141
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Create Session */
141
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Create Session */
142
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Destroy Session */
142
	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Destroy Session */
(-)fs/nfsserver/nfs_nfsdstate.c (-6 / +87 lines)
Lines 582-587 nfsrv_getclient(nfsquad_t clientid, int Link Here
582
			error = NFSERR_STALECLIENTID;
582
			error = NFSERR_STALECLIENTID;
583
		else if (nfsrv_notsamecredname(nd, clp))
583
		else if (nfsrv_notsamecredname(nd, clp))
584
			error = NFSERR_CLIDINUSE;
584
			error = NFSERR_CLIDINUSE;
585
		else if ((nd->nd_flag & ND_NFSV41) != 0 && nsep != NULL &&
586
		    clp->lc_sesscnt > NFSRV_MAXCLIENTSESS)
587
{ printf("Too many sessions\n");
588
			error = NFSERR_RESOURCE;
589
}
585
590
586
		if (!error) {
591
		if (!error) {
587
		    if ((clp->lc_flags & (LCL_NEEDSCONFIRM | LCL_DONTCLEAN)) ==
592
		    if ((clp->lc_flags & (LCL_NEEDSCONFIRM | LCL_DONTCLEAN)) ==
Lines 614-623 nfsrv_getclient(nfsquad_t clientid, int Link Here
614
		    if (nsep != NULL) {
619
		    if (nsep != NULL) {
615
			/* Hold a reference on the xprt for a backchannel. */
620
			/* Hold a reference on the xprt for a backchannel. */
616
			if ((nsep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN)
621
			if ((nsep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN)
617
			    != 0 && clp->lc_req.nr_client == NULL) {
622
			    != 0) {
618
			    clp->lc_req.nr_client = (struct __rpc_client *)
623
			    if (clp->lc_req.nr_client == NULL)
619
				clnt_bck_create(nd->nd_xprt->xp_socket,
624
				clp->lc_req.nr_client = (struct __rpc_client *)
620
				cbprogram, NFSV4_CBVERS);
625
				    clnt_bck_create(nd->nd_xprt->xp_socket,
626
				    cbprogram, NFSV4_CBVERS);
621
			    if (clp->lc_req.nr_client != NULL) {
627
			    if (clp->lc_req.nr_client != NULL) {
622
				SVC_ACQUIRE(nd->nd_xprt);
628
				SVC_ACQUIRE(nd->nd_xprt);
623
				nd->nd_xprt->xp_p2 =
629
				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);
644
			LIST_INSERT_HEAD(&shp->list, nsep, sess_hash);
639
			LIST_INSERT_HEAD(&clp->lc_session, nsep, sess_list);
645
			LIST_INSERT_HEAD(&clp->lc_session, nsep, sess_list);
640
			nsep->sess_clp = clp;
646
			nsep->sess_clp = clp;
647
			clp->lc_sesscnt++;
641
			NFSUNLOCKSESSION(shp);
648
			NFSUNLOCKSESSION(shp);
642
			NFSUNLOCKSTATE();
649
			NFSUNLOCKSTATE();
643
		    }
650
		    }
Lines 4248-4254 nfsrv_docallback(struct nfsclient *clp, Link Here
4248
			error = newnfs_request(nd, NULL, clp, &clp->lc_req,
4255
			error = newnfs_request(nd, NULL, clp, &clp->lc_req,
4249
			    NULL, NULL, cred, clp->lc_program,
4256
			    NULL, NULL, cred, clp->lc_program,
4250
			    clp->lc_req.nr_vers, NULL, 1, NULL, NULL);
4257
			    clp->lc_req.nr_vers, NULL, 1, NULL, NULL);
4251
	}
4258
	} else if ((nd->nd_flag & ND_NFSV41) != 0 && sep != NULL)
4259
		nfsrv_freesession(sep, NULL);
4252
errout:
4260
errout:
4253
	NFSFREECRED(cred);
4261
	NFSFREECRED(cred);
4254
4262
Lines 5833-5839 nfsrv_checksequence(struct nfsrv_descrip Link Here
5833
	 * RPC, since this is the one being used.
5841
	 * RPC, since this is the one being used.
5834
	 */
5842
	 */
5835
	if (sep->sess_clp->lc_req.nr_client != NULL &&
5843
	if (sep->sess_clp->lc_req.nr_client != NULL &&
5836
	    (sep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN) != 0) {
5844
	    sep->sess_cbsess.nfsess_xprt != nd->nd_xprt &&
5845
	    (sep->sess_crflags & (NFSV4CRSESS_CONNBACKCHAN |
5846
	     NFSV4CRSESS_DONEBINDCONN)) == NFSV4CRSESS_CONNBACKCHAN) {
5847
printf("implicit bind backchan\n");
5837
		savxprt = sep->sess_cbsess.nfsess_xprt;
5848
		savxprt = sep->sess_cbsess.nfsess_xprt;
5838
		SVC_ACQUIRE(nd->nd_xprt);
5849
		SVC_ACQUIRE(nd->nd_xprt);
5839
		nd->nd_xprt->xp_p2 =
5850
		nd->nd_xprt->xp_p2 =
Lines 5950-5955 nfsrv_destroysession(struct nfsrv_descri Link Here
5950
}
5961
}
5951
5962
5952
/*
5963
/*
5964
 * Bind a connection to a session.
5965
 * For now, only certain variants are supported, since the current session
5966
 * structure can only handle a single backchannel entry, which will be
5967
 * applied to all connections if it is set.
5968
 */
5969
int
5970
nfsrv_bindconnsess(struct nfsrv_descript *nd, uint8_t *sessionid, int *foreaftp)
5971
{
5972
	struct nfssessionhash *shp;
5973
	struct nfsdsession *sep;
5974
	struct nfsclient *clp;
5975
	SVCXPRT *savxprt;
5976
	int error;
5977
5978
	error = 0;
5979
	shp = NFSSESSIONHASH(sessionid);
5980
	NFSLOCKSESSION(shp);
5981
	sep = nfsrv_findsession(sessionid);
5982
	if (sep != NULL) {
5983
		clp = sep->sess_clp;
5984
		if (*foreaftp == NFSCDFC4_BACK ||
5985
		    *foreaftp == NFSCDFC4_BACK_OR_BOTH ||
5986
		    *foreaftp == NFSCDFC4_FORE_OR_BOTH) {
5987
			/* Try to set up a backchannel. */
5988
			if (clp->lc_req.nr_client == NULL)
5989
{ printf("nfsrv_bindconnsess: clnt_bck_create\n");
5990
				clp->lc_req.nr_client = (struct __rpc_client *)
5991
				    clnt_bck_create(nd->nd_xprt->xp_socket,
5992
				    sep->sess_cbprogram, NFSV4_CBVERS);
5993
}
5994
			if (clp->lc_req.nr_client != NULL) {
5995
				savxprt = sep->sess_cbsess.nfsess_xprt;
5996
				SVC_ACQUIRE(nd->nd_xprt);
5997
				nd->nd_xprt->xp_p2 =
5998
				    clp->lc_req.nr_client->cl_private;
5999
				/* Disable idle timeout. */
6000
				nd->nd_xprt->xp_idletimeout = 0;
6001
				sep->sess_cbsess.nfsess_xprt = nd->nd_xprt;
6002
				if (savxprt != NULL)
6003
					SVC_RELEASE(savxprt);
6004
				sep->sess_crflags |= (NFSV4CRSESS_CONNBACKCHAN |
6005
				     NFSV4CRSESS_DONEBINDCONN);
6006
				if (*foreaftp == NFSCDFS4_BACK)
6007
					*foreaftp = NFSCDFS4_BACK;
6008
				else
6009
					*foreaftp = NFSCDFS4_BOTH;
6010
printf("nfsrv_bindconnsess: Added backchannel\n");
6011
			} else if (*foreaftp != NFSCDFC4_BACK) {
6012
printf("nfsrv_bindconnsess: No backchannel\n");
6013
				sep->sess_crflags &= ~NFSV4CRSESS_CONNBACKCHAN;
6014
				sep->sess_crflags |= NFSV4CRSESS_DONEBINDCONN;
6015
				*foreaftp = NFSCDFS4_FORE;
6016
			} else {
6017
				error = NFSERR_NOTSUPP;
6018
				printf("nfsrv_bindconnsess: Can't add "
6019
				    "backchannel\n");
6020
			}
6021
		} else {
6022
printf("nfsrv_bindconnsess: Set forechannel\n");
6023
			sep->sess_crflags |= NFSV4CRSESS_DONEBINDCONN;
6024
			*foreaftp = NFSCDFS4_FORE;
6025
		}
6026
	} else
6027
		error = NFSERR_BADSESSION;
6028
	NFSUNLOCKSESSION(shp);
6029
	return (error);
6030
}
6031
6032
/*
5953
 * Free up a session structure.
6033
 * Free up a session structure.
5954
 */
6034
 */
5955
static int
6035
static int
Lines 5976-5981 nfsrv_freesession(struct nfsdsession *se Link Here
5976
		}
6056
		}
5977
		LIST_REMOVE(sep, sess_hash);
6057
		LIST_REMOVE(sep, sess_hash);
5978
		LIST_REMOVE(sep, sess_list);
6058
		LIST_REMOVE(sep, sess_list);
6059
		sep->sess_clp->lc_sesscnt--;
5979
	}
6060
	}
5980
	NFSUNLOCKSESSION(shp);
6061
	NFSUNLOCKSESSION(shp);
5981
	NFSUNLOCKSTATE();
6062
	NFSUNLOCKSTATE();
(-)fs/nfsserver/nfs_nfsdserv.c (+39 lines)
Lines 4041-4046 nfsmout: Link Here
4041
}
4041
}
4042
4042
4043
/*
4043
/*
4044
 * nfsv4 bind connection to session service
4045
 */
4046
APPLESTATIC int
4047
nfsrvd_bindconnsess(struct nfsrv_descript *nd, __unused int isdgram,
4048
    __unused vnode_t vp, NFSPROC_T *p, __unused struct nfsexstuff *exp)
4049
{
4050
	uint32_t *tl;
4051
	uint8_t sessid[NFSX_V4SESSIONID];
4052
	int error = 0, foreaft;
4053
4054
	if (nfs_rootfhset == 0 || nfsd_checkrootexp(nd) != 0) {
4055
		nd->nd_repstat = NFSERR_WRONGSEC;
4056
		goto nfsmout;
4057
	}
4058
	NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID + 2 * NFSX_UNSIGNED);
4059
	NFSBCOPY(tl, sessid, NFSX_V4SESSIONID);
4060
	tl += (NFSX_V4SESSIONID / NFSX_UNSIGNED);
4061
	foreaft = fxdr_unsigned(int, *tl++);
4062
	if (*tl == newnfs_true) {
4063
		/* RDMA is not supported. */
4064
		nd->nd_repstat = NFSERR_NOTSUPP;
4065
		goto nfsmout;
4066
	}
4067
4068
	nd->nd_repstat = nfsrv_bindconnsess(nd, sessid, &foreaft);
4069
	if (nd->nd_repstat == 0) {
4070
		NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID + 2 *
4071
		    NFSX_UNSIGNED);
4072
		NFSBCOPY(sessid, tl, NFSX_V4SESSIONID);
4073
		tl += (NFSX_V4SESSIONID / NFSX_UNSIGNED);
4074
		*tl++ = txdr_unsigned(foreaft);
4075
		*tl = newnfs_false;
4076
	}
4077
nfsmout:
4078
	NFSEXITCODE2(error, nd);
4079
	return (error);
4080
}
4081
4082
/*
4044
 * nfsv4 destroy session service
4083
 * nfsv4 destroy session service
4045
 */
4084
 */
4046
APPLESTATIC int
4085
APPLESTATIC int
(-)fs/nfsserver/nfs_nfsdsocket.c (-1 / +1 lines)
Lines 176-182 int (*nfsrv4_ops0[NFSV41_NOPS])(struct n Link Here
176
	nfsrvd_write,
176
	nfsrvd_write,
177
	nfsrvd_releaselckown,
177
	nfsrvd_releaselckown,
178
	nfsrvd_notsupp,
178
	nfsrvd_notsupp,
179
	nfsrvd_notsupp,
179
	nfsrvd_bindconnsess,
180
	nfsrvd_exchangeid,
180
	nfsrvd_exchangeid,
181
	nfsrvd_createsession,
181
	nfsrvd_createsession,
182
	nfsrvd_destroysession,
182
	nfsrvd_destroysession,

Return to bug 226493