summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/nfs/nfs4x.h
blob: 52c5f7f74ceca1bcdc5432649612be9c1f704a2e (plain)
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
/*
 * 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>

/*
 * 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 */
	kmutex_t	se_lock;
} rfs4_slot_t;

/*
 * NFSv4.1 Sessions
 */

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 */
	rfs4_slot_t		 *bsd_slots;	/* opaque token for slot tab */
	nfsstat4		  bsd_stat;
	krwlock_t		  bsd_rwlock;	/* protect slot tab info */
	uint64_t		  bsd_idx;	/* Index of next spare CLNT */
	uint64_t		  bsd_cur;	/* Most recent added CLNT */
	int			  bsd_ch_free;
	CLIENT			 *bsd_clnt[MAX_CH_CACHE];
} sess_bcsd_t;

typedef struct {
	channel_dir_from_server4 cn_dir;		/* Chan Direction */
	channel_attrs4		 cn_attrs;		/* chan Attrs */
	channel_attrs4		 cn_back_attrs;		/* back channel Attrs */
	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	4

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 */
	rfs4_slot_t		*sn_slots;	/* slot replay cache */
	time_t			 sn_laccess;	/* struct was last accessed */
	int			 sn_csflags;	/* create_session only flags */
	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	progno;		/* cb_program number */
		uint32_t	failed:1;	/* TRUE if no cb path avail */
		uint32_t	pnginprog:1;
	} 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 *);
void rfs4x_sequence_done(COMPOUND4res *, struct compound_state *);

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif /* _NFS4X_H */