xref: /OK3568_Linux_fs/kernel/fs/nfsd/xdr4.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  *  Server-side types for NFSv4.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  *  Copyright (c) 2002 The Regents of the University of Michigan.
5*4882a593Smuzhiyun  *  All rights reserved.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  *  Kendrick Smith <kmsmith@umich.edu>
8*4882a593Smuzhiyun  *  Andy Adamson   <andros@umich.edu>
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  *  Redistribution and use in source and binary forms, with or without
11*4882a593Smuzhiyun  *  modification, are permitted provided that the following conditions
12*4882a593Smuzhiyun  *  are met:
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *  1. Redistributions of source code must retain the above copyright
15*4882a593Smuzhiyun  *     notice, this list of conditions and the following disclaimer.
16*4882a593Smuzhiyun  *  2. Redistributions in binary form must reproduce the above copyright
17*4882a593Smuzhiyun  *     notice, this list of conditions and the following disclaimer in the
18*4882a593Smuzhiyun  *     documentation and/or other materials provided with the distribution.
19*4882a593Smuzhiyun  *  3. Neither the name of the University nor the names of its
20*4882a593Smuzhiyun  *     contributors may be used to endorse or promote products derived
21*4882a593Smuzhiyun  *     from this software without specific prior written permission.
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
24*4882a593Smuzhiyun  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25*4882a593Smuzhiyun  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26*4882a593Smuzhiyun  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27*4882a593Smuzhiyun  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28*4882a593Smuzhiyun  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29*4882a593Smuzhiyun  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30*4882a593Smuzhiyun  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31*4882a593Smuzhiyun  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32*4882a593Smuzhiyun  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33*4882a593Smuzhiyun  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  */
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #ifndef _LINUX_NFSD_XDR4_H
38*4882a593Smuzhiyun #define _LINUX_NFSD_XDR4_H
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #include "state.h"
41*4882a593Smuzhiyun #include "nfsd.h"
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #define NFSD4_MAX_TAGLEN	128
44*4882a593Smuzhiyun #define XDR_LEN(n)                     (((n) + 3) & ~3)
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun #define CURRENT_STATE_ID_FLAG (1<<0)
47*4882a593Smuzhiyun #define SAVED_STATE_ID_FLAG (1<<1)
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define SET_CSTATE_FLAG(c, f) ((c)->sid_flags |= (f))
50*4882a593Smuzhiyun #define HAS_CSTATE_FLAG(c, f) ((c)->sid_flags & (f))
51*4882a593Smuzhiyun #define CLEAR_CSTATE_FLAG(c, f) ((c)->sid_flags &= ~(f))
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun struct nfsd4_compound_state {
54*4882a593Smuzhiyun 	struct svc_fh		current_fh;
55*4882a593Smuzhiyun 	struct svc_fh		save_fh;
56*4882a593Smuzhiyun 	struct nfs4_stateowner	*replay_owner;
57*4882a593Smuzhiyun 	struct nfs4_client	*clp;
58*4882a593Smuzhiyun 	/* For sessions DRC */
59*4882a593Smuzhiyun 	struct nfsd4_session	*session;
60*4882a593Smuzhiyun 	struct nfsd4_slot	*slot;
61*4882a593Smuzhiyun 	int			data_offset;
62*4882a593Smuzhiyun 	bool                    spo_must_allowed;
63*4882a593Smuzhiyun 	size_t			iovlen;
64*4882a593Smuzhiyun 	u32			minorversion;
65*4882a593Smuzhiyun 	__be32			status;
66*4882a593Smuzhiyun 	stateid_t	current_stateid;
67*4882a593Smuzhiyun 	stateid_t	save_stateid;
68*4882a593Smuzhiyun 	/* to indicate current and saved state id presents */
69*4882a593Smuzhiyun 	u32		sid_flags;
70*4882a593Smuzhiyun };
71*4882a593Smuzhiyun 
nfsd4_has_session(struct nfsd4_compound_state * cs)72*4882a593Smuzhiyun static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun 	return cs->slot != NULL;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun struct nfsd4_change_info {
78*4882a593Smuzhiyun 	u32		atomic;
79*4882a593Smuzhiyun 	bool		change_supported;
80*4882a593Smuzhiyun 	u32		before_ctime_sec;
81*4882a593Smuzhiyun 	u32		before_ctime_nsec;
82*4882a593Smuzhiyun 	u64		before_change;
83*4882a593Smuzhiyun 	u32		after_ctime_sec;
84*4882a593Smuzhiyun 	u32		after_ctime_nsec;
85*4882a593Smuzhiyun 	u64		after_change;
86*4882a593Smuzhiyun };
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun struct nfsd4_access {
89*4882a593Smuzhiyun 	u32		ac_req_access;      /* request */
90*4882a593Smuzhiyun 	u32		ac_supported;       /* response */
91*4882a593Smuzhiyun 	u32		ac_resp_access;     /* response */
92*4882a593Smuzhiyun };
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun struct nfsd4_close {
95*4882a593Smuzhiyun 	u32		cl_seqid;           /* request */
96*4882a593Smuzhiyun 	stateid_t	cl_stateid;         /* request+response */
97*4882a593Smuzhiyun };
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun struct nfsd4_commit {
100*4882a593Smuzhiyun 	u64		co_offset;          /* request */
101*4882a593Smuzhiyun 	u32		co_count;           /* request */
102*4882a593Smuzhiyun 	nfs4_verifier	co_verf;            /* response */
103*4882a593Smuzhiyun };
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun struct nfsd4_create {
106*4882a593Smuzhiyun 	u32		cr_namelen;         /* request */
107*4882a593Smuzhiyun 	char *		cr_name;            /* request */
108*4882a593Smuzhiyun 	u32		cr_type;            /* request */
109*4882a593Smuzhiyun 	union {                             /* request */
110*4882a593Smuzhiyun 		struct {
111*4882a593Smuzhiyun 			u32 datalen;
112*4882a593Smuzhiyun 			char *data;
113*4882a593Smuzhiyun 			struct kvec first;
114*4882a593Smuzhiyun 		} link;   /* NF4LNK */
115*4882a593Smuzhiyun 		struct {
116*4882a593Smuzhiyun 			u32 specdata1;
117*4882a593Smuzhiyun 			u32 specdata2;
118*4882a593Smuzhiyun 		} dev;    /* NF4BLK, NF4CHR */
119*4882a593Smuzhiyun 	} u;
120*4882a593Smuzhiyun 	u32		cr_bmval[3];        /* request */
121*4882a593Smuzhiyun 	struct iattr	cr_iattr;           /* request */
122*4882a593Smuzhiyun 	int		cr_umask;           /* request */
123*4882a593Smuzhiyun 	struct nfsd4_change_info  cr_cinfo; /* response */
124*4882a593Smuzhiyun 	struct nfs4_acl *cr_acl;
125*4882a593Smuzhiyun 	struct xdr_netobj cr_label;
126*4882a593Smuzhiyun };
127*4882a593Smuzhiyun #define cr_datalen	u.link.datalen
128*4882a593Smuzhiyun #define cr_data		u.link.data
129*4882a593Smuzhiyun #define cr_first	u.link.first
130*4882a593Smuzhiyun #define cr_specdata1	u.dev.specdata1
131*4882a593Smuzhiyun #define cr_specdata2	u.dev.specdata2
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun struct nfsd4_delegreturn {
134*4882a593Smuzhiyun 	stateid_t	dr_stateid;
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun struct nfsd4_getattr {
138*4882a593Smuzhiyun 	u32		ga_bmval[3];        /* request */
139*4882a593Smuzhiyun 	struct svc_fh	*ga_fhp;            /* response */
140*4882a593Smuzhiyun };
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun struct nfsd4_link {
143*4882a593Smuzhiyun 	u32		li_namelen;         /* request */
144*4882a593Smuzhiyun 	char *		li_name;            /* request */
145*4882a593Smuzhiyun 	struct nfsd4_change_info  li_cinfo; /* response */
146*4882a593Smuzhiyun };
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun struct nfsd4_lock_denied {
149*4882a593Smuzhiyun 	clientid_t	ld_clientid;
150*4882a593Smuzhiyun 	struct xdr_netobj	ld_owner;
151*4882a593Smuzhiyun 	u64             ld_start;
152*4882a593Smuzhiyun 	u64             ld_length;
153*4882a593Smuzhiyun 	u32             ld_type;
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun struct nfsd4_lock {
157*4882a593Smuzhiyun 	/* request */
158*4882a593Smuzhiyun 	u32             lk_type;
159*4882a593Smuzhiyun 	u32             lk_reclaim;         /* boolean */
160*4882a593Smuzhiyun 	u64             lk_offset;
161*4882a593Smuzhiyun 	u64             lk_length;
162*4882a593Smuzhiyun 	u32             lk_is_new;
163*4882a593Smuzhiyun 	union {
164*4882a593Smuzhiyun 		struct {
165*4882a593Smuzhiyun 			u32             open_seqid;
166*4882a593Smuzhiyun 			stateid_t       open_stateid;
167*4882a593Smuzhiyun 			u32             lock_seqid;
168*4882a593Smuzhiyun 			clientid_t      clientid;
169*4882a593Smuzhiyun 			struct xdr_netobj owner;
170*4882a593Smuzhiyun 		} new;
171*4882a593Smuzhiyun 		struct {
172*4882a593Smuzhiyun 			stateid_t       lock_stateid;
173*4882a593Smuzhiyun 			u32             lock_seqid;
174*4882a593Smuzhiyun 		} old;
175*4882a593Smuzhiyun 	} v;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	/* response */
178*4882a593Smuzhiyun 	union {
179*4882a593Smuzhiyun 		struct {
180*4882a593Smuzhiyun 			stateid_t               stateid;
181*4882a593Smuzhiyun 		} ok;
182*4882a593Smuzhiyun 		struct nfsd4_lock_denied        denied;
183*4882a593Smuzhiyun 	} u;
184*4882a593Smuzhiyun };
185*4882a593Smuzhiyun #define lk_new_open_seqid       v.new.open_seqid
186*4882a593Smuzhiyun #define lk_new_open_stateid     v.new.open_stateid
187*4882a593Smuzhiyun #define lk_new_lock_seqid       v.new.lock_seqid
188*4882a593Smuzhiyun #define lk_new_clientid         v.new.clientid
189*4882a593Smuzhiyun #define lk_new_owner            v.new.owner
190*4882a593Smuzhiyun #define lk_old_lock_stateid     v.old.lock_stateid
191*4882a593Smuzhiyun #define lk_old_lock_seqid       v.old.lock_seqid
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun #define lk_resp_stateid u.ok.stateid
194*4882a593Smuzhiyun #define lk_denied       u.denied
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun struct nfsd4_lockt {
198*4882a593Smuzhiyun 	u32				lt_type;
199*4882a593Smuzhiyun 	clientid_t			lt_clientid;
200*4882a593Smuzhiyun 	struct xdr_netobj		lt_owner;
201*4882a593Smuzhiyun 	u64				lt_offset;
202*4882a593Smuzhiyun 	u64				lt_length;
203*4882a593Smuzhiyun 	struct nfsd4_lock_denied  	lt_denied;
204*4882a593Smuzhiyun };
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun struct nfsd4_locku {
208*4882a593Smuzhiyun 	u32             lu_type;
209*4882a593Smuzhiyun 	u32             lu_seqid;
210*4882a593Smuzhiyun 	stateid_t       lu_stateid;
211*4882a593Smuzhiyun 	u64             lu_offset;
212*4882a593Smuzhiyun 	u64             lu_length;
213*4882a593Smuzhiyun };
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun struct nfsd4_lookup {
217*4882a593Smuzhiyun 	u32		lo_len;             /* request */
218*4882a593Smuzhiyun 	char *		lo_name;            /* request */
219*4882a593Smuzhiyun };
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun struct nfsd4_putfh {
222*4882a593Smuzhiyun 	u32		pf_fhlen;           /* request */
223*4882a593Smuzhiyun 	char		*pf_fhval;          /* request */
224*4882a593Smuzhiyun 	bool		no_verify;	    /* represents foreigh fh */
225*4882a593Smuzhiyun };
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun struct nfsd4_getxattr {
228*4882a593Smuzhiyun 	char		*getxa_name;		/* request */
229*4882a593Smuzhiyun 	u32		getxa_len;		/* request */
230*4882a593Smuzhiyun 	void		*getxa_buf;
231*4882a593Smuzhiyun };
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun struct nfsd4_setxattr {
234*4882a593Smuzhiyun 	u32		setxa_flags;		/* request */
235*4882a593Smuzhiyun 	char		*setxa_name;		/* request */
236*4882a593Smuzhiyun 	char		*setxa_buf;		/* request */
237*4882a593Smuzhiyun 	u32		setxa_len;		/* request */
238*4882a593Smuzhiyun 	struct nfsd4_change_info  setxa_cinfo;	/* response */
239*4882a593Smuzhiyun };
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun struct nfsd4_removexattr {
242*4882a593Smuzhiyun 	char		*rmxa_name;		/* request */
243*4882a593Smuzhiyun 	struct nfsd4_change_info  rmxa_cinfo;	/* response */
244*4882a593Smuzhiyun };
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun struct nfsd4_listxattrs {
247*4882a593Smuzhiyun 	u64		lsxa_cookie;		/* request */
248*4882a593Smuzhiyun 	u32		lsxa_maxcount;		/* request */
249*4882a593Smuzhiyun 	char		*lsxa_buf;		/* unfiltered buffer (reply) */
250*4882a593Smuzhiyun 	u32		lsxa_len;		/* unfiltered len (reply) */
251*4882a593Smuzhiyun };
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun struct nfsd4_open {
254*4882a593Smuzhiyun 	u32		op_claim_type;      /* request */
255*4882a593Smuzhiyun 	struct xdr_netobj op_fname;	    /* request - everything but CLAIM_PREV */
256*4882a593Smuzhiyun 	u32		op_delegate_type;   /* request - CLAIM_PREV only */
257*4882a593Smuzhiyun 	stateid_t       op_delegate_stateid; /* request - response */
258*4882a593Smuzhiyun 	u32		op_why_no_deleg;    /* response - DELEG_NONE_EXT only */
259*4882a593Smuzhiyun 	u32		op_create;     	    /* request */
260*4882a593Smuzhiyun 	u32		op_createmode;      /* request */
261*4882a593Smuzhiyun 	int		op_umask;           /* request */
262*4882a593Smuzhiyun 	u32		op_bmval[3];        /* request */
263*4882a593Smuzhiyun 	struct iattr	op_iattr;           /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
264*4882a593Smuzhiyun 	nfs4_verifier	op_verf __attribute__((aligned(32)));
265*4882a593Smuzhiyun 					    /* EXCLUSIVE4 */
266*4882a593Smuzhiyun 	clientid_t	op_clientid;        /* request */
267*4882a593Smuzhiyun 	struct xdr_netobj op_owner;           /* request */
268*4882a593Smuzhiyun 	u32		op_seqid;           /* request */
269*4882a593Smuzhiyun 	u32		op_share_access;    /* request */
270*4882a593Smuzhiyun 	u32		op_share_deny;      /* request */
271*4882a593Smuzhiyun 	u32		op_deleg_want;      /* request */
272*4882a593Smuzhiyun 	stateid_t	op_stateid;         /* response */
273*4882a593Smuzhiyun 	__be32		op_xdr_error;       /* see nfsd4_open_omfg() */
274*4882a593Smuzhiyun 	u32		op_recall;          /* recall */
275*4882a593Smuzhiyun 	struct nfsd4_change_info  op_cinfo; /* response */
276*4882a593Smuzhiyun 	u32		op_rflags;          /* response */
277*4882a593Smuzhiyun 	bool		op_truncate;        /* used during processing */
278*4882a593Smuzhiyun 	bool		op_created;         /* used during processing */
279*4882a593Smuzhiyun 	struct nfs4_openowner *op_openowner; /* used during processing */
280*4882a593Smuzhiyun 	struct nfs4_file *op_file;          /* used during processing */
281*4882a593Smuzhiyun 	struct nfs4_ol_stateid *op_stp;	    /* used during processing */
282*4882a593Smuzhiyun 	struct nfs4_clnt_odstate *op_odstate; /* used during processing */
283*4882a593Smuzhiyun 	struct nfs4_acl *op_acl;
284*4882a593Smuzhiyun 	struct xdr_netobj op_label;
285*4882a593Smuzhiyun };
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun struct nfsd4_open_confirm {
288*4882a593Smuzhiyun 	stateid_t	oc_req_stateid		/* request */;
289*4882a593Smuzhiyun 	u32		oc_seqid    		/* request */;
290*4882a593Smuzhiyun 	stateid_t	oc_resp_stateid		/* response */;
291*4882a593Smuzhiyun };
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun struct nfsd4_open_downgrade {
294*4882a593Smuzhiyun 	stateid_t       od_stateid;
295*4882a593Smuzhiyun 	u32             od_seqid;
296*4882a593Smuzhiyun 	u32             od_share_access;	/* request */
297*4882a593Smuzhiyun 	u32		od_deleg_want;		/* request */
298*4882a593Smuzhiyun 	u32             od_share_deny;		/* request */
299*4882a593Smuzhiyun };
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun struct nfsd4_read {
303*4882a593Smuzhiyun 	stateid_t		rd_stateid;         /* request */
304*4882a593Smuzhiyun 	u64			rd_offset;          /* request */
305*4882a593Smuzhiyun 	u32			rd_length;          /* request */
306*4882a593Smuzhiyun 	int			rd_vlen;
307*4882a593Smuzhiyun 	struct nfsd_file	*rd_nf;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	struct svc_rqst		*rd_rqstp;          /* response */
310*4882a593Smuzhiyun 	struct svc_fh		*rd_fhp;             /* response */
311*4882a593Smuzhiyun };
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun struct nfsd4_readdir {
314*4882a593Smuzhiyun 	u64		rd_cookie;          /* request */
315*4882a593Smuzhiyun 	nfs4_verifier	rd_verf;            /* request */
316*4882a593Smuzhiyun 	u32		rd_dircount;        /* request */
317*4882a593Smuzhiyun 	u32		rd_maxcount;        /* request */
318*4882a593Smuzhiyun 	u32		rd_bmval[3];        /* request */
319*4882a593Smuzhiyun 	struct svc_rqst *rd_rqstp;          /* response */
320*4882a593Smuzhiyun 	struct svc_fh * rd_fhp;             /* response */
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	struct readdir_cd	common;
323*4882a593Smuzhiyun 	struct xdr_stream	*xdr;
324*4882a593Smuzhiyun 	int			cookie_offset;
325*4882a593Smuzhiyun };
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun struct nfsd4_release_lockowner {
328*4882a593Smuzhiyun 	clientid_t        rl_clientid;
329*4882a593Smuzhiyun 	struct xdr_netobj rl_owner;
330*4882a593Smuzhiyun };
331*4882a593Smuzhiyun struct nfsd4_readlink {
332*4882a593Smuzhiyun 	struct svc_rqst *rl_rqstp;          /* request */
333*4882a593Smuzhiyun 	struct svc_fh *	rl_fhp;             /* request */
334*4882a593Smuzhiyun };
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun struct nfsd4_remove {
337*4882a593Smuzhiyun 	u32		rm_namelen;         /* request */
338*4882a593Smuzhiyun 	char *		rm_name;            /* request */
339*4882a593Smuzhiyun 	struct nfsd4_change_info  rm_cinfo; /* response */
340*4882a593Smuzhiyun };
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun struct nfsd4_rename {
343*4882a593Smuzhiyun 	u32		rn_snamelen;        /* request */
344*4882a593Smuzhiyun 	char *		rn_sname;           /* request */
345*4882a593Smuzhiyun 	u32		rn_tnamelen;        /* request */
346*4882a593Smuzhiyun 	char *		rn_tname;           /* request */
347*4882a593Smuzhiyun 	struct nfsd4_change_info  rn_sinfo; /* response */
348*4882a593Smuzhiyun 	struct nfsd4_change_info  rn_tinfo; /* response */
349*4882a593Smuzhiyun };
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun struct nfsd4_secinfo {
352*4882a593Smuzhiyun 	u32 si_namelen;					/* request */
353*4882a593Smuzhiyun 	char *si_name;					/* request */
354*4882a593Smuzhiyun 	struct svc_export *si_exp;			/* response */
355*4882a593Smuzhiyun };
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun struct nfsd4_secinfo_no_name {
358*4882a593Smuzhiyun 	u32 sin_style;					/* request */
359*4882a593Smuzhiyun 	struct svc_export *sin_exp;			/* response */
360*4882a593Smuzhiyun };
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun struct nfsd4_setattr {
363*4882a593Smuzhiyun 	stateid_t	sa_stateid;         /* request */
364*4882a593Smuzhiyun 	u32		sa_bmval[3];        /* request */
365*4882a593Smuzhiyun 	struct iattr	sa_iattr;           /* request */
366*4882a593Smuzhiyun 	struct nfs4_acl *sa_acl;
367*4882a593Smuzhiyun 	struct xdr_netobj sa_label;
368*4882a593Smuzhiyun };
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun struct nfsd4_setclientid {
371*4882a593Smuzhiyun 	nfs4_verifier	se_verf;            /* request */
372*4882a593Smuzhiyun 	struct xdr_netobj se_name;
373*4882a593Smuzhiyun 	u32		se_callback_prog;   /* request */
374*4882a593Smuzhiyun 	u32		se_callback_netid_len;  /* request */
375*4882a593Smuzhiyun 	char *		se_callback_netid_val;  /* request */
376*4882a593Smuzhiyun 	u32		se_callback_addr_len;   /* request */
377*4882a593Smuzhiyun 	char *		se_callback_addr_val;   /* request */
378*4882a593Smuzhiyun 	u32		se_callback_ident;  /* request */
379*4882a593Smuzhiyun 	clientid_t	se_clientid;        /* response */
380*4882a593Smuzhiyun 	nfs4_verifier	se_confirm;         /* response */
381*4882a593Smuzhiyun };
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun struct nfsd4_setclientid_confirm {
384*4882a593Smuzhiyun 	clientid_t	sc_clientid;
385*4882a593Smuzhiyun 	nfs4_verifier	sc_confirm;
386*4882a593Smuzhiyun };
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun struct nfsd4_saved_compoundargs {
389*4882a593Smuzhiyun 	__be32 *p;
390*4882a593Smuzhiyun 	__be32 *end;
391*4882a593Smuzhiyun 	int pagelen;
392*4882a593Smuzhiyun 	struct page **pagelist;
393*4882a593Smuzhiyun };
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun struct nfsd4_test_stateid_id {
396*4882a593Smuzhiyun 	__be32			ts_id_status;
397*4882a593Smuzhiyun 	stateid_t		ts_id_stateid;
398*4882a593Smuzhiyun 	struct list_head	ts_id_list;
399*4882a593Smuzhiyun };
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun struct nfsd4_test_stateid {
402*4882a593Smuzhiyun 	u32		ts_num_ids;
403*4882a593Smuzhiyun 	struct list_head ts_stateid_list;
404*4882a593Smuzhiyun };
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun struct nfsd4_free_stateid {
407*4882a593Smuzhiyun 	stateid_t	fr_stateid;         /* request */
408*4882a593Smuzhiyun };
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun /* also used for NVERIFY */
411*4882a593Smuzhiyun struct nfsd4_verify {
412*4882a593Smuzhiyun 	u32		ve_bmval[3];        /* request */
413*4882a593Smuzhiyun 	u32		ve_attrlen;         /* request */
414*4882a593Smuzhiyun 	char *		ve_attrval;         /* request */
415*4882a593Smuzhiyun };
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun struct nfsd4_write {
418*4882a593Smuzhiyun 	stateid_t	wr_stateid;         /* request */
419*4882a593Smuzhiyun 	u64		wr_offset;          /* request */
420*4882a593Smuzhiyun 	u32		wr_stable_how;      /* request */
421*4882a593Smuzhiyun 	u32		wr_buflen;          /* request */
422*4882a593Smuzhiyun 	struct kvec	wr_head;
423*4882a593Smuzhiyun 	struct page **	wr_pagelist;        /* request */
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	u32		wr_bytes_written;   /* response */
426*4882a593Smuzhiyun 	u32		wr_how_written;     /* response */
427*4882a593Smuzhiyun 	nfs4_verifier	wr_verifier;        /* response */
428*4882a593Smuzhiyun };
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun struct nfsd4_exchange_id {
431*4882a593Smuzhiyun 	nfs4_verifier	verifier;
432*4882a593Smuzhiyun 	struct xdr_netobj clname;
433*4882a593Smuzhiyun 	u32		flags;
434*4882a593Smuzhiyun 	clientid_t	clientid;
435*4882a593Smuzhiyun 	u32		seqid;
436*4882a593Smuzhiyun 	int		spa_how;
437*4882a593Smuzhiyun 	u32             spo_must_enforce[3];
438*4882a593Smuzhiyun 	u32             spo_must_allow[3];
439*4882a593Smuzhiyun 	struct xdr_netobj nii_domain;
440*4882a593Smuzhiyun 	struct xdr_netobj nii_name;
441*4882a593Smuzhiyun 	struct timespec64 nii_time;
442*4882a593Smuzhiyun };
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun struct nfsd4_sequence {
445*4882a593Smuzhiyun 	struct nfs4_sessionid	sessionid;		/* request/response */
446*4882a593Smuzhiyun 	u32			seqid;			/* request/response */
447*4882a593Smuzhiyun 	u32			slotid;			/* request/response */
448*4882a593Smuzhiyun 	u32			maxslots;		/* request/response */
449*4882a593Smuzhiyun 	u32			cachethis;		/* request */
450*4882a593Smuzhiyun #if 0
451*4882a593Smuzhiyun 	u32			target_maxslots;	/* response */
452*4882a593Smuzhiyun #endif /* not yet */
453*4882a593Smuzhiyun 	u32			status_flags;		/* response */
454*4882a593Smuzhiyun };
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun struct nfsd4_destroy_session {
457*4882a593Smuzhiyun 	struct nfs4_sessionid	sessionid;
458*4882a593Smuzhiyun };
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun struct nfsd4_destroy_clientid {
461*4882a593Smuzhiyun 	clientid_t clientid;
462*4882a593Smuzhiyun };
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun struct nfsd4_reclaim_complete {
465*4882a593Smuzhiyun 	u32 rca_one_fs;
466*4882a593Smuzhiyun };
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun struct nfsd4_deviceid {
469*4882a593Smuzhiyun 	u64			fsid_idx;
470*4882a593Smuzhiyun 	u32			generation;
471*4882a593Smuzhiyun 	u32			pad;
472*4882a593Smuzhiyun };
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun struct nfsd4_layout_seg {
475*4882a593Smuzhiyun 	u32			iomode;
476*4882a593Smuzhiyun 	u64			offset;
477*4882a593Smuzhiyun 	u64			length;
478*4882a593Smuzhiyun };
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun struct nfsd4_getdeviceinfo {
481*4882a593Smuzhiyun 	struct nfsd4_deviceid	gd_devid;	/* request */
482*4882a593Smuzhiyun 	u32			gd_layout_type;	/* request */
483*4882a593Smuzhiyun 	u32			gd_maxcount;	/* request */
484*4882a593Smuzhiyun 	u32			gd_notify_types;/* request - response */
485*4882a593Smuzhiyun 	void			*gd_device;	/* response */
486*4882a593Smuzhiyun };
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun struct nfsd4_layoutget {
489*4882a593Smuzhiyun 	u64			lg_minlength;	/* request */
490*4882a593Smuzhiyun 	u32			lg_signal;	/* request */
491*4882a593Smuzhiyun 	u32			lg_layout_type;	/* request */
492*4882a593Smuzhiyun 	u32			lg_maxcount;	/* request */
493*4882a593Smuzhiyun 	stateid_t		lg_sid;		/* request/response */
494*4882a593Smuzhiyun 	struct nfsd4_layout_seg	lg_seg;		/* request/response */
495*4882a593Smuzhiyun 	void			*lg_content;	/* response */
496*4882a593Smuzhiyun };
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun struct nfsd4_layoutcommit {
499*4882a593Smuzhiyun 	stateid_t		lc_sid;		/* request */
500*4882a593Smuzhiyun 	struct nfsd4_layout_seg	lc_seg;		/* request */
501*4882a593Smuzhiyun 	u32			lc_reclaim;	/* request */
502*4882a593Smuzhiyun 	u32			lc_newoffset;	/* request */
503*4882a593Smuzhiyun 	u64			lc_last_wr;	/* request */
504*4882a593Smuzhiyun 	struct timespec64	lc_mtime;	/* request */
505*4882a593Smuzhiyun 	u32			lc_layout_type;	/* request */
506*4882a593Smuzhiyun 	u32			lc_up_len;	/* layout length */
507*4882a593Smuzhiyun 	void			*lc_up_layout;	/* decoded by callback */
508*4882a593Smuzhiyun 	u32			lc_size_chg;	/* boolean for response */
509*4882a593Smuzhiyun 	u64			lc_newsize;	/* response */
510*4882a593Smuzhiyun };
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun struct nfsd4_layoutreturn {
513*4882a593Smuzhiyun 	u32			lr_return_type;	/* request */
514*4882a593Smuzhiyun 	u32			lr_layout_type;	/* request */
515*4882a593Smuzhiyun 	struct nfsd4_layout_seg	lr_seg;		/* request */
516*4882a593Smuzhiyun 	u32			lr_reclaim;	/* request */
517*4882a593Smuzhiyun 	u32			lrf_body_len;	/* request */
518*4882a593Smuzhiyun 	void			*lrf_body;	/* request */
519*4882a593Smuzhiyun 	stateid_t		lr_sid;		/* request/response */
520*4882a593Smuzhiyun 	u32			lrs_present;	/* response */
521*4882a593Smuzhiyun };
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun struct nfsd4_fallocate {
524*4882a593Smuzhiyun 	/* request */
525*4882a593Smuzhiyun 	stateid_t	falloc_stateid;
526*4882a593Smuzhiyun 	loff_t		falloc_offset;
527*4882a593Smuzhiyun 	u64		falloc_length;
528*4882a593Smuzhiyun };
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun struct nfsd4_clone {
531*4882a593Smuzhiyun 	/* request */
532*4882a593Smuzhiyun 	stateid_t	cl_src_stateid;
533*4882a593Smuzhiyun 	stateid_t	cl_dst_stateid;
534*4882a593Smuzhiyun 	u64		cl_src_pos;
535*4882a593Smuzhiyun 	u64		cl_dst_pos;
536*4882a593Smuzhiyun 	u64		cl_count;
537*4882a593Smuzhiyun };
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun struct nfsd42_write_res {
540*4882a593Smuzhiyun 	u64			wr_bytes_written;
541*4882a593Smuzhiyun 	u32			wr_stable_how;
542*4882a593Smuzhiyun 	nfs4_verifier		wr_verifier;
543*4882a593Smuzhiyun 	stateid_t		cb_stateid;
544*4882a593Smuzhiyun };
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun struct nfsd4_copy {
547*4882a593Smuzhiyun 	/* request */
548*4882a593Smuzhiyun 	stateid_t		cp_src_stateid;
549*4882a593Smuzhiyun 	stateid_t		cp_dst_stateid;
550*4882a593Smuzhiyun 	u64			cp_src_pos;
551*4882a593Smuzhiyun 	u64			cp_dst_pos;
552*4882a593Smuzhiyun 	u64			cp_count;
553*4882a593Smuzhiyun 	struct nl4_server	cp_src;
554*4882a593Smuzhiyun 	bool			cp_intra;
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	/* both */
557*4882a593Smuzhiyun 	bool		cp_synchronous;
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 	/* response */
560*4882a593Smuzhiyun 	struct nfsd42_write_res	cp_res;
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 	/* for cb_offload */
563*4882a593Smuzhiyun 	struct nfsd4_callback	cp_cb;
564*4882a593Smuzhiyun 	__be32			nfserr;
565*4882a593Smuzhiyun 	struct knfsd_fh		fh;
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun 	struct nfs4_client      *cp_clp;
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	struct nfsd_file        *nf_src;
570*4882a593Smuzhiyun 	struct nfsd_file        *nf_dst;
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	copy_stateid_t		cp_stateid;
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 	struct list_head	copies;
575*4882a593Smuzhiyun 	struct task_struct	*copy_task;
576*4882a593Smuzhiyun 	refcount_t		refcount;
577*4882a593Smuzhiyun 	bool			stopped;
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	struct vfsmount		*ss_mnt;
580*4882a593Smuzhiyun 	struct nfs_fh		c_fh;
581*4882a593Smuzhiyun 	nfs4_stateid		stateid;
582*4882a593Smuzhiyun };
583*4882a593Smuzhiyun extern bool inter_copy_offload_enable;
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun struct nfsd4_seek {
586*4882a593Smuzhiyun 	/* request */
587*4882a593Smuzhiyun 	stateid_t	seek_stateid;
588*4882a593Smuzhiyun 	loff_t		seek_offset;
589*4882a593Smuzhiyun 	u32		seek_whence;
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	/* response */
592*4882a593Smuzhiyun 	u32		seek_eof;
593*4882a593Smuzhiyun 	loff_t		seek_pos;
594*4882a593Smuzhiyun };
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun struct nfsd4_offload_status {
597*4882a593Smuzhiyun 	/* request */
598*4882a593Smuzhiyun 	stateid_t	stateid;
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun 	/* response */
601*4882a593Smuzhiyun 	u64		count;
602*4882a593Smuzhiyun 	u32		status;
603*4882a593Smuzhiyun };
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun struct nfsd4_copy_notify {
606*4882a593Smuzhiyun 	/* request */
607*4882a593Smuzhiyun 	stateid_t		cpn_src_stateid;
608*4882a593Smuzhiyun 	struct nl4_server	cpn_dst;
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	/* response */
611*4882a593Smuzhiyun 	stateid_t		cpn_cnr_stateid;
612*4882a593Smuzhiyun 	u64			cpn_sec;
613*4882a593Smuzhiyun 	u32			cpn_nsec;
614*4882a593Smuzhiyun 	struct nl4_server	cpn_src;
615*4882a593Smuzhiyun };
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun struct nfsd4_op {
618*4882a593Smuzhiyun 	int					opnum;
619*4882a593Smuzhiyun 	const struct nfsd4_operation *		opdesc;
620*4882a593Smuzhiyun 	__be32					status;
621*4882a593Smuzhiyun 	union nfsd4_op_u {
622*4882a593Smuzhiyun 		struct nfsd4_access		access;
623*4882a593Smuzhiyun 		struct nfsd4_close		close;
624*4882a593Smuzhiyun 		struct nfsd4_commit		commit;
625*4882a593Smuzhiyun 		struct nfsd4_create		create;
626*4882a593Smuzhiyun 		struct nfsd4_delegreturn	delegreturn;
627*4882a593Smuzhiyun 		struct nfsd4_getattr		getattr;
628*4882a593Smuzhiyun 		struct svc_fh *			getfh;
629*4882a593Smuzhiyun 		struct nfsd4_link		link;
630*4882a593Smuzhiyun 		struct nfsd4_lock		lock;
631*4882a593Smuzhiyun 		struct nfsd4_lockt		lockt;
632*4882a593Smuzhiyun 		struct nfsd4_locku		locku;
633*4882a593Smuzhiyun 		struct nfsd4_lookup		lookup;
634*4882a593Smuzhiyun 		struct nfsd4_verify		nverify;
635*4882a593Smuzhiyun 		struct nfsd4_open		open;
636*4882a593Smuzhiyun 		struct nfsd4_open_confirm	open_confirm;
637*4882a593Smuzhiyun 		struct nfsd4_open_downgrade	open_downgrade;
638*4882a593Smuzhiyun 		struct nfsd4_putfh		putfh;
639*4882a593Smuzhiyun 		struct nfsd4_read		read;
640*4882a593Smuzhiyun 		struct nfsd4_readdir		readdir;
641*4882a593Smuzhiyun 		struct nfsd4_readlink		readlink;
642*4882a593Smuzhiyun 		struct nfsd4_remove		remove;
643*4882a593Smuzhiyun 		struct nfsd4_rename		rename;
644*4882a593Smuzhiyun 		clientid_t			renew;
645*4882a593Smuzhiyun 		struct nfsd4_secinfo		secinfo;
646*4882a593Smuzhiyun 		struct nfsd4_setattr		setattr;
647*4882a593Smuzhiyun 		struct nfsd4_setclientid	setclientid;
648*4882a593Smuzhiyun 		struct nfsd4_setclientid_confirm setclientid_confirm;
649*4882a593Smuzhiyun 		struct nfsd4_verify		verify;
650*4882a593Smuzhiyun 		struct nfsd4_write		write;
651*4882a593Smuzhiyun 		struct nfsd4_release_lockowner	release_lockowner;
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 		/* NFSv4.1 */
654*4882a593Smuzhiyun 		struct nfsd4_exchange_id	exchange_id;
655*4882a593Smuzhiyun 		struct nfsd4_backchannel_ctl	backchannel_ctl;
656*4882a593Smuzhiyun 		struct nfsd4_bind_conn_to_session bind_conn_to_session;
657*4882a593Smuzhiyun 		struct nfsd4_create_session	create_session;
658*4882a593Smuzhiyun 		struct nfsd4_destroy_session	destroy_session;
659*4882a593Smuzhiyun 		struct nfsd4_destroy_clientid	destroy_clientid;
660*4882a593Smuzhiyun 		struct nfsd4_sequence		sequence;
661*4882a593Smuzhiyun 		struct nfsd4_reclaim_complete	reclaim_complete;
662*4882a593Smuzhiyun 		struct nfsd4_test_stateid	test_stateid;
663*4882a593Smuzhiyun 		struct nfsd4_free_stateid	free_stateid;
664*4882a593Smuzhiyun 		struct nfsd4_getdeviceinfo	getdeviceinfo;
665*4882a593Smuzhiyun 		struct nfsd4_layoutget		layoutget;
666*4882a593Smuzhiyun 		struct nfsd4_layoutcommit	layoutcommit;
667*4882a593Smuzhiyun 		struct nfsd4_layoutreturn	layoutreturn;
668*4882a593Smuzhiyun 		struct nfsd4_secinfo_no_name	secinfo_no_name;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 		/* NFSv4.2 */
671*4882a593Smuzhiyun 		struct nfsd4_fallocate		allocate;
672*4882a593Smuzhiyun 		struct nfsd4_fallocate		deallocate;
673*4882a593Smuzhiyun 		struct nfsd4_clone		clone;
674*4882a593Smuzhiyun 		struct nfsd4_copy		copy;
675*4882a593Smuzhiyun 		struct nfsd4_offload_status	offload_status;
676*4882a593Smuzhiyun 		struct nfsd4_copy_notify	copy_notify;
677*4882a593Smuzhiyun 		struct nfsd4_seek		seek;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 		struct nfsd4_getxattr		getxattr;
680*4882a593Smuzhiyun 		struct nfsd4_setxattr		setxattr;
681*4882a593Smuzhiyun 		struct nfsd4_listxattrs		listxattrs;
682*4882a593Smuzhiyun 		struct nfsd4_removexattr	removexattr;
683*4882a593Smuzhiyun 	} u;
684*4882a593Smuzhiyun 	struct nfs4_replay *			replay;
685*4882a593Smuzhiyun };
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun bool nfsd4_cache_this_op(struct nfsd4_op *);
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun /*
690*4882a593Smuzhiyun  * Memory needed just for the duration of processing one compound:
691*4882a593Smuzhiyun  */
692*4882a593Smuzhiyun struct svcxdr_tmpbuf {
693*4882a593Smuzhiyun 	struct svcxdr_tmpbuf *next;
694*4882a593Smuzhiyun 	char buf[];
695*4882a593Smuzhiyun };
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun struct nfsd4_compoundargs {
698*4882a593Smuzhiyun 	/* scratch variables for XDR decode */
699*4882a593Smuzhiyun 	__be32 *			p;
700*4882a593Smuzhiyun 	__be32 *			end;
701*4882a593Smuzhiyun 	struct page **			pagelist;
702*4882a593Smuzhiyun 	int				pagelen;
703*4882a593Smuzhiyun 	bool				tail;
704*4882a593Smuzhiyun 	__be32				tmp[8];
705*4882a593Smuzhiyun 	__be32 *			tmpp;
706*4882a593Smuzhiyun 	struct svcxdr_tmpbuf		*to_free;
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun 	struct svc_rqst			*rqstp;
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	u32				taglen;
711*4882a593Smuzhiyun 	char *				tag;
712*4882a593Smuzhiyun 	u32				minorversion;
713*4882a593Smuzhiyun 	u32				opcnt;
714*4882a593Smuzhiyun 	struct nfsd4_op			*ops;
715*4882a593Smuzhiyun 	struct nfsd4_op			iops[8];
716*4882a593Smuzhiyun 	int				cachetype;
717*4882a593Smuzhiyun };
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun struct nfsd4_compoundres {
720*4882a593Smuzhiyun 	/* scratch variables for XDR encode */
721*4882a593Smuzhiyun 	struct xdr_stream		xdr;
722*4882a593Smuzhiyun 	struct svc_rqst *		rqstp;
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 	u32				taglen;
725*4882a593Smuzhiyun 	char *				tag;
726*4882a593Smuzhiyun 	u32				opcnt;
727*4882a593Smuzhiyun 	__be32 *			tagp; /* tag, opcount encode location */
728*4882a593Smuzhiyun 	struct nfsd4_compound_state	cstate;
729*4882a593Smuzhiyun };
730*4882a593Smuzhiyun 
nfsd4_is_solo_sequence(struct nfsd4_compoundres * resp)731*4882a593Smuzhiyun static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp)
732*4882a593Smuzhiyun {
733*4882a593Smuzhiyun 	struct nfsd4_compoundargs *args = resp->rqstp->rq_argp;
734*4882a593Smuzhiyun 	return resp->opcnt == 1 && args->ops[0].opnum == OP_SEQUENCE;
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun /*
738*4882a593Smuzhiyun  * The session reply cache only needs to cache replies that the client
739*4882a593Smuzhiyun  * actually asked us to.  But it's almost free for us to cache compounds
740*4882a593Smuzhiyun  * consisting of only a SEQUENCE op, so we may as well cache those too.
741*4882a593Smuzhiyun  * Also, the protocol doesn't give us a convenient response in the case
742*4882a593Smuzhiyun  * of a replay of a solo SEQUENCE op that wasn't cached
743*4882a593Smuzhiyun  * (RETRY_UNCACHED_REP can only be returned in the second op of a
744*4882a593Smuzhiyun  * compound).
745*4882a593Smuzhiyun  */
nfsd4_cache_this(struct nfsd4_compoundres * resp)746*4882a593Smuzhiyun static inline bool nfsd4_cache_this(struct nfsd4_compoundres *resp)
747*4882a593Smuzhiyun {
748*4882a593Smuzhiyun 	return (resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS)
749*4882a593Smuzhiyun 		|| nfsd4_is_solo_sequence(resp);
750*4882a593Smuzhiyun }
751*4882a593Smuzhiyun 
nfsd4_last_compound_op(struct svc_rqst * rqstp)752*4882a593Smuzhiyun static inline bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
753*4882a593Smuzhiyun {
754*4882a593Smuzhiyun 	struct nfsd4_compoundres *resp = rqstp->rq_resp;
755*4882a593Smuzhiyun 	struct nfsd4_compoundargs *argp = rqstp->rq_argp;
756*4882a593Smuzhiyun 
757*4882a593Smuzhiyun 	return argp->opcnt == resp->opcnt;
758*4882a593Smuzhiyun }
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun const struct nfsd4_operation *OPDESC(struct nfsd4_op *op);
761*4882a593Smuzhiyun int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op);
762*4882a593Smuzhiyun void warn_on_nonidempotent_op(struct nfsd4_op *op);
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun #define NFS4_SVC_XDRSIZE		sizeof(struct nfsd4_compoundargs)
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun static inline void
set_change_info(struct nfsd4_change_info * cinfo,struct svc_fh * fhp)767*4882a593Smuzhiyun set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
768*4882a593Smuzhiyun {
769*4882a593Smuzhiyun 	BUG_ON(!fhp->fh_pre_saved);
770*4882a593Smuzhiyun 	cinfo->atomic = (u32)fhp->fh_post_saved;
771*4882a593Smuzhiyun 	cinfo->change_supported = IS_I_VERSION(d_inode(fhp->fh_dentry));
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun 	cinfo->before_change = fhp->fh_pre_change;
774*4882a593Smuzhiyun 	cinfo->after_change = fhp->fh_post_change;
775*4882a593Smuzhiyun 	cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
776*4882a593Smuzhiyun 	cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
777*4882a593Smuzhiyun 	cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
778*4882a593Smuzhiyun 	cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
779*4882a593Smuzhiyun 
780*4882a593Smuzhiyun }
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 
783*4882a593Smuzhiyun bool nfsd4_mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp);
784*4882a593Smuzhiyun int nfs4svc_decode_voidarg(struct svc_rqst *, __be32 *);
785*4882a593Smuzhiyun int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *);
786*4882a593Smuzhiyun int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *);
787*4882a593Smuzhiyun int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *);
788*4882a593Smuzhiyun __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);
789*4882a593Smuzhiyun void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
790*4882a593Smuzhiyun void nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op);
791*4882a593Smuzhiyun __be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
792*4882a593Smuzhiyun 		struct svc_fh *fhp, struct svc_export *exp,
793*4882a593Smuzhiyun 		struct dentry *dentry,
794*4882a593Smuzhiyun 		u32 *bmval, struct svc_rqst *, int ignore_crossmnt);
795*4882a593Smuzhiyun extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
796*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
797*4882a593Smuzhiyun extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
798*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
799*4882a593Smuzhiyun extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
800*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
801*4882a593Smuzhiyun extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *,
802*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
803*4882a593Smuzhiyun extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *,
804*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
805*4882a593Smuzhiyun extern __be32 nfsd4_create_session(struct svc_rqst *,
806*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
807*4882a593Smuzhiyun extern __be32 nfsd4_sequence(struct svc_rqst *,
808*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
809*4882a593Smuzhiyun extern void nfsd4_sequence_done(struct nfsd4_compoundres *resp);
810*4882a593Smuzhiyun extern __be32 nfsd4_destroy_session(struct svc_rqst *,
811*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
812*4882a593Smuzhiyun extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *,
813*4882a593Smuzhiyun 		union nfsd4_op_u *u);
814*4882a593Smuzhiyun __be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *,
815*4882a593Smuzhiyun 		union nfsd4_op_u *u);
816*4882a593Smuzhiyun extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
817*4882a593Smuzhiyun 		struct nfsd4_open *open, struct nfsd_net *nn);
818*4882a593Smuzhiyun extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
819*4882a593Smuzhiyun 		struct svc_fh *current_fh, struct nfsd4_open *open);
820*4882a593Smuzhiyun extern void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate);
821*4882a593Smuzhiyun extern void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
822*4882a593Smuzhiyun 		struct nfsd4_open *open);
823*4882a593Smuzhiyun extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
824*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
825*4882a593Smuzhiyun extern __be32 nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
826*4882a593Smuzhiyun 		union nfsd4_op_u *u);
827*4882a593Smuzhiyun extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp,
828*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
829*4882a593Smuzhiyun extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
830*4882a593Smuzhiyun 		union nfsd4_op_u *u);
831*4882a593Smuzhiyun extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
832*4882a593Smuzhiyun 		union nfsd4_op_u *u);
833*4882a593Smuzhiyun extern __be32 nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
834*4882a593Smuzhiyun 		union nfsd4_op_u *u);
835*4882a593Smuzhiyun extern __be32
836*4882a593Smuzhiyun nfsd4_release_lockowner(struct svc_rqst *rqstp,
837*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
838*4882a593Smuzhiyun extern void nfsd4_release_compoundargs(struct svc_rqst *rqstp);
839*4882a593Smuzhiyun extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp,
840*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
841*4882a593Smuzhiyun extern __be32 nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
842*4882a593Smuzhiyun 		union nfsd4_op_u *u);
843*4882a593Smuzhiyun extern __be32 nfsd4_test_stateid(struct svc_rqst *rqstp,
844*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *);
845*4882a593Smuzhiyun extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp,
846*4882a593Smuzhiyun 		struct nfsd4_compound_state *, union nfsd4_op_u *);
847*4882a593Smuzhiyun extern void nfsd4_bump_seqid(struct nfsd4_compound_state *, __be32 nfserr);
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun enum nfsd4_op_flags {
850*4882a593Smuzhiyun 	ALLOWED_WITHOUT_FH = 1 << 0,    /* No current filehandle required */
851*4882a593Smuzhiyun 	ALLOWED_ON_ABSENT_FS = 1 << 1,  /* ops processed on absent fs */
852*4882a593Smuzhiyun 	ALLOWED_AS_FIRST_OP = 1 << 2,   /* ops reqired first in compound */
853*4882a593Smuzhiyun 	/* For rfc 5661 section 2.6.3.1.1: */
854*4882a593Smuzhiyun 	OP_HANDLES_WRONGSEC = 1 << 3,
855*4882a593Smuzhiyun 	OP_IS_PUTFH_LIKE = 1 << 4,
856*4882a593Smuzhiyun 	/*
857*4882a593Smuzhiyun 	 * These are the ops whose result size we estimate before
858*4882a593Smuzhiyun 	 * encoding, to avoid performing an op then not being able to
859*4882a593Smuzhiyun 	 * respond or cache a response.  This includes writes and setattrs
860*4882a593Smuzhiyun 	 * as well as the operations usually called "nonidempotent":
861*4882a593Smuzhiyun 	 */
862*4882a593Smuzhiyun 	OP_MODIFIES_SOMETHING = 1 << 5,
863*4882a593Smuzhiyun 	/*
864*4882a593Smuzhiyun 	 * Cache compounds containing these ops in the xid-based drc:
865*4882a593Smuzhiyun 	 * We use the DRC for compounds containing non-idempotent
866*4882a593Smuzhiyun 	 * operations, *except* those that are 4.1-specific (since
867*4882a593Smuzhiyun 	 * sessions provide their own EOS), and except for stateful
868*4882a593Smuzhiyun 	 * operations other than setclientid and setclientid_confirm
869*4882a593Smuzhiyun 	 * (since sequence numbers provide EOS for open, lock, etc in
870*4882a593Smuzhiyun 	 * the v4.0 case).
871*4882a593Smuzhiyun 	 */
872*4882a593Smuzhiyun 	OP_CACHEME = 1 << 6,
873*4882a593Smuzhiyun 	/*
874*4882a593Smuzhiyun 	 * These are ops which clear current state id.
875*4882a593Smuzhiyun 	 */
876*4882a593Smuzhiyun 	OP_CLEAR_STATEID = 1 << 7,
877*4882a593Smuzhiyun 	/* Most ops return only an error on failure; some may do more: */
878*4882a593Smuzhiyun 	OP_NONTRIVIAL_ERROR_ENCODE = 1 << 8,
879*4882a593Smuzhiyun };
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun struct nfsd4_operation {
882*4882a593Smuzhiyun 	__be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
883*4882a593Smuzhiyun 			union nfsd4_op_u *);
884*4882a593Smuzhiyun 	void (*op_release)(union nfsd4_op_u *);
885*4882a593Smuzhiyun 	u32 op_flags;
886*4882a593Smuzhiyun 	char *op_name;
887*4882a593Smuzhiyun 	/* Try to get response size before operation */
888*4882a593Smuzhiyun 	u32 (*op_rsize_bop)(struct svc_rqst *, struct nfsd4_op *);
889*4882a593Smuzhiyun 	void (*op_get_currentstateid)(struct nfsd4_compound_state *,
890*4882a593Smuzhiyun 			union nfsd4_op_u *);
891*4882a593Smuzhiyun 	void (*op_set_currentstateid)(struct nfsd4_compound_state *,
892*4882a593Smuzhiyun 			union nfsd4_op_u *);
893*4882a593Smuzhiyun };
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun 
896*4882a593Smuzhiyun #endif
897*4882a593Smuzhiyun 
898*4882a593Smuzhiyun /*
899*4882a593Smuzhiyun  * Local variables:
900*4882a593Smuzhiyun  *  c-basic-offset: 8
901*4882a593Smuzhiyun  * End:
902*4882a593Smuzhiyun  */
903