xref: /openbmc/linux/fs/nfsd/xdr4.h (revision 880a3a53)
19a74af21SBoaz Harrosh /*
29a74af21SBoaz Harrosh  *  Server-side types for NFSv4.
39a74af21SBoaz Harrosh  *
49a74af21SBoaz Harrosh  *  Copyright (c) 2002 The Regents of the University of Michigan.
59a74af21SBoaz Harrosh  *  All rights reserved.
69a74af21SBoaz Harrosh  *
79a74af21SBoaz Harrosh  *  Kendrick Smith <kmsmith@umich.edu>
89a74af21SBoaz Harrosh  *  Andy Adamson   <andros@umich.edu>
99a74af21SBoaz Harrosh  *
109a74af21SBoaz Harrosh  *  Redistribution and use in source and binary forms, with or without
119a74af21SBoaz Harrosh  *  modification, are permitted provided that the following conditions
129a74af21SBoaz Harrosh  *  are met:
139a74af21SBoaz Harrosh  *
149a74af21SBoaz Harrosh  *  1. Redistributions of source code must retain the above copyright
159a74af21SBoaz Harrosh  *     notice, this list of conditions and the following disclaimer.
169a74af21SBoaz Harrosh  *  2. Redistributions in binary form must reproduce the above copyright
179a74af21SBoaz Harrosh  *     notice, this list of conditions and the following disclaimer in the
189a74af21SBoaz Harrosh  *     documentation and/or other materials provided with the distribution.
199a74af21SBoaz Harrosh  *  3. Neither the name of the University nor the names of its
209a74af21SBoaz Harrosh  *     contributors may be used to endorse or promote products derived
219a74af21SBoaz Harrosh  *     from this software without specific prior written permission.
229a74af21SBoaz Harrosh  *
239a74af21SBoaz Harrosh  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
249a74af21SBoaz Harrosh  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
259a74af21SBoaz Harrosh  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
269a74af21SBoaz Harrosh  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
279a74af21SBoaz Harrosh  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
289a74af21SBoaz Harrosh  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
299a74af21SBoaz Harrosh  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
309a74af21SBoaz Harrosh  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
319a74af21SBoaz Harrosh  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
329a74af21SBoaz Harrosh  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
339a74af21SBoaz Harrosh  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
349a74af21SBoaz Harrosh  *
359a74af21SBoaz Harrosh  */
369a74af21SBoaz Harrosh 
379a74af21SBoaz Harrosh #ifndef _LINUX_NFSD_XDR4_H
389a74af21SBoaz Harrosh #define _LINUX_NFSD_XDR4_H
399a74af21SBoaz Harrosh 
409a74af21SBoaz Harrosh #include "state.h"
419a74af21SBoaz Harrosh #include "nfsd.h"
429a74af21SBoaz Harrosh 
439a74af21SBoaz Harrosh #define NFSD4_MAX_TAGLEN	128
449a74af21SBoaz Harrosh #define XDR_LEN(n)                     (((n) + 3) & ~3)
459a74af21SBoaz Harrosh 
4637c593c5STigran Mkrtchyan #define CURRENT_STATE_ID_FLAG (1<<0)
4737c593c5STigran Mkrtchyan #define SAVED_STATE_ID_FLAG (1<<1)
4837c593c5STigran Mkrtchyan 
4937c593c5STigran Mkrtchyan #define SET_STATE_ID(c, f) ((c)->sid_flags |= (f))
5037c593c5STigran Mkrtchyan #define HAS_STATE_ID(c, f) ((c)->sid_flags & (f))
5137c593c5STigran Mkrtchyan #define CLEAR_STATE_ID(c, f) ((c)->sid_flags &= ~(f))
5237c593c5STigran Mkrtchyan 
539a74af21SBoaz Harrosh struct nfsd4_compound_state {
549a74af21SBoaz Harrosh 	struct svc_fh		current_fh;
559a74af21SBoaz Harrosh 	struct svc_fh		save_fh;
569a74af21SBoaz Harrosh 	struct nfs4_stateowner	*replay_owner;
574b24ca7dSJeff Layton 	struct nfs4_client	*clp;
589a74af21SBoaz Harrosh 	/* For sessions DRC */
599a74af21SBoaz Harrosh 	struct nfsd4_session	*session;
609a74af21SBoaz Harrosh 	struct nfsd4_slot	*slot;
61f5236013SJ. Bruce Fields 	int			data_offset;
62ed941643SAndrew Elble 	bool                    spo_must_allowed;
639a74af21SBoaz Harrosh 	size_t			iovlen;
649a74af21SBoaz Harrosh 	u32			minorversion;
6557b7b43bSJ. Bruce Fields 	__be32			status;
6637c593c5STigran Mkrtchyan 	stateid_t	current_stateid;
6737c593c5STigran Mkrtchyan 	stateid_t	save_stateid;
6837c593c5STigran Mkrtchyan 	/* to indicate current and saved state id presents */
6937c593c5STigran Mkrtchyan 	u32		sid_flags;
709a74af21SBoaz Harrosh };
719a74af21SBoaz Harrosh 
729a74af21SBoaz Harrosh static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
739a74af21SBoaz Harrosh {
749a74af21SBoaz Harrosh 	return cs->slot != NULL;
759a74af21SBoaz Harrosh }
769a74af21SBoaz Harrosh 
779a74af21SBoaz Harrosh struct nfsd4_change_info {
789a74af21SBoaz Harrosh 	u32		atomic;
799a74af21SBoaz Harrosh 	bool		change_supported;
809a74af21SBoaz Harrosh 	u32		before_ctime_sec;
819a74af21SBoaz Harrosh 	u32		before_ctime_nsec;
829a74af21SBoaz Harrosh 	u64		before_change;
839a74af21SBoaz Harrosh 	u32		after_ctime_sec;
849a74af21SBoaz Harrosh 	u32		after_ctime_nsec;
859a74af21SBoaz Harrosh 	u64		after_change;
869a74af21SBoaz Harrosh };
879a74af21SBoaz Harrosh 
889a74af21SBoaz Harrosh struct nfsd4_access {
899a74af21SBoaz Harrosh 	u32		ac_req_access;      /* request */
909a74af21SBoaz Harrosh 	u32		ac_supported;       /* response */
919a74af21SBoaz Harrosh 	u32		ac_resp_access;     /* response */
929a74af21SBoaz Harrosh };
939a74af21SBoaz Harrosh 
949a74af21SBoaz Harrosh struct nfsd4_close {
959a74af21SBoaz Harrosh 	u32		cl_seqid;           /* request */
969a74af21SBoaz Harrosh 	stateid_t	cl_stateid;         /* request+response */
979a74af21SBoaz Harrosh };
989a74af21SBoaz Harrosh 
999a74af21SBoaz Harrosh struct nfsd4_commit {
1009a74af21SBoaz Harrosh 	u64		co_offset;          /* request */
1019a74af21SBoaz Harrosh 	u32		co_count;           /* request */
1029a74af21SBoaz Harrosh 	nfs4_verifier	co_verf;            /* response */
1039a74af21SBoaz Harrosh };
1049a74af21SBoaz Harrosh 
1059a74af21SBoaz Harrosh struct nfsd4_create {
1069a74af21SBoaz Harrosh 	u32		cr_namelen;         /* request */
1079a74af21SBoaz Harrosh 	char *		cr_name;            /* request */
1089a74af21SBoaz Harrosh 	u32		cr_type;            /* request */
1099a74af21SBoaz Harrosh 	union {                             /* request */
1109a74af21SBoaz Harrosh 		struct {
1117fb84306SJ. Bruce Fields 			u32 datalen;
1127fb84306SJ. Bruce Fields 			char *data;
11338a70315SChuck Lever 			struct kvec first;
1149a74af21SBoaz Harrosh 		} link;   /* NF4LNK */
1159a74af21SBoaz Harrosh 		struct {
1169a74af21SBoaz Harrosh 			u32 specdata1;
1179a74af21SBoaz Harrosh 			u32 specdata2;
1189a74af21SBoaz Harrosh 		} dev;    /* NF4BLK, NF4CHR */
1199a74af21SBoaz Harrosh 	} u;
1209a74af21SBoaz Harrosh 	u32		cr_bmval[3];        /* request */
1219a74af21SBoaz Harrosh 	struct iattr	cr_iattr;           /* request */
122880a3a53SJ. Bruce Fields 	int		cr_umask;           /* request */
1239a74af21SBoaz Harrosh 	struct nfsd4_change_info  cr_cinfo; /* response */
1249a74af21SBoaz Harrosh 	struct nfs4_acl *cr_acl;
12518032ca0SDavid Quigley 	struct xdr_netobj cr_label;
1269a74af21SBoaz Harrosh };
1277fb84306SJ. Bruce Fields #define cr_datalen	u.link.datalen
1287fb84306SJ. Bruce Fields #define cr_data		u.link.data
12938a70315SChuck Lever #define cr_first	u.link.first
1309a74af21SBoaz Harrosh #define cr_specdata1	u.dev.specdata1
1319a74af21SBoaz Harrosh #define cr_specdata2	u.dev.specdata2
1329a74af21SBoaz Harrosh 
1339a74af21SBoaz Harrosh struct nfsd4_delegreturn {
1349a74af21SBoaz Harrosh 	stateid_t	dr_stateid;
1359a74af21SBoaz Harrosh };
1369a74af21SBoaz Harrosh 
1379a74af21SBoaz Harrosh struct nfsd4_getattr {
1389a74af21SBoaz Harrosh 	u32		ga_bmval[3];        /* request */
1399a74af21SBoaz Harrosh 	struct svc_fh	*ga_fhp;            /* response */
1409a74af21SBoaz Harrosh };
1419a74af21SBoaz Harrosh 
1429a74af21SBoaz Harrosh struct nfsd4_link {
1439a74af21SBoaz Harrosh 	u32		li_namelen;         /* request */
1449a74af21SBoaz Harrosh 	char *		li_name;            /* request */
1459a74af21SBoaz Harrosh 	struct nfsd4_change_info  li_cinfo; /* response */
1469a74af21SBoaz Harrosh };
1479a74af21SBoaz Harrosh 
1489a74af21SBoaz Harrosh struct nfsd4_lock_denied {
1499a74af21SBoaz Harrosh 	clientid_t	ld_clientid;
1507c13f344SJ. Bruce Fields 	struct xdr_netobj	ld_owner;
1519a74af21SBoaz Harrosh 	u64             ld_start;
1529a74af21SBoaz Harrosh 	u64             ld_length;
1539a74af21SBoaz Harrosh 	u32             ld_type;
1549a74af21SBoaz Harrosh };
1559a74af21SBoaz Harrosh 
1569a74af21SBoaz Harrosh struct nfsd4_lock {
1579a74af21SBoaz Harrosh 	/* request */
1589a74af21SBoaz Harrosh 	u32             lk_type;
1599a74af21SBoaz Harrosh 	u32             lk_reclaim;         /* boolean */
1609a74af21SBoaz Harrosh 	u64             lk_offset;
1619a74af21SBoaz Harrosh 	u64             lk_length;
1629a74af21SBoaz Harrosh 	u32             lk_is_new;
1639a74af21SBoaz Harrosh 	union {
1649a74af21SBoaz Harrosh 		struct {
1659a74af21SBoaz Harrosh 			u32             open_seqid;
1669a74af21SBoaz Harrosh 			stateid_t       open_stateid;
1679a74af21SBoaz Harrosh 			u32             lock_seqid;
1689a74af21SBoaz Harrosh 			clientid_t      clientid;
1699a74af21SBoaz Harrosh 			struct xdr_netobj owner;
1709a74af21SBoaz Harrosh 		} new;
1719a74af21SBoaz Harrosh 		struct {
1729a74af21SBoaz Harrosh 			stateid_t       lock_stateid;
1739a74af21SBoaz Harrosh 			u32             lock_seqid;
1749a74af21SBoaz Harrosh 		} old;
1759a74af21SBoaz Harrosh 	} v;
1769a74af21SBoaz Harrosh 
1779a74af21SBoaz Harrosh 	/* response */
1789a74af21SBoaz Harrosh 	union {
1799a74af21SBoaz Harrosh 		struct {
1809a74af21SBoaz Harrosh 			stateid_t               stateid;
1819a74af21SBoaz Harrosh 		} ok;
1829a74af21SBoaz Harrosh 		struct nfsd4_lock_denied        denied;
1839a74af21SBoaz Harrosh 	} u;
1849a74af21SBoaz Harrosh };
1859a74af21SBoaz Harrosh #define lk_new_open_seqid       v.new.open_seqid
1869a74af21SBoaz Harrosh #define lk_new_open_stateid     v.new.open_stateid
1879a74af21SBoaz Harrosh #define lk_new_lock_seqid       v.new.lock_seqid
1889a74af21SBoaz Harrosh #define lk_new_clientid         v.new.clientid
1899a74af21SBoaz Harrosh #define lk_new_owner            v.new.owner
1909a74af21SBoaz Harrosh #define lk_old_lock_stateid     v.old.lock_stateid
1919a74af21SBoaz Harrosh #define lk_old_lock_seqid       v.old.lock_seqid
1929a74af21SBoaz Harrosh 
1939a74af21SBoaz Harrosh #define lk_resp_stateid u.ok.stateid
1949a74af21SBoaz Harrosh #define lk_denied       u.denied
1959a74af21SBoaz Harrosh 
1969a74af21SBoaz Harrosh 
1979a74af21SBoaz Harrosh struct nfsd4_lockt {
1989a74af21SBoaz Harrosh 	u32				lt_type;
1999a74af21SBoaz Harrosh 	clientid_t			lt_clientid;
2009a74af21SBoaz Harrosh 	struct xdr_netobj		lt_owner;
2019a74af21SBoaz Harrosh 	u64				lt_offset;
2029a74af21SBoaz Harrosh 	u64				lt_length;
2039a74af21SBoaz Harrosh 	struct nfsd4_lock_denied  	lt_denied;
2049a74af21SBoaz Harrosh };
2059a74af21SBoaz Harrosh 
2069a74af21SBoaz Harrosh 
2079a74af21SBoaz Harrosh struct nfsd4_locku {
2089a74af21SBoaz Harrosh 	u32             lu_type;
2099a74af21SBoaz Harrosh 	u32             lu_seqid;
2109a74af21SBoaz Harrosh 	stateid_t       lu_stateid;
2119a74af21SBoaz Harrosh 	u64             lu_offset;
2129a74af21SBoaz Harrosh 	u64             lu_length;
2139a74af21SBoaz Harrosh };
2149a74af21SBoaz Harrosh 
2159a74af21SBoaz Harrosh 
2169a74af21SBoaz Harrosh struct nfsd4_lookup {
2179a74af21SBoaz Harrosh 	u32		lo_len;             /* request */
2189a74af21SBoaz Harrosh 	char *		lo_name;            /* request */
2199a74af21SBoaz Harrosh };
2209a74af21SBoaz Harrosh 
2219a74af21SBoaz Harrosh struct nfsd4_putfh {
2229a74af21SBoaz Harrosh 	u32		pf_fhlen;           /* request */
2239a74af21SBoaz Harrosh 	char		*pf_fhval;          /* request */
2249a74af21SBoaz Harrosh };
2259a74af21SBoaz Harrosh 
2269a74af21SBoaz Harrosh struct nfsd4_open {
2279a74af21SBoaz Harrosh 	u32		op_claim_type;      /* request */
2289a74af21SBoaz Harrosh 	struct xdr_netobj op_fname;	    /* request - everything but CLAIM_PREV */
2299a74af21SBoaz Harrosh 	u32		op_delegate_type;   /* request - CLAIM_PREV only */
2309a74af21SBoaz Harrosh 	stateid_t       op_delegate_stateid; /* request - response */
231d24433cdSBenny Halevy 	u32		op_why_no_deleg;    /* response - DELEG_NONE_EXT only */
2329a74af21SBoaz Harrosh 	u32		op_create;     	    /* request */
2339a74af21SBoaz Harrosh 	u32		op_createmode;      /* request */
234880a3a53SJ. Bruce Fields 	int		op_umask;           /* request */
2359a74af21SBoaz Harrosh 	u32		op_bmval[3];        /* request */
2363ff69309SKinglong Mee 	struct iattr	op_iattr;           /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
237ab4684d1SChuck Lever 	nfs4_verifier	op_verf __attribute__((aligned(32)));
238ab4684d1SChuck Lever 					    /* EXCLUSIVE4 */
2399a74af21SBoaz Harrosh 	clientid_t	op_clientid;        /* request */
2409a74af21SBoaz Harrosh 	struct xdr_netobj op_owner;           /* request */
2419a74af21SBoaz Harrosh 	u32		op_seqid;           /* request */
2429a74af21SBoaz Harrosh 	u32		op_share_access;    /* request */
2439a74af21SBoaz Harrosh 	u32		op_share_deny;      /* request */
2442c8bd7e0SBenny Halevy 	u32		op_deleg_want;      /* request */
2459a74af21SBoaz Harrosh 	stateid_t	op_stateid;         /* response */
2469d313b17SJ. Bruce Fields 	__be32		op_xdr_error;       /* see nfsd4_open_omfg() */
2479a74af21SBoaz Harrosh 	u32		op_recall;          /* recall */
2489a74af21SBoaz Harrosh 	struct nfsd4_change_info  op_cinfo; /* response */
2499a74af21SBoaz Harrosh 	u32		op_rflags;          /* response */
250856121b2SJ. Bruce Fields 	bool		op_truncate;        /* used during processing */
251856121b2SJ. Bruce Fields 	bool		op_created;         /* used during processing */
252fe0750e5SJ. Bruce Fields 	struct nfs4_openowner *op_openowner; /* used during processing */
25332513b40SJ. Bruce Fields 	struct nfs4_file *op_file;          /* used during processing */
2544cdc951bSJ. Bruce Fields 	struct nfs4_ol_stateid *op_stp;	    /* used during processing */
2558287f009SSachin Bhamare 	struct nfs4_clnt_odstate *op_odstate; /* used during processing */
2569a74af21SBoaz Harrosh 	struct nfs4_acl *op_acl;
25718032ca0SDavid Quigley 	struct xdr_netobj op_label;
2589a74af21SBoaz Harrosh };
2599a74af21SBoaz Harrosh 
2609a74af21SBoaz Harrosh struct nfsd4_open_confirm {
2619a74af21SBoaz Harrosh 	stateid_t	oc_req_stateid		/* request */;
2629a74af21SBoaz Harrosh 	u32		oc_seqid    		/* request */;
2639a74af21SBoaz Harrosh 	stateid_t	oc_resp_stateid		/* response */;
2649a74af21SBoaz Harrosh };
2659a74af21SBoaz Harrosh 
2669a74af21SBoaz Harrosh struct nfsd4_open_downgrade {
2679a74af21SBoaz Harrosh 	stateid_t       od_stateid;
2689a74af21SBoaz Harrosh 	u32             od_seqid;
2692c8bd7e0SBenny Halevy 	u32             od_share_access;	/* request */
2702c8bd7e0SBenny Halevy 	u32		od_deleg_want;		/* request */
2712c8bd7e0SBenny Halevy 	u32             od_share_deny;		/* request */
2729a74af21SBoaz Harrosh };
2739a74af21SBoaz Harrosh 
2749a74af21SBoaz Harrosh 
2759a74af21SBoaz Harrosh struct nfsd4_read {
2769a74af21SBoaz Harrosh 	stateid_t	rd_stateid;         /* request */
2779a74af21SBoaz Harrosh 	u64		rd_offset;          /* request */
2789a74af21SBoaz Harrosh 	u32		rd_length;          /* request */
2799a74af21SBoaz Harrosh 	int		rd_vlen;
2809a74af21SBoaz Harrosh 	struct file     *rd_filp;
281af90f707SChristoph Hellwig 	bool		rd_tmp_file;
2829a74af21SBoaz Harrosh 
2839a74af21SBoaz Harrosh 	struct svc_rqst *rd_rqstp;          /* response */
2849a74af21SBoaz Harrosh 	struct svc_fh * rd_fhp;             /* response */
2859a74af21SBoaz Harrosh };
2869a74af21SBoaz Harrosh 
2879a74af21SBoaz Harrosh struct nfsd4_readdir {
2889a74af21SBoaz Harrosh 	u64		rd_cookie;          /* request */
2899a74af21SBoaz Harrosh 	nfs4_verifier	rd_verf;            /* request */
2909a74af21SBoaz Harrosh 	u32		rd_dircount;        /* request */
2919a74af21SBoaz Harrosh 	u32		rd_maxcount;        /* request */
2929a74af21SBoaz Harrosh 	u32		rd_bmval[3];        /* request */
2939a74af21SBoaz Harrosh 	struct svc_rqst *rd_rqstp;          /* response */
2949a74af21SBoaz Harrosh 	struct svc_fh * rd_fhp;             /* response */
2959a74af21SBoaz Harrosh 
2969a74af21SBoaz Harrosh 	struct readdir_cd	common;
297561f0ed4SJ. Bruce Fields 	struct xdr_stream	*xdr;
298561f0ed4SJ. Bruce Fields 	int			cookie_offset;
2999a74af21SBoaz Harrosh };
3009a74af21SBoaz Harrosh 
3019a74af21SBoaz Harrosh struct nfsd4_release_lockowner {
3029a74af21SBoaz Harrosh 	clientid_t        rl_clientid;
3039a74af21SBoaz Harrosh 	struct xdr_netobj rl_owner;
3049a74af21SBoaz Harrosh };
3059a74af21SBoaz Harrosh struct nfsd4_readlink {
3069a74af21SBoaz Harrosh 	struct svc_rqst *rl_rqstp;          /* request */
3079a74af21SBoaz Harrosh 	struct svc_fh *	rl_fhp;             /* request */
3089a74af21SBoaz Harrosh };
3099a74af21SBoaz Harrosh 
3109a74af21SBoaz Harrosh struct nfsd4_remove {
3119a74af21SBoaz Harrosh 	u32		rm_namelen;         /* request */
3129a74af21SBoaz Harrosh 	char *		rm_name;            /* request */
3139a74af21SBoaz Harrosh 	struct nfsd4_change_info  rm_cinfo; /* response */
3149a74af21SBoaz Harrosh };
3159a74af21SBoaz Harrosh 
3169a74af21SBoaz Harrosh struct nfsd4_rename {
3179a74af21SBoaz Harrosh 	u32		rn_snamelen;        /* request */
3189a74af21SBoaz Harrosh 	char *		rn_sname;           /* request */
3199a74af21SBoaz Harrosh 	u32		rn_tnamelen;        /* request */
3209a74af21SBoaz Harrosh 	char *		rn_tname;           /* request */
3219a74af21SBoaz Harrosh 	struct nfsd4_change_info  rn_sinfo; /* response */
3229a74af21SBoaz Harrosh 	struct nfsd4_change_info  rn_tinfo; /* response */
3239a74af21SBoaz Harrosh };
3249a74af21SBoaz Harrosh 
3259a74af21SBoaz Harrosh struct nfsd4_secinfo {
3269a74af21SBoaz Harrosh 	u32 si_namelen;					/* request */
3279a74af21SBoaz Harrosh 	char *si_name;					/* request */
3289a74af21SBoaz Harrosh 	struct svc_export *si_exp;			/* response */
3299a74af21SBoaz Harrosh };
3309a74af21SBoaz Harrosh 
33104f4ad16SJ. Bruce Fields struct nfsd4_secinfo_no_name {
33204f4ad16SJ. Bruce Fields 	u32 sin_style;					/* request */
33304f4ad16SJ. Bruce Fields 	struct svc_export *sin_exp;			/* response */
33404f4ad16SJ. Bruce Fields };
33504f4ad16SJ. Bruce Fields 
3369a74af21SBoaz Harrosh struct nfsd4_setattr {
3379a74af21SBoaz Harrosh 	stateid_t	sa_stateid;         /* request */
3389a74af21SBoaz Harrosh 	u32		sa_bmval[3];        /* request */
3399a74af21SBoaz Harrosh 	struct iattr	sa_iattr;           /* request */
3409a74af21SBoaz Harrosh 	struct nfs4_acl *sa_acl;
34118032ca0SDavid Quigley 	struct xdr_netobj sa_label;
3429a74af21SBoaz Harrosh };
3439a74af21SBoaz Harrosh 
3449a74af21SBoaz Harrosh struct nfsd4_setclientid {
3459a74af21SBoaz Harrosh 	nfs4_verifier	se_verf;            /* request */
346a084daf5SJ. Bruce Fields 	struct xdr_netobj se_name;
3479a74af21SBoaz Harrosh 	u32		se_callback_prog;   /* request */
3489a74af21SBoaz Harrosh 	u32		se_callback_netid_len;  /* request */
3499a74af21SBoaz Harrosh 	char *		se_callback_netid_val;  /* request */
3509a74af21SBoaz Harrosh 	u32		se_callback_addr_len;   /* request */
3519a74af21SBoaz Harrosh 	char *		se_callback_addr_val;   /* request */
3529a74af21SBoaz Harrosh 	u32		se_callback_ident;  /* request */
3539a74af21SBoaz Harrosh 	clientid_t	se_clientid;        /* response */
3549a74af21SBoaz Harrosh 	nfs4_verifier	se_confirm;         /* response */
3559a74af21SBoaz Harrosh };
3569a74af21SBoaz Harrosh 
3579a74af21SBoaz Harrosh struct nfsd4_setclientid_confirm {
3589a74af21SBoaz Harrosh 	clientid_t	sc_clientid;
3599a74af21SBoaz Harrosh 	nfs4_verifier	sc_confirm;
3609a74af21SBoaz Harrosh };
3619a74af21SBoaz Harrosh 
36217456804SBryan Schumaker struct nfsd4_saved_compoundargs {
36317456804SBryan Schumaker 	__be32 *p;
36417456804SBryan Schumaker 	__be32 *end;
36517456804SBryan Schumaker 	int pagelen;
36617456804SBryan Schumaker 	struct page **pagelist;
36717456804SBryan Schumaker };
36817456804SBryan Schumaker 
36903cfb420SBryan Schumaker struct nfsd4_test_stateid_id {
37003cfb420SBryan Schumaker 	__be32			ts_id_status;
37103cfb420SBryan Schumaker 	stateid_t		ts_id_stateid;
37203cfb420SBryan Schumaker 	struct list_head	ts_id_list;
37303cfb420SBryan Schumaker };
37403cfb420SBryan Schumaker 
37517456804SBryan Schumaker struct nfsd4_test_stateid {
37657b7b43bSJ. Bruce Fields 	u32		ts_num_ids;
37703cfb420SBryan Schumaker 	struct list_head ts_stateid_list;
37817456804SBryan Schumaker };
37917456804SBryan Schumaker 
380e1ca12dfSBryan Schumaker struct nfsd4_free_stateid {
381e1ca12dfSBryan Schumaker 	stateid_t	fr_stateid;         /* request */
382e1ca12dfSBryan Schumaker };
383e1ca12dfSBryan Schumaker 
3849a74af21SBoaz Harrosh /* also used for NVERIFY */
3859a74af21SBoaz Harrosh struct nfsd4_verify {
3869a74af21SBoaz Harrosh 	u32		ve_bmval[3];        /* request */
3879a74af21SBoaz Harrosh 	u32		ve_attrlen;         /* request */
3889a74af21SBoaz Harrosh 	char *		ve_attrval;         /* request */
3899a74af21SBoaz Harrosh };
3909a74af21SBoaz Harrosh 
3919a74af21SBoaz Harrosh struct nfsd4_write {
3929a74af21SBoaz Harrosh 	stateid_t	wr_stateid;         /* request */
3939a74af21SBoaz Harrosh 	u64		wr_offset;          /* request */
3949a74af21SBoaz Harrosh 	u32		wr_stable_how;      /* request */
3959a74af21SBoaz Harrosh 	u32		wr_buflen;          /* request */
39670cc7f75SJ. Bruce Fields 	struct kvec	wr_head;
39770cc7f75SJ. Bruce Fields 	struct page **	wr_pagelist;        /* request */
3989a74af21SBoaz Harrosh 
3999a74af21SBoaz Harrosh 	u32		wr_bytes_written;   /* response */
4009a74af21SBoaz Harrosh 	u32		wr_how_written;     /* response */
4019a74af21SBoaz Harrosh 	nfs4_verifier	wr_verifier;        /* response */
4029a74af21SBoaz Harrosh };
4039a74af21SBoaz Harrosh 
4049a74af21SBoaz Harrosh struct nfsd4_exchange_id {
4059a74af21SBoaz Harrosh 	nfs4_verifier	verifier;
4069a74af21SBoaz Harrosh 	struct xdr_netobj clname;
4079a74af21SBoaz Harrosh 	u32		flags;
4089a74af21SBoaz Harrosh 	clientid_t	clientid;
4099a74af21SBoaz Harrosh 	u32		seqid;
4109a74af21SBoaz Harrosh 	int		spa_how;
411ed941643SAndrew Elble 	u32             spo_must_enforce[3];
412ed941643SAndrew Elble 	u32             spo_must_allow[3];
4139a74af21SBoaz Harrosh };
4149a74af21SBoaz Harrosh 
4159a74af21SBoaz Harrosh struct nfsd4_sequence {
4169a74af21SBoaz Harrosh 	struct nfs4_sessionid	sessionid;		/* request/response */
4179a74af21SBoaz Harrosh 	u32			seqid;			/* request/response */
4189a74af21SBoaz Harrosh 	u32			slotid;			/* request/response */
4199a74af21SBoaz Harrosh 	u32			maxslots;		/* request/response */
4209a74af21SBoaz Harrosh 	u32			cachethis;		/* request */
4219a74af21SBoaz Harrosh #if 0
4229a74af21SBoaz Harrosh 	u32			target_maxslots;	/* response */
4239a74af21SBoaz Harrosh #endif /* not yet */
4240d7bb719SJ. Bruce Fields 	u32			status_flags;		/* response */
4259a74af21SBoaz Harrosh };
4269a74af21SBoaz Harrosh 
4279a74af21SBoaz Harrosh struct nfsd4_destroy_session {
4289a74af21SBoaz Harrosh 	struct nfs4_sessionid	sessionid;
4299a74af21SBoaz Harrosh };
4309a74af21SBoaz Harrosh 
431345c2842SMi Jinlong struct nfsd4_destroy_clientid {
432345c2842SMi Jinlong 	clientid_t clientid;
433345c2842SMi Jinlong };
434345c2842SMi Jinlong 
4354dc6ec00SJ. Bruce Fields struct nfsd4_reclaim_complete {
4364dc6ec00SJ. Bruce Fields 	u32 rca_one_fs;
4374dc6ec00SJ. Bruce Fields };
4384dc6ec00SJ. Bruce Fields 
4399cf514ccSChristoph Hellwig struct nfsd4_deviceid {
4409cf514ccSChristoph Hellwig 	u64			fsid_idx;
4419cf514ccSChristoph Hellwig 	u32			generation;
4429cf514ccSChristoph Hellwig 	u32			pad;
4439cf514ccSChristoph Hellwig };
4449cf514ccSChristoph Hellwig 
4459cf514ccSChristoph Hellwig struct nfsd4_layout_seg {
4469cf514ccSChristoph Hellwig 	u32			iomode;
4479cf514ccSChristoph Hellwig 	u64			offset;
4489cf514ccSChristoph Hellwig 	u64			length;
4499cf514ccSChristoph Hellwig };
4509cf514ccSChristoph Hellwig 
4519cf514ccSChristoph Hellwig struct nfsd4_getdeviceinfo {
4529cf514ccSChristoph Hellwig 	struct nfsd4_deviceid	gd_devid;	/* request */
4539cf514ccSChristoph Hellwig 	u32			gd_layout_type;	/* request */
4549cf514ccSChristoph Hellwig 	u32			gd_maxcount;	/* request */
4559cf514ccSChristoph Hellwig 	u32			gd_notify_types;/* request - response */
4569cf514ccSChristoph Hellwig 	void			*gd_device;	/* response */
4579cf514ccSChristoph Hellwig };
4589cf514ccSChristoph Hellwig 
4599cf514ccSChristoph Hellwig struct nfsd4_layoutget {
4609cf514ccSChristoph Hellwig 	u64			lg_minlength;	/* request */
4619cf514ccSChristoph Hellwig 	u32			lg_signal;	/* request */
4629cf514ccSChristoph Hellwig 	u32			lg_layout_type;	/* request */
4639cf514ccSChristoph Hellwig 	u32			lg_maxcount;	/* request */
4649cf514ccSChristoph Hellwig 	stateid_t		lg_sid;		/* request/response */
4659cf514ccSChristoph Hellwig 	struct nfsd4_layout_seg	lg_seg;		/* request/response */
4669cf514ccSChristoph Hellwig 	void			*lg_content;	/* response */
4679cf514ccSChristoph Hellwig };
4689cf514ccSChristoph Hellwig 
4699cf514ccSChristoph Hellwig struct nfsd4_layoutcommit {
4709cf514ccSChristoph Hellwig 	stateid_t		lc_sid;		/* request */
4719cf514ccSChristoph Hellwig 	struct nfsd4_layout_seg	lc_seg;		/* request */
4729cf514ccSChristoph Hellwig 	u32			lc_reclaim;	/* request */
4739cf514ccSChristoph Hellwig 	u32			lc_newoffset;	/* request */
4749cf514ccSChristoph Hellwig 	u64			lc_last_wr;	/* request */
4759cf514ccSChristoph Hellwig 	struct timespec		lc_mtime;	/* request */
4769cf514ccSChristoph Hellwig 	u32			lc_layout_type;	/* request */
4779cf514ccSChristoph Hellwig 	u32			lc_up_len;	/* layout length */
4789cf514ccSChristoph Hellwig 	void			*lc_up_layout;	/* decoded by callback */
4799cf514ccSChristoph Hellwig 	u32			lc_size_chg;	/* boolean for response */
4809cf514ccSChristoph Hellwig 	u64			lc_newsize;	/* response */
4819cf514ccSChristoph Hellwig };
4829cf514ccSChristoph Hellwig 
4839cf514ccSChristoph Hellwig struct nfsd4_layoutreturn {
4849cf514ccSChristoph Hellwig 	u32			lr_return_type;	/* request */
4859cf514ccSChristoph Hellwig 	u32			lr_layout_type;	/* request */
4869cf514ccSChristoph Hellwig 	struct nfsd4_layout_seg	lr_seg;		/* request */
4879cf514ccSChristoph Hellwig 	u32			lr_reclaim;	/* request */
4889cf514ccSChristoph Hellwig 	u32			lrf_body_len;	/* request */
4899cf514ccSChristoph Hellwig 	void			*lrf_body;	/* request */
4909cf514ccSChristoph Hellwig 	stateid_t		lr_sid;		/* request/response */
4919cf514ccSChristoph Hellwig 	u32			lrs_present;	/* response */
4929cf514ccSChristoph Hellwig };
4939cf514ccSChristoph Hellwig 
49495d871f0SAnna Schumaker struct nfsd4_fallocate {
49595d871f0SAnna Schumaker 	/* request */
49695d871f0SAnna Schumaker 	stateid_t	falloc_stateid;
49795d871f0SAnna Schumaker 	loff_t		falloc_offset;
49895d871f0SAnna Schumaker 	u64		falloc_length;
49995d871f0SAnna Schumaker };
50095d871f0SAnna Schumaker 
501ffa0160aSChristoph Hellwig struct nfsd4_clone {
502ffa0160aSChristoph Hellwig 	/* request */
503ffa0160aSChristoph Hellwig 	stateid_t	cl_src_stateid;
504ffa0160aSChristoph Hellwig 	stateid_t	cl_dst_stateid;
505ffa0160aSChristoph Hellwig 	u64		cl_src_pos;
506ffa0160aSChristoph Hellwig 	u64		cl_dst_pos;
507ffa0160aSChristoph Hellwig 	u64		cl_count;
508ffa0160aSChristoph Hellwig };
509ffa0160aSChristoph Hellwig 
51029ae7f9dSAnna Schumaker struct nfsd42_write_res {
51129ae7f9dSAnna Schumaker 	u64			wr_bytes_written;
51229ae7f9dSAnna Schumaker 	u32			wr_stable_how;
51329ae7f9dSAnna Schumaker 	nfs4_verifier		wr_verifier;
51429ae7f9dSAnna Schumaker };
51529ae7f9dSAnna Schumaker 
51629ae7f9dSAnna Schumaker struct nfsd4_copy {
51729ae7f9dSAnna Schumaker 	/* request */
51829ae7f9dSAnna Schumaker 	stateid_t	cp_src_stateid;
51929ae7f9dSAnna Schumaker 	stateid_t	cp_dst_stateid;
52029ae7f9dSAnna Schumaker 	u64		cp_src_pos;
52129ae7f9dSAnna Schumaker 	u64		cp_dst_pos;
52229ae7f9dSAnna Schumaker 	u64		cp_count;
52329ae7f9dSAnna Schumaker 
52429ae7f9dSAnna Schumaker 	/* both */
52529ae7f9dSAnna Schumaker 	bool		cp_synchronous;
52629ae7f9dSAnna Schumaker 
52729ae7f9dSAnna Schumaker 	/* response */
52829ae7f9dSAnna Schumaker 	struct nfsd42_write_res	cp_res;
52929ae7f9dSAnna Schumaker };
53029ae7f9dSAnna Schumaker 
53124bab491SAnna Schumaker struct nfsd4_seek {
53224bab491SAnna Schumaker 	/* request */
53324bab491SAnna Schumaker 	stateid_t	seek_stateid;
53424bab491SAnna Schumaker 	loff_t		seek_offset;
53524bab491SAnna Schumaker 	u32		seek_whence;
53624bab491SAnna Schumaker 
53724bab491SAnna Schumaker 	/* response */
53824bab491SAnna Schumaker 	u32		seek_eof;
53924bab491SAnna Schumaker 	loff_t		seek_pos;
54024bab491SAnna Schumaker };
54124bab491SAnna Schumaker 
5429a74af21SBoaz Harrosh struct nfsd4_op {
5439a74af21SBoaz Harrosh 	int					opnum;
544f4f9ef4aSJ. Bruce Fields 	const struct nfsd4_operation *		opdesc;
5459a74af21SBoaz Harrosh 	__be32					status;
546b60e9859SChristoph Hellwig 	union nfsd4_op_u {
5479a74af21SBoaz Harrosh 		struct nfsd4_access		access;
5489a74af21SBoaz Harrosh 		struct nfsd4_close		close;
5499a74af21SBoaz Harrosh 		struct nfsd4_commit		commit;
5509a74af21SBoaz Harrosh 		struct nfsd4_create		create;
5519a74af21SBoaz Harrosh 		struct nfsd4_delegreturn	delegreturn;
5529a74af21SBoaz Harrosh 		struct nfsd4_getattr		getattr;
5539a74af21SBoaz Harrosh 		struct svc_fh *			getfh;
5549a74af21SBoaz Harrosh 		struct nfsd4_link		link;
5559a74af21SBoaz Harrosh 		struct nfsd4_lock		lock;
5569a74af21SBoaz Harrosh 		struct nfsd4_lockt		lockt;
5579a74af21SBoaz Harrosh 		struct nfsd4_locku		locku;
5589a74af21SBoaz Harrosh 		struct nfsd4_lookup		lookup;
5599a74af21SBoaz Harrosh 		struct nfsd4_verify		nverify;
5609a74af21SBoaz Harrosh 		struct nfsd4_open		open;
5619a74af21SBoaz Harrosh 		struct nfsd4_open_confirm	open_confirm;
5629a74af21SBoaz Harrosh 		struct nfsd4_open_downgrade	open_downgrade;
5639a74af21SBoaz Harrosh 		struct nfsd4_putfh		putfh;
5649a74af21SBoaz Harrosh 		struct nfsd4_read		read;
5659a74af21SBoaz Harrosh 		struct nfsd4_readdir		readdir;
5669a74af21SBoaz Harrosh 		struct nfsd4_readlink		readlink;
5679a74af21SBoaz Harrosh 		struct nfsd4_remove		remove;
5689a74af21SBoaz Harrosh 		struct nfsd4_rename		rename;
5699a74af21SBoaz Harrosh 		clientid_t			renew;
5709a74af21SBoaz Harrosh 		struct nfsd4_secinfo		secinfo;
5719a74af21SBoaz Harrosh 		struct nfsd4_setattr		setattr;
5729a74af21SBoaz Harrosh 		struct nfsd4_setclientid	setclientid;
5739a74af21SBoaz Harrosh 		struct nfsd4_setclientid_confirm setclientid_confirm;
5749a74af21SBoaz Harrosh 		struct nfsd4_verify		verify;
5759a74af21SBoaz Harrosh 		struct nfsd4_write		write;
5769a74af21SBoaz Harrosh 		struct nfsd4_release_lockowner	release_lockowner;
5779a74af21SBoaz Harrosh 
5789a74af21SBoaz Harrosh 		/* NFSv4.1 */
5799a74af21SBoaz Harrosh 		struct nfsd4_exchange_id	exchange_id;
580cb73a9f4SJ. Bruce Fields 		struct nfsd4_backchannel_ctl	backchannel_ctl;
5811d1bc8f2SJ. Bruce Fields 		struct nfsd4_bind_conn_to_session bind_conn_to_session;
5829a74af21SBoaz Harrosh 		struct nfsd4_create_session	create_session;
5839a74af21SBoaz Harrosh 		struct nfsd4_destroy_session	destroy_session;
584eb69853dSChristoph Hellwig 		struct nfsd4_destroy_clientid	destroy_clientid;
5859a74af21SBoaz Harrosh 		struct nfsd4_sequence		sequence;
5864dc6ec00SJ. Bruce Fields 		struct nfsd4_reclaim_complete	reclaim_complete;
58717456804SBryan Schumaker 		struct nfsd4_test_stateid	test_stateid;
588e1ca12dfSBryan Schumaker 		struct nfsd4_free_stateid	free_stateid;
5899cf514ccSChristoph Hellwig 		struct nfsd4_getdeviceinfo	getdeviceinfo;
5909cf514ccSChristoph Hellwig 		struct nfsd4_layoutget		layoutget;
5919cf514ccSChristoph Hellwig 		struct nfsd4_layoutcommit	layoutcommit;
5929cf514ccSChristoph Hellwig 		struct nfsd4_layoutreturn	layoutreturn;
593eb69853dSChristoph Hellwig 		struct nfsd4_secinfo_no_name	secinfo_no_name;
59424bab491SAnna Schumaker 
59524bab491SAnna Schumaker 		/* NFSv4.2 */
59695d871f0SAnna Schumaker 		struct nfsd4_fallocate		allocate;
597b0cb9085SAnna Schumaker 		struct nfsd4_fallocate		deallocate;
598ffa0160aSChristoph Hellwig 		struct nfsd4_clone		clone;
59929ae7f9dSAnna Schumaker 		struct nfsd4_copy		copy;
60024bab491SAnna Schumaker 		struct nfsd4_seek		seek;
6019a74af21SBoaz Harrosh 	} u;
6029a74af21SBoaz Harrosh 	struct nfs4_replay *			replay;
6039a74af21SBoaz Harrosh };
6049a74af21SBoaz Harrosh 
6051091006cSJ. Bruce Fields bool nfsd4_cache_this_op(struct nfsd4_op *);
6061091006cSJ. Bruce Fields 
607d5e23383SJ. Bruce Fields /*
608d5e23383SJ. Bruce Fields  * Memory needed just for the duration of processing one compound:
609d5e23383SJ. Bruce Fields  */
610d5e23383SJ. Bruce Fields struct svcxdr_tmpbuf {
611d5e23383SJ. Bruce Fields 	struct svcxdr_tmpbuf *next;
612d5e23383SJ. Bruce Fields 	char buf[];
613d5e23383SJ. Bruce Fields };
614d5e23383SJ. Bruce Fields 
6159a74af21SBoaz Harrosh struct nfsd4_compoundargs {
6169a74af21SBoaz Harrosh 	/* scratch variables for XDR decode */
6179a74af21SBoaz Harrosh 	__be32 *			p;
6189a74af21SBoaz Harrosh 	__be32 *			end;
6199a74af21SBoaz Harrosh 	struct page **			pagelist;
6209a74af21SBoaz Harrosh 	int				pagelen;
621eae03e2aSChuck Lever 	bool				tail;
6229a74af21SBoaz Harrosh 	__be32				tmp[8];
6239a74af21SBoaz Harrosh 	__be32 *			tmpp;
624d5e23383SJ. Bruce Fields 	struct svcxdr_tmpbuf		*to_free;
6259a74af21SBoaz Harrosh 
6269a74af21SBoaz Harrosh 	struct svc_rqst			*rqstp;
6279a74af21SBoaz Harrosh 
6289a74af21SBoaz Harrosh 	u32				taglen;
6299a74af21SBoaz Harrosh 	char *				tag;
6309a74af21SBoaz Harrosh 	u32				minorversion;
6319a74af21SBoaz Harrosh 	u32				opcnt;
6329a74af21SBoaz Harrosh 	struct nfsd4_op			*ops;
6339a74af21SBoaz Harrosh 	struct nfsd4_op			iops[8];
6341091006cSJ. Bruce Fields 	int				cachetype;
6359a74af21SBoaz Harrosh };
6369a74af21SBoaz Harrosh 
6379a74af21SBoaz Harrosh struct nfsd4_compoundres {
6389a74af21SBoaz Harrosh 	/* scratch variables for XDR encode */
6394aea24b2SJ. Bruce Fields 	struct xdr_stream		xdr;
6409a74af21SBoaz Harrosh 	struct svc_rqst *		rqstp;
6419a74af21SBoaz Harrosh 
6429a74af21SBoaz Harrosh 	u32				taglen;
6439a74af21SBoaz Harrosh 	char *				tag;
6449a74af21SBoaz Harrosh 	u32				opcnt;
6459a74af21SBoaz Harrosh 	__be32 *			tagp; /* tag, opcount encode location */
6469a74af21SBoaz Harrosh 	struct nfsd4_compound_state	cstate;
6479a74af21SBoaz Harrosh };
6489a74af21SBoaz Harrosh 
6499a74af21SBoaz Harrosh static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp)
6509a74af21SBoaz Harrosh {
6519a74af21SBoaz Harrosh 	struct nfsd4_compoundargs *args = resp->rqstp->rq_argp;
6529a74af21SBoaz Harrosh 	return resp->opcnt == 1 && args->ops[0].opnum == OP_SEQUENCE;
6539a74af21SBoaz Harrosh }
6549a74af21SBoaz Harrosh 
655085def3aSJ. Bruce Fields /*
656085def3aSJ. Bruce Fields  * The session reply cache only needs to cache replies that the client
657085def3aSJ. Bruce Fields  * actually asked us to.  But it's almost free for us to cache compounds
658085def3aSJ. Bruce Fields  * consisting of only a SEQUENCE op, so we may as well cache those too.
659085def3aSJ. Bruce Fields  * Also, the protocol doesn't give us a convenient response in the case
660085def3aSJ. Bruce Fields  * of a replay of a solo SEQUENCE op that wasn't cached
661085def3aSJ. Bruce Fields  * (RETRY_UNCACHED_REP can only be returned in the second op of a
662085def3aSJ. Bruce Fields  * compound).
663085def3aSJ. Bruce Fields  */
664085def3aSJ. Bruce Fields static inline bool nfsd4_cache_this(struct nfsd4_compoundres *resp)
6659a74af21SBoaz Harrosh {
666085def3aSJ. Bruce Fields 	return (resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS)
66773e79482SJ. Bruce Fields 		|| nfsd4_is_solo_sequence(resp);
6689a74af21SBoaz Harrosh }
6699a74af21SBoaz Harrosh 
6709b3234b9SJ. Bruce Fields static inline bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
6719b3234b9SJ. Bruce Fields {
6729b3234b9SJ. Bruce Fields 	struct nfsd4_compoundres *resp = rqstp->rq_resp;
6739b3234b9SJ. Bruce Fields 	struct nfsd4_compoundargs *argp = rqstp->rq_argp;
6749b3234b9SJ. Bruce Fields 
6759b3234b9SJ. Bruce Fields 	return argp->opcnt == resp->opcnt;
6769b3234b9SJ. Bruce Fields }
6779b3234b9SJ. Bruce Fields 
678f4f9ef4aSJ. Bruce Fields const struct nfsd4_operation *OPDESC(struct nfsd4_op *op);
6794f0cefbfSJ. Bruce Fields int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op);
68007d1f802SJ. Bruce Fields void warn_on_nonidempotent_op(struct nfsd4_op *op);
68107d1f802SJ. Bruce Fields 
6829a74af21SBoaz Harrosh #define NFS4_SVC_XDRSIZE		sizeof(struct nfsd4_compoundargs)
6839a74af21SBoaz Harrosh 
6849a74af21SBoaz Harrosh static inline void
6859a74af21SBoaz Harrosh set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
6869a74af21SBoaz Harrosh {
687c1ac3ffcSNeil Brown 	BUG_ON(!fhp->fh_pre_saved);
688aaf91ec1SJeff Layton 	cinfo->atomic = (u32)fhp->fh_post_saved;
6892b0143b5SDavid Howells 	cinfo->change_supported = IS_I_VERSION(d_inode(fhp->fh_dentry));
690c1ac3ffcSNeil Brown 
6919a74af21SBoaz Harrosh 	cinfo->before_change = fhp->fh_pre_change;
6929a74af21SBoaz Harrosh 	cinfo->after_change = fhp->fh_post_change;
6939a74af21SBoaz Harrosh 	cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
6949a74af21SBoaz Harrosh 	cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
6959a74af21SBoaz Harrosh 	cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
6969a74af21SBoaz Harrosh 	cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
697c1ac3ffcSNeil Brown 
6989a74af21SBoaz Harrosh }
6999a74af21SBoaz Harrosh 
700dedeb13fSAndrew Elble 
701dedeb13fSAndrew Elble bool nfsd4_mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp);
70263f8de37SChristoph Hellwig int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *);
703026fec7eSChristoph Hellwig int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *);
70463f8de37SChristoph Hellwig int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *);
70557b7b43bSJ. Bruce Fields __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);
7069a74af21SBoaz Harrosh void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
707d0a381ddSJ. Bruce Fields void nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op);
708d5184658SJ. Bruce Fields __be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
709d5184658SJ. Bruce Fields 		struct svc_fh *fhp, struct svc_export *exp,
710d5184658SJ. Bruce Fields 		struct dentry *dentry,
7119a74af21SBoaz Harrosh 		u32 *bmval, struct svc_rqst *, int ignore_crossmnt);
7129a74af21SBoaz Harrosh extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
713eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
7149a74af21SBoaz Harrosh extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
715eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
7169a74af21SBoaz Harrosh extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
717eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
718eb69853dSChristoph Hellwig extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *,
719eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
720eb69853dSChristoph Hellwig extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *,
721eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
7229a74af21SBoaz Harrosh extern __be32 nfsd4_create_session(struct svc_rqst *,
723eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
7249a74af21SBoaz Harrosh extern __be32 nfsd4_sequence(struct svc_rqst *,
725eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
726b607664eSTrond Myklebust extern void nfsd4_sequence_done(struct nfsd4_compoundres *resp);
7279a74af21SBoaz Harrosh extern __be32 nfsd4_destroy_session(struct svc_rqst *,
728eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
729eb69853dSChristoph Hellwig extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *,
730eb69853dSChristoph Hellwig 		union nfsd4_op_u *u);
731eb69853dSChristoph Hellwig __be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *,
732eb69853dSChristoph Hellwig 		union nfsd4_op_u *u);
7339a74af21SBoaz Harrosh extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
7343320fef1SStanislav Kinsbursky 		struct nfsd4_open *open, struct nfsd_net *nn);
7359a74af21SBoaz Harrosh extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
7369a74af21SBoaz Harrosh 		struct svc_fh *current_fh, struct nfsd4_open *open);
73758fb12e6SJeff Layton extern void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate);
73858fb12e6SJeff Layton extern void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
73942297899SJeff Layton 		struct nfsd4_open *open);
7409a74af21SBoaz Harrosh extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
741eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
742eb69853dSChristoph Hellwig extern __be32 nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
743eb69853dSChristoph Hellwig 		union nfsd4_op_u *u);
7449a74af21SBoaz Harrosh extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp,
745eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
7469a74af21SBoaz Harrosh extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
747eb69853dSChristoph Hellwig 		union nfsd4_op_u *u);
748eb69853dSChristoph Hellwig extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
749eb69853dSChristoph Hellwig 		union nfsd4_op_u *u);
750eb69853dSChristoph Hellwig extern __be32 nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
751eb69853dSChristoph Hellwig 		union nfsd4_op_u *u);
7529a74af21SBoaz Harrosh extern __be32
7539a74af21SBoaz Harrosh nfsd4_release_lockowner(struct svc_rqst *rqstp,
754eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
7558537488bSChristoph Hellwig extern void nfsd4_release_compoundargs(struct svc_rqst *rqstp);
7569a74af21SBoaz Harrosh extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp,
757eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *u);
758eb69853dSChristoph Hellwig extern __be32 nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
759eb69853dSChristoph Hellwig 		union nfsd4_op_u *u);
76017456804SBryan Schumaker extern __be32 nfsd4_test_stateid(struct svc_rqst *rqstp,
761eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *);
762e1ca12dfSBryan Schumaker extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp,
763eb69853dSChristoph Hellwig 		struct nfsd4_compound_state *, union nfsd4_op_u *);
7649411b1d4SJ. Bruce Fields extern void nfsd4_bump_seqid(struct nfsd4_compound_state *, __be32 nfserr);
76558fb12e6SJeff Layton 
7660020939fSJ. Bruce Fields enum nfsd4_op_flags {
7670020939fSJ. Bruce Fields 	ALLOWED_WITHOUT_FH = 1 << 0,    /* No current filehandle required */
7680020939fSJ. Bruce Fields 	ALLOWED_ON_ABSENT_FS = 1 << 1,  /* ops processed on absent fs */
7690020939fSJ. Bruce Fields 	ALLOWED_AS_FIRST_OP = 1 << 2,   /* ops reqired first in compound */
7700020939fSJ. Bruce Fields 	/* For rfc 5661 section 2.6.3.1.1: */
7710020939fSJ. Bruce Fields 	OP_HANDLES_WRONGSEC = 1 << 3,
7720020939fSJ. Bruce Fields 	OP_IS_PUTFH_LIKE = 1 << 4,
7730020939fSJ. Bruce Fields 	/*
7740020939fSJ. Bruce Fields 	 * These are the ops whose result size we estimate before
7750020939fSJ. Bruce Fields 	 * encoding, to avoid performing an op then not being able to
7760020939fSJ. Bruce Fields 	 * respond or cache a response.  This includes writes and setattrs
7770020939fSJ. Bruce Fields 	 * as well as the operations usually called "nonidempotent":
7780020939fSJ. Bruce Fields 	 */
7790020939fSJ. Bruce Fields 	OP_MODIFIES_SOMETHING = 1 << 5,
7800020939fSJ. Bruce Fields 	/*
7810020939fSJ. Bruce Fields 	 * Cache compounds containing these ops in the xid-based drc:
7820020939fSJ. Bruce Fields 	 * We use the DRC for compounds containing non-idempotent
7830020939fSJ. Bruce Fields 	 * operations, *except* those that are 4.1-specific (since
7840020939fSJ. Bruce Fields 	 * sessions provide their own EOS), and except for stateful
7850020939fSJ. Bruce Fields 	 * operations other than setclientid and setclientid_confirm
7860020939fSJ. Bruce Fields 	 * (since sequence numbers provide EOS for open, lock, etc in
7870020939fSJ. Bruce Fields 	 * the v4.0 case).
7880020939fSJ. Bruce Fields 	 */
7890020939fSJ. Bruce Fields 	OP_CACHEME = 1 << 6,
7900020939fSJ. Bruce Fields 	/*
7910020939fSJ. Bruce Fields 	 * These are ops which clear current state id.
7920020939fSJ. Bruce Fields 	 */
7930020939fSJ. Bruce Fields 	OP_CLEAR_STATEID = 1 << 7,
794b7571e4cSJ. Bruce Fields 	/* Most ops return only an error on failure; some may do more: */
795b7571e4cSJ. Bruce Fields 	OP_NONTRIVIAL_ERROR_ENCODE = 1 << 8,
7960020939fSJ. Bruce Fields };
7970020939fSJ. Bruce Fields 
7980020939fSJ. Bruce Fields struct nfsd4_operation {
7990020939fSJ. Bruce Fields 	__be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
8000020939fSJ. Bruce Fields 			union nfsd4_op_u *);
80134b1744cSJ. Bruce Fields 	void (*op_release)(union nfsd4_op_u *);
8020020939fSJ. Bruce Fields 	u32 op_flags;
8030020939fSJ. Bruce Fields 	char *op_name;
8040020939fSJ. Bruce Fields 	/* Try to get response size before operation */
8050020939fSJ. Bruce Fields 	u32 (*op_rsize_bop)(struct svc_rqst *, struct nfsd4_op *);
8060020939fSJ. Bruce Fields 	void (*op_get_currentstateid)(struct nfsd4_compound_state *,
8070020939fSJ. Bruce Fields 			union nfsd4_op_u *);
8080020939fSJ. Bruce Fields 	void (*op_set_currentstateid)(struct nfsd4_compound_state *,
8090020939fSJ. Bruce Fields 			union nfsd4_op_u *);
8100020939fSJ. Bruce Fields };
8110020939fSJ. Bruce Fields 
8120020939fSJ. Bruce Fields 
8139a74af21SBoaz Harrosh #endif
8149a74af21SBoaz Harrosh 
8159a74af21SBoaz Harrosh /*
8169a74af21SBoaz Harrosh  * Local variables:
8179a74af21SBoaz Harrosh  *  c-basic-offset: 8
8189a74af21SBoaz Harrosh  * End:
8199a74af21SBoaz Harrosh  */
820