|
root / base / usr / src / uts / common / nfs / nfs4x.h
nfs4x.h C 309 lines 8.5 KB
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright 2017 RackTop Systems.
 */

#ifndef _NFS4X_H
#define	_NFS4X_H

#ifdef	__cplusplus
extern "C" {
#endif

#ifdef _KERNEL

#include <sys/cred.h>
#include <nfs/nfs4_kprot.h>

/*
 * 24 bytes of rpc header
 * 12 bytes for compound header
 * 44 bytes for SEQUENCE response
 */
#define	NFS4_MIN_HDR_SEQSZ	(24 + 12 + 44)

/*
 * NFSv4.1: slot support (reply cache)
 */

#define	RFS4_SLOT_INUSE		(1 << 0)
#define	RFS4_SLOT_CACHED	(1 << 1)

/* Slot entry structure */
typedef struct rfs4_slot {
	uint32_t	se_flags;
	sequenceid4	se_seqid;
	COMPOUND4res	se_buf;	/* Buf for slot and replays */
	void		*se_p;	/* Call-back race detection info buf */
	kmutex_t	se_lock;
} rfs4_slot_t;

/* se_state values */
#define	SLRC_EMPTY_SLOT		0x00000001
#define	SLRC_CACHED_OKAY	0x00000002
#define	SLRC_CACHED_PURGING	0x00000004
#define	SLRC_INPROG_NEWREQ	0x00000008
#define	SLRC_INPROG_REPLAY	0x00000010
#define	SLOT_FREE		0x00000020
#define	SLOT_ERROR		0x00000040
#define	SLOT_INUSE		0x00000080
#define	SLOT_RECALLED		0x00000100

/* Slot entry structure */
typedef struct slot_ent {
	avl_node_t	se_node;
	slotid4		se_sltno;
	uint32_t	se_state;
	sequenceid4	se_seqid;
	COMPOUND4res	se_buf;	/* Buf for slot and replays */
	void		*se_p;	/* Call-back race detection info buf */
	kmutex_t	se_lock;
	kcondvar_t	se_wait;
} slot_ent_t;

/* Slot table token */
typedef struct slot_tab_token {
	uint_t		st_currw;	/* current width of slot table */
	uint_t		st_fslots;	/* current # of available slots */
	avl_tree_t	*st_sltab;	/* tree of 'currw' pointers */
	kmutex_t	st_lock;	/* cache lock; resize or destroy */
	kcondvar_t	st_wait;
	void		(*cleanup_entry)(slot_ent_t *);
} stok_t;

typedef enum {
	SLT_NOSLEEP	= 0,
	SLT_SLEEP	= 1
} slt_wait_t;

#define	SA_SLOT_ANY	0x0001
#define	SA_SLOT_SPEC	0x0002

typedef struct {
	slotid4		sa_sltno;
	uint16_t	sa_flags;
} slt_arg_t;

typedef enum {
	SLT_MAXSLOT	= 1
} slt_query_t;

/*
 * NFSv4.x Sessions
 */

/*
 * 4.1 only: delegation recallable state info.
 * struct contents meaningful iff refcnt > 0
 */
typedef struct {
	uint32_t	refcnt;
	sessionid4	sessid;
	sequenceid4	seqid;
	slotid4		slotno;
} rfs41_drs_info_t;

typedef struct rfs41_csr {	/* contrived create_session result */
	sequenceid4		xi_sid;		/* seqid response to EXCHG_ID */
	nfsstat4		cs_status;
	CREATE_SESSION4resok	cs_res;		/* cached results if NFS4_OK */
} rfs41_csr_t;

/*
 * Sessions Callback Infrastructure
 *
 * Locking:
 *
 * . cn_lock protects all fields in sess_channel_t, but since
 *   fore/back and dir don't change often, we serialize only
 *   the occasional update.
 *
 * cn_lock:	cn_lock
 * bsd_rwlock:	cn_lock -> bsd_rwlock
 */

#define		MAX_CH_CACHE	10
typedef struct {				/* Back Chan Specific Data */
	stok_t			 *bsd_stok;	/* opaque token for slot tab */
	nfsstat4		  bsd_stat;
	kmutex_t		  bsd_lock;	/* protect slot tab info */
	int			  bsd_ch_free;
	CLIENT			 *bsd_clnt[MAX_CH_CACHE];
} sess_bcsd_t;

typedef struct {
	channel_dir_from_server4 cn_dir;		/* Chan Direction */
	sess_bcsd_t		*cn_csd;		/* Chan Specific Data */
	krwlock_t		 cn_lock;
} sess_channel_t;

/*
 * Maximum number of concurrent COMPOUND requests per session
 */
#define	MAXSLOTS	256
#define	MAXSLOTS_BACK	16

typedef struct {
	state_protect_how4	 sp_type;
} rfs41_sprot_t;

/*
 * NFSv4.1 Sessions (cont'd)
 *
 *   rfs4_session_t             rfs4_client_t
 *   +-------------+           +--------------------+
 *   | sn_sessid   |           | clientid           |
 *   | sn_clnt *  -|---------->|    :               |
 *   | sn_fore     |           +--------------------+
 *   | sn_back     |
 *   | sn_slots * -|---------> +--------------------------------+
 *   +-------------+           |        (slot_ent_t)            |
 *                             |  +----------------------------+|
 *                             |  | status, slot, seqid, resp *||------><Res>
 *                             |  +----------------------------+|
 *                             |  | status, slot, seqid, resp *||
 *                             |  +----------------------------+|
 *                             |  | status, slot, seqid, resp *||
 *                             |  +----------------------------+|
 *			       | .				|
 *			       | :				|
 *                             +--------------------------------+
 *                             stok_t
 */
struct rfs4_client;
struct rfs4_dbe;

typedef struct {
	nfsstat4		 cs_error;
	struct rfs4_client	*cs_client;
	struct svc_req		*cs_req;
	uint32_t		 cs_id;
	CREATE_SESSION4args	 cs_aotw;
} session41_create_t;

/*
 * sn_seq4 - sequence result bit accounting info (session scope)
 *	CB_PATH_DOWN_SESSION, CB_GSS_CONTEXT_EXPIRING,
 *	CB_GSS_CONTEXT_EXPIRED, BACKCHANNEL_FAULT
 */
typedef struct rfs4_session {
	struct rfs4_dbe		*sn_dbe;
	sessionid4		 sn_sessid;	/* session id */
	struct rfs4_client	*sn_clnt;	/* back ptr to client state */
	sess_channel_t		*sn_fore;	/* fore chan for this session */
	sess_channel_t		*sn_back;	/* back chan for this session */
	channel_attrs4		cn_attrs;	/* chan Attrs */
	channel_attrs4		cn_back_attrs;	/* back channel Attrs */
	rfs4_slot_t		*sn_slots;	/* slot replay cache */
	time_t			 sn_laccess;	/* struct was last accessed */
	int			 sn_csflags;	/* create_session only flags */
	bool_t			 sn_bdrpc;
	uint32_t		 sn_flags;	/* SEQ4 status bits */
	list_node_t		 sn_node;	/* link node to rfs4_client */
	struct	{
		uint32_t	pngcnt;		/* conn pings outstanding */
		uint32_t	paths;		/* callback paths verified */
		uint32_t	progno;		/* cb_program number */
		csa_sec_parms_t	secprms;	/* csa_sec_params */
		uint32_t	failed:1;	/* TRUE if no cb path avail */
		uint32_t	pnginprog:1;
		uint32_t	_reserved:30;
		cred_t		*cr;
	} sn_bc;
	uint32_t		 sn_rcached;	/* cached replies, for stat */
} rfs4_session_t;

#define	SN_CB_CHAN_EST(x)	((x)->sn_back != NULL)
#define	SN_CB_CHAN_OK(x)	((x)->sn_bc.failed == 0)

/* error code for internal use */
#define	nfserr_replay_cache NFS4ERR_REPLAY_CACHE

/* Session end */

/*
 * Set of RPC credentials used for a particular operation.
 * Used for operations like SETCLIENTID_CONFIRM where the
 * credentials needs to match those used at SETCLIENTID.
 * For EXCHANGE_ID (NFSv4.1+)
 */

typedef struct {
	cred_t	*cp_cr;
	int	 cp_aflavor;
	int	 cp_secmod;
	caddr_t	 cp_princ;
} cred_set_t;

/* NFSv4.1 Functions */
extern int rfs4x_dispatch(struct svc_req *, SVCXPRT *, char *);

void rfs4_free_cred_set(cred_set_t *);
void rfs4x_session_rele(rfs4_session_t *);
rfs4_session_t *rfs4x_createsession(session41_create_t *);
nfsstat4 rfs4x_destroysession(rfs4_session_t *, unsigned useref);
void rfs4x_client_session_remove(struct rfs4_client *);
rfs4_session_t *rfs4x_findsession_by_id(sessionid4);

void rfs4x_session_hold(rfs4_session_t *);
void rfs4x_session_rele(rfs4_session_t *);

/* Some init/fini helpers */
struct rfs4_srv;
struct compound_state;
void rfs4x_state_init_locked(struct nfs4_srv *);
void rfs4x_state_fini(struct nfs4_srv *);
int rfs4x_sequence_prep(COMPOUND4args *, COMPOUND4res *,
    struct compound_state *, SVCXPRT *);
void rfs4x_sequence_done(COMPOUND4res *, struct compound_state *);

extern void rfs4x_cb_chflush(rfs4_session_t *);

/*
 * NFS4.1 backchannel security
 */
struct rfs4_deleg_state;
struct rfs4_client;

extern bool_t rfs4x_cbsec_valid(callback_sec_parms4 *);
extern void rfs4x_cbsec_init(callback_sec_parms4 *, callback_sec_parms4 *);
extern void rfs4x_cbsec_fini(rfs4_session_t *);
extern uid_t rfs4x_cbsec_getuid(callback_sec_parms4 *);
extern gid_t rfs4x_cbsec_getgid(callback_sec_parms4 *);
extern sess_channel_t *rfs41_create_session_channel(channel_dir_from_server4);
extern void rfs41_destroy_back_channel(sess_channel_t *);
extern slotid4 svc_slot_maxslot(rfs4_session_t *);
extern nfsstat4 slot_cb_status(stok_t *);
extern void rfs41_deleg_rs_hold(struct rfs4_deleg_state *);
extern void rfs41_deleg_rs_rele(struct rfs4_deleg_state *);


/*
 * NFS4.1 Backchannel slot support.
 */
extern int slot_alloc(stok_t *, slt_wait_t, slot_ent_t **);
extern void slot_free(stok_t *, slot_ent_t *);
extern void slot_table_create(stok_t **, int);
extern void slot_incr_seq(slot_ent_t *);
extern void slot_table_destroy(stok_t *);
extern void slot_table_query(stok_t *, slt_query_t, void *);
extern slot_ent_t *slot_get(stok_t *, slotid4);

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _NFS4X_H */