1/*
2 *  Copyright (c) 2001 The Regents of the University of Michigan.
3 *  All rights reserved.
4 *
5 *  Kendrick Smith <kmsmith@umich.edu>
6 *  Andy Adamson <andros@umich.edu>
7 *
8 *  Redistribution and use in source and binary forms, with or without
9 *  modification, are permitted provided that the following conditions
10 *  are met:
11 *
12 *  1. Redistributions of source code must retain the above copyright
13 *     notice, this list of conditions and the following disclaimer.
14 *  2. Redistributions in binary form must reproduce the above copyright
15 *     notice, this list of conditions and the following disclaimer in the
16 *     documentation and/or other materials provided with the distribution.
17 *  3. Neither the name of the University nor the names of its
18 *     contributors may be used to endorse or promote products derived
19 *     from this software without specific prior written permission.
20 *
21 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#ifndef _NFSD4_STATE_H
36#define _NFSD4_STATE_H
37
38#include <linux/nfsd/nfsfh.h>
39#include "nfsfh.h"
40
41typedef struct {
42	u32             cl_boot;
43	u32             cl_id;
44} clientid_t;
45
46typedef struct {
47	u32             so_boot;
48	u32             so_stateownerid;
49	u32             so_fileid;
50} stateid_opaque_t;
51
52typedef struct {
53	u32                     si_generation;
54	stateid_opaque_t        si_opaque;
55} stateid_t;
56#define si_boot           si_opaque.so_boot
57#define si_stateownerid   si_opaque.so_stateownerid
58#define si_fileid         si_opaque.so_fileid
59
60#define STATEID_FMT	"(%08x/%08x/%08x/%08x)"
61#define STATEID_VAL(s) \
62	(s)->si_boot, \
63	(s)->si_stateownerid, \
64	(s)->si_fileid, \
65	(s)->si_generation
66
67struct nfsd4_cb_sequence {
68	/* args/res */
69	u32			cbs_minorversion;
70	struct nfs4_client	*cbs_clp;
71};
72
73struct nfs4_rpc_args {
74	void				*args_op;
75	struct nfsd4_cb_sequence	args_seq;
76};
77
78struct nfsd4_callback {
79	struct nfs4_rpc_args cb_args;
80	struct work_struct cb_work;
81};
82
83struct nfs4_delegation {
84	struct list_head	dl_perfile;
85	struct list_head	dl_perclnt;
86	struct list_head	dl_recall_lru;  /* delegation recalled */
87	atomic_t		dl_count;       /* ref count */
88	struct nfs4_client	*dl_client;
89	struct nfs4_file	*dl_file;
90	struct file_lock	*dl_flock;
91	u32			dl_type;
92	time_t			dl_time;
93/* For recall: */
94	u32			dl_ident;
95	stateid_t		dl_stateid;
96	struct knfsd_fh		dl_fh;
97	int			dl_retries;
98	struct nfsd4_callback	dl_recall;
99};
100
101/* client delegation callback info */
102struct nfs4_cb_conn {
103	/* SETCLIENTID info */
104	struct sockaddr_storage	cb_addr;
105	size_t			cb_addrlen;
106	u32                     cb_prog;
107	u32			cb_minorversion;
108	u32                     cb_ident;	/* minorversion 0 only */
109	struct svc_xprt		*cb_xprt;	/* minorversion 1 only */
110};
111
112/* Maximum number of slots per session. 160 is useful for long haul TCP */
113#define NFSD_MAX_SLOTS_PER_SESSION     160
114/* Maximum number of operations per session compound */
115#define NFSD_MAX_OPS_PER_COMPOUND	16
116/* Maximum  session per slot cache size */
117#define NFSD_SLOT_CACHE_SIZE		1024
118/* Maximum number of NFSD_SLOT_CACHE_SIZE slots per session */
119#define NFSD_CACHE_SIZE_SLOTS_PER_SESSION	32
120#define NFSD_MAX_MEM_PER_SESSION  \
121		(NFSD_CACHE_SIZE_SLOTS_PER_SESSION * NFSD_SLOT_CACHE_SIZE)
122
123struct nfsd4_slot {
124	bool	sl_inuse;
125	bool	sl_cachethis;
126	u16	sl_opcnt;
127	u32	sl_seqid;
128	__be32	sl_status;
129	u32	sl_datalen;
130	char	sl_data[];
131};
132
133struct nfsd4_channel_attrs {
134	u32		headerpadsz;
135	u32		maxreq_sz;
136	u32		maxresp_sz;
137	u32		maxresp_cached;
138	u32		maxops;
139	u32		maxreqs;
140	u32		nr_rdma_attrs;
141	u32		rdma_attrs;
142};
143
144struct nfsd4_create_session {
145	clientid_t			clientid;
146	struct nfs4_sessionid		sessionid;
147	u32				seqid;
148	u32				flags;
149	struct nfsd4_channel_attrs	fore_channel;
150	struct nfsd4_channel_attrs	back_channel;
151	u32				callback_prog;
152	u32				uid;
153	u32				gid;
154};
155
156/* The single slot clientid cache structure */
157struct nfsd4_clid_slot {
158	u32				sl_seqid;
159	__be32				sl_status;
160	struct nfsd4_create_session	sl_cr_ses;
161};
162
163struct nfsd4_session {
164	struct kref		se_ref;
165	struct list_head	se_hash;	/* hash by sessionid */
166	struct list_head	se_perclnt;
167	u32			se_flags;
168	struct nfs4_client	*se_client;
169	struct nfs4_sessionid	se_sessionid;
170	struct nfsd4_channel_attrs se_fchannel;
171	struct nfsd4_channel_attrs se_bchannel;
172	struct nfsd4_slot	*se_slots[];	/* forward channel slots */
173};
174
175static inline void
176nfsd4_put_session(struct nfsd4_session *ses)
177{
178	extern void free_session(struct kref *kref);
179	kref_put(&ses->se_ref, free_session);
180}
181
182static inline void
183nfsd4_get_session(struct nfsd4_session *ses)
184{
185	kref_get(&ses->se_ref);
186}
187
188/* formatted contents of nfs4_sessionid */
189struct nfsd4_sessionid {
190	clientid_t	clientid;
191	u32		sequence;
192	u32		reserved;
193};
194
195#define HEXDIR_LEN     33 /* hex version of 16 byte md5 of cl_name plus '\0' */
196
197/*
198 * struct nfs4_client - one per client.  Clientids live here.
199 * 	o Each nfs4_client is hashed by clientid.
200 *
201 * 	o Each nfs4_clients is also hashed by name
202 * 	  (the opaque quantity initially sent by the client to identify itself).
203 *
204 *	o cl_perclient list is used to ensure no dangling stateowner references
205 *	  when we expire the nfs4_client
206 */
207struct nfs4_client {
208	struct list_head	cl_idhash; 	/* hash by cl_clientid.id */
209	struct list_head	cl_strhash; 	/* hash by cl_name */
210	struct list_head	cl_openowners;
211	struct list_head	cl_delegations;
212	struct list_head        cl_lru;         /* tail queue */
213	struct xdr_netobj	cl_name; 	/* id generated by client */
214	char                    cl_recdir[HEXDIR_LEN]; /* recovery dir */
215	nfs4_verifier		cl_verifier; 	/* generated by client */
216	time_t                  cl_time;        /* time of last lease renewal */
217	struct sockaddr_storage	cl_addr; 	/* client ipaddress */
218	u32			cl_flavor;	/* setclientid pseudoflavor */
219	char			*cl_principal;	/* setclientid principal name */
220	struct svc_cred		cl_cred; 	/* setclientid principal */
221	clientid_t		cl_clientid;	/* generated by server */
222	nfs4_verifier		cl_confirm;	/* generated by server */
223	u32			cl_firststate;	/* recovery dir creation */
224
225	/* for v4.0 and v4.1 callbacks: */
226	struct nfs4_cb_conn	cl_cb_conn;
227	struct rpc_clnt		*cl_cb_client;
228	atomic_t		cl_cb_set;
229
230	/* for nfs41 */
231	struct list_head	cl_sessions;
232	struct nfsd4_clid_slot	cl_cs_slot;	/* create_session slot */
233	u32			cl_exchange_flags;
234	struct nfs4_sessionid	cl_sessionid;
235	/* number of rpc's in progress over an associated session: */
236	atomic_t		cl_refcount;
237
238	/* for nfs41 callbacks */
239	/* We currently support a single back channel with a single slot */
240	unsigned long		cl_cb_slot_busy;
241	u32			cl_cb_seq_nr;
242	struct rpc_wait_queue	cl_cb_waitq;	/* backchannel callers may */
243						/* wait here for slots */
244};
245
246static inline void
247mark_client_expired(struct nfs4_client *clp)
248{
249	clp->cl_time = 0;
250}
251
252static inline bool
253is_client_expired(struct nfs4_client *clp)
254{
255	return clp->cl_time == 0;
256}
257
258/* struct nfs4_client_reset
259 * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl
260 * upon lease reset, or from upcall to state_daemon (to read in state
261 * from non-volitile storage) upon reboot.
262 */
263struct nfs4_client_reclaim {
264	struct list_head	cr_strhash;	/* hash by cr_name */
265	char			cr_recdir[HEXDIR_LEN]; /* recover dir */
266};
267
268static inline void
269update_stateid(stateid_t *stateid)
270{
271	stateid->si_generation++;
272}
273
274/* A reasonable value for REPLAY_ISIZE was estimated as follows:
275 * The OPEN response, typically the largest, requires
276 *   4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) +  8(verifier) +
277 *   4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) +
278 *   20(deleg. space limit) + ~32(deleg. ace) = 112 bytes
279 */
280
281#define NFSD4_REPLAY_ISIZE       112
282
283/*
284 * Replay buffer, where the result of the last seqid-mutating operation
285 * is cached.
286 */
287struct nfs4_replay {
288	__be32			rp_status;
289	unsigned int		rp_buflen;
290	char			*rp_buf;
291	unsigned		intrp_allocated;
292	struct knfsd_fh		rp_openfh;
293	char			rp_ibuf[NFSD4_REPLAY_ISIZE];
294};
295
296/*
297* nfs4_stateowner can either be an open_owner, or a lock_owner
298*
299*    so_idhash:  stateid_hashtbl[] for open owner, lockstateid_hashtbl[]
300*         for lock_owner
301*    so_strhash: ownerstr_hashtbl[] for open_owner, lock_ownerstr_hashtbl[]
302*         for lock_owner
303*    so_perclient: nfs4_client->cl_perclient entry - used when nfs4_client
304*         struct is reaped.
305*    so_perfilestate: heads the list of nfs4_stateid (either open or lock)
306*         and is used to ensure no dangling nfs4_stateid references when we
307*         release a stateowner.
308*    so_perlockowner: (open) nfs4_stateid->st_perlockowner entry - used when
309*         close is called to reap associated byte-range locks
310*    so_close_lru: (open) stateowner is placed on this list instead of being
311*         reaped (when so_perfilestate is empty) to hold the last close replay.
312*         reaped by laundramat thread after lease period.
313*/
314struct nfs4_stateowner {
315	struct kref		so_ref;
316	struct list_head        so_idhash;   /* hash by so_id */
317	struct list_head        so_strhash;   /* hash by op_name */
318	struct list_head        so_perclient;
319	struct list_head        so_stateids;
320	struct list_head        so_perstateid; /* for lockowners only */
321	struct list_head	so_close_lru; /* tail queue */
322	time_t			so_time; /* time of placement on so_close_lru */
323	int			so_is_open_owner; /* 1=openowner,0=lockowner */
324	u32                     so_id;
325	struct nfs4_client *    so_client;
326	/* after increment in ENCODE_SEQID_OP_TAIL, represents the next
327	 * sequence id expected from the client: */
328	u32                     so_seqid;
329	struct xdr_netobj       so_owner;     /* open owner name */
330	int                     so_confirmed; /* successful OPEN_CONFIRM? */
331	struct nfs4_replay	so_replay;
332};
333
334/*
335*  nfs4_file: a file opened by some number of (open) nfs4_stateowners.
336*    o fi_perfile list is used to search for conflicting
337*      share_acces, share_deny on the file.
338*/
339struct nfs4_file {
340	atomic_t		fi_ref;
341	struct list_head        fi_hash;    /* hash by "struct inode *" */
342	struct list_head        fi_stateids;
343	struct list_head	fi_delegations;
344	/* One each for O_RDONLY, O_WRONLY, O_RDWR: */
345	struct file *		fi_fds[3];
346	/* One each for O_RDONLY, O_WRONLY: */
347	atomic_t		fi_access[2];
348	/*
349	 * Each open stateid contributes 1 to either fi_readers or
350	 * fi_writers, or both, depending on the open mode.  A
351	 * delegation also takes an fi_readers reference.  Lock
352	 * stateid's take none.
353	 */
354	atomic_t		fi_readers;
355	atomic_t		fi_writers;
356	struct inode		*fi_inode;
357	u32                     fi_id;      /* used with stateowner->so_id
358					     * for stateid_hashtbl hash */
359	bool			fi_had_conflict;
360};
361
362static inline struct file *find_writeable_file(struct nfs4_file *f)
363{
364	if (f->fi_fds[O_WRONLY])
365		return f->fi_fds[O_WRONLY];
366	return f->fi_fds[O_RDWR];
367}
368
369static inline struct file *find_readable_file(struct nfs4_file *f)
370{
371	if (f->fi_fds[O_RDONLY])
372		return f->fi_fds[O_RDONLY];
373	return f->fi_fds[O_RDWR];
374}
375
376static inline struct file *find_any_file(struct nfs4_file *f)
377{
378	if (f->fi_fds[O_RDWR])
379		return f->fi_fds[O_RDWR];
380	else if (f->fi_fds[O_WRONLY])
381		return f->fi_fds[O_WRONLY];
382	else
383		return f->fi_fds[O_RDONLY];
384}
385
386
387struct nfs4_stateid {
388	struct list_head              st_hash;
389	struct list_head              st_perfile;
390	struct list_head              st_perstateowner;
391	struct list_head              st_lockowners;
392	struct nfs4_stateowner      * st_stateowner;
393	struct nfs4_file            * st_file;
394	stateid_t                     st_stateid;
395	unsigned long                 st_access_bmap;
396	unsigned long                 st_deny_bmap;
397	struct nfs4_stateid         * st_openstp;
398};
399
400/* flags for preprocess_seqid_op() */
401#define HAS_SESSION             0x00000001
402#define CONFIRM                 0x00000002
403#define OPEN_STATE              0x00000004
404#define LOCK_STATE              0x00000008
405#define RD_STATE	        0x00000010
406#define WR_STATE	        0x00000020
407#define CLOSE_STATE             0x00000040
408
409#define seqid_mutating_err(err)                       \
410	(((err) != nfserr_stale_clientid) &&    \
411	((err) != nfserr_bad_seqid) &&          \
412	((err) != nfserr_stale_stateid) &&      \
413	((err) != nfserr_bad_stateid))
414
415struct nfsd4_compound_state;
416
417extern __be32 nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
418		stateid_t *stateid, int flags, struct file **filp);
419extern void nfs4_lock_state(void);
420extern void nfs4_unlock_state(void);
421extern int nfs4_in_grace(void);
422extern __be32 nfs4_check_open_reclaim(clientid_t *clid);
423extern void nfs4_free_stateowner(struct kref *kref);
424extern int set_callback_cred(void);
425extern void nfsd4_probe_callback(struct nfs4_client *clp, struct nfs4_cb_conn *);
426extern void nfsd4_do_callback_rpc(struct work_struct *);
427extern void nfsd4_cb_recall(struct nfs4_delegation *dp);
428extern int nfsd4_create_callback_queue(void);
429extern void nfsd4_destroy_callback_queue(void);
430extern void nfsd4_set_callback_client(struct nfs4_client *, struct rpc_clnt *);
431extern void nfs4_put_delegation(struct nfs4_delegation *dp);
432extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname);
433extern void nfsd4_init_recdir(char *recdir_name);
434extern int nfsd4_recdir_load(void);
435extern void nfsd4_shutdown_recdir(void);
436extern int nfs4_client_to_reclaim(const char *name);
437extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id);
438extern void nfsd4_recdir_purge_old(void);
439extern int nfsd4_create_clid_dir(struct nfs4_client *clp);
440extern void nfsd4_remove_clid_dir(struct nfs4_client *clp);
441extern void release_session_client(struct nfsd4_session *);
442
443static inline void
444nfs4_put_stateowner(struct nfs4_stateowner *so)
445{
446	kref_put(&so->so_ref, nfs4_free_stateowner);
447}
448
449static inline void
450nfs4_get_stateowner(struct nfs4_stateowner *so)
451{
452	kref_get(&so->so_ref);
453}
454
455#endif   /* NFSD4_STATE_H */
456