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 (+4 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
/*
Lines 299-304 struct nfsreferral { Link Here
299
#define	LCL_ADMINREVOKED	0x00008000
302
#define	LCL_ADMINREVOKED	0x00008000
300
#define	LCL_RECLAIMCOMPLETE	0x00010000
303
#define	LCL_RECLAIMCOMPLETE	0x00010000
301
#define	LCL_NFSV41		0x00020000
304
#define	LCL_NFSV41		0x00020000
305
#define	LCL_DONEBINDCONN	0x00040000
302
306
303
#define	LCL_GSS		LCL_KERBV	/* Or of all mechs */
307
#define	LCL_GSS		LCL_KERBV	/* Or of all mechs */
304
308
(-)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/nfs/nfsproto.h (+9 lines)
Lines 650-655 Link Here
650
#define	NFSFLAYUTIL_DENSE		0x1
650
#define	NFSFLAYUTIL_DENSE		0x1
651
#define	NFSFLAYUTIL_COMMIT_THRU_MDS	0x2
651
#define	NFSFLAYUTIL_COMMIT_THRU_MDS	0x2
652
652
653
/* Enum values for Bind Connection to Session. */
654
#define	NFSCDFC4_FORE		0x1
655
#define	NFSCDFC4_BACK		0x2
656
#define	NFSCDFC4_FORE_OR_BOTH	0x3
657
#define	NFSCDFC4_BACK_OR_BOTH	0x7
658
#define	NFSCDFS4_FORE		0x1
659
#define	NFSCDFS4_BACK		0x2
660
#define	NFSCDFS4_BOTH		0x3
661
653
/* Conversion macros */
662
/* Conversion macros */
654
#define	vtonfsv2_mode(t,m) 						\
663
#define	vtonfsv2_mode(t,m) 						\
655
		txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : 	\
664
		txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : 	\
(-)fs/nfsserver/nfs_nfsdstate.c (-7 / +100 lines)
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();
(-)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