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