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