linux/fs/nfsd/nfs4proc.c

/*
 *  Server-side procedures for NFSv4.
 *
 *  Copyright (c) 2002 The Regents of the University of Michigan.
 *  All rights reserved.
 *
 *  Kendrick Smith <[email protected]>
 *  Andy Adamson   <[email protected]>
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the University nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <linux/fs_struct.h>
#include <linux/file.h>
#include <linux/falloc.h>
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/namei.h>

#include <linux/sunrpc/addr.h>
#include <linux/nfs_ssc.h>

#include "idmap.h"
#include "cache.h"
#include "xdr4.h"
#include "vfs.h"
#include "current_stateid.h"
#include "netns.h"
#include "acl.h"
#include "pnfs.h"
#include "trace.h"

static bool inter_copy_offload_enable;
module_param(inter_copy_offload_enable, bool, 0644);
MODULE_PARM_DESC();

#ifdef CONFIG_NFSD_V4_2_INTER_SSC
static int nfsd4_ssc_umount_timeout =;		/* default to 15 mins */
module_param(nfsd4_ssc_umount_timeout, int, 0644);
MODULE_PARM_DESC();
#endif

#define NFSDDBG_FACILITY

static u32 nfsd_attrmask[] =;

static u32 nfsd41_ex_attrmask[] =;

static __be32
check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		   u32 *bmval, u32 *writable)
{}

static __be32
nfsd4_check_open_attributes(struct svc_rqst *rqstp,
	struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
{}

static int
is_create_with_attrs(struct nfsd4_open *open)
{}

static inline void
fh_dup2(struct svc_fh *dst, struct svc_fh *src)
{}

static __be32
do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, int accmode)
{}

static __be32 nfsd_check_obj_isreg(struct svc_fh *fh)
{}

static void nfsd4_set_open_owner_reply_cache(struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh *resfh)
{}

static inline bool nfsd4_create_is_exclusive(int createmode)
{}

static __be32
nfsd4_vfs_create(struct svc_fh *fhp, struct dentry *child,
		 struct nfsd4_open *open)
{}

/*
 * Implement NFSv4's unchecked, guarded, and exclusive create
 * semantics for regular files. Open state for this new file is
 * subsequently fabricated in nfsd4_process_open2().
 *
 * Upon return, caller must release @fhp and @resfhp.
 */
static __be32
nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
		  struct svc_fh *resfhp, struct nfsd4_open *open)
{}

/**
 * set_change_info - set up the change_info4 for a reply
 * @cinfo: pointer to nfsd4_change_info to be populated
 * @fhp: pointer to svc_fh to use as source
 *
 * Many operations in NFSv4 require change_info4 in the reply. This function
 * populates that from the info that we (should!) have already collected. In
 * the event that we didn't get any pre-attrs, just zero out both.
 */
static void
set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
{}

static __be32
do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh **resfh)
{}

static __be32
do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
{}

static void
copy_clientid(clientid_t *clid, struct nfsd4_session *session)
{}

static __be32
nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	   union nfsd4_op_u *u)
{}

/*
 * OPEN is the only seqid-mutating operation whose decoding can fail
 * with a seqid-mutating error (specifically, decoding of user names in
 * the attributes).  Therefore we have to do some processing to look up
 * the stateowner so that we can bump the seqid.
 */
static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_op *op)
{}

/*
 * filehandle-manipulating ops.
 */
static __be32
nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	    union nfsd4_op_u *u)
{}

static __be32
nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	    union nfsd4_op_u *u)
{}

static __be32
nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		union nfsd4_op_u *u)
{}

static __be32
nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		union nfsd4_op_u *u)
{}

static __be32
nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	     union nfsd4_op_u *u)
{}

/*
 * misc nfsv4 ops
 */
static __be32
nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	     union nfsd4_op_u *u)
{}

static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net)
{}

static __be32
nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	     union nfsd4_op_u *u)
{}

static __be32
nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	     union nfsd4_op_u *u)
{}

static __be32
nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	      union nfsd4_op_u *u)
{}

static __be32
nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	   union nfsd4_op_u *u)
{}

static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh)
{}

static __be32
nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	      union nfsd4_op_u *u)
{}

static __be32
nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	     union nfsd4_op_u *u)
{}

static __be32
nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	   union nfsd4_op_u *u)
{}


static void
nfsd4_read_release(union nfsd4_op_u *u)
{}

static __be32
nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	      union nfsd4_op_u *u)
{}

static __be32
nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	       union nfsd4_op_u *u)
{}

static __be32
nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	     union nfsd4_op_u *u)
{}

static __be32
nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	     union nfsd4_op_u *u)
{}

static __be32
nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	      union nfsd4_op_u *u)
{}

static __be32
nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		union nfsd4_op_u *u)
{}

static void
nfsd4_secinfo_release(union nfsd4_op_u *u)
{}

static void
nfsd4_secinfo_no_name_release(union nfsd4_op_u *u)
{}

static __be32
nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	      union nfsd4_op_u *u)
{}

static __be32
nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	    union nfsd4_op_u *u)
{}

static __be32
nfsd4_verify_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		  stateid_t *src_stateid, struct nfsd_file **src,
		  stateid_t *dst_stateid, struct nfsd_file **dst)
{}

static __be32
nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		union nfsd4_op_u *u)
{}

static void nfs4_put_copy(struct nfsd4_copy *copy)
{}

static void nfsd4_stop_copy(struct nfsd4_copy *copy)
{}

static struct nfsd4_copy *nfsd4_get_copy(struct nfs4_client *clp)
{}

void nfsd4_shutdown_copy(struct nfs4_client *clp)
{}
#ifdef CONFIG_NFSD_V4_2_INTER_SSC

extern struct file *nfs42_ssc_open(struct vfsmount *ss_mnt,
				   struct nfs_fh *src_fh,
				   nfs4_stateid *stateid);
extern void nfs42_ssc_close(struct file *filep);

extern void nfs_sb_deactive(struct super_block *sb);

#define NFSD42_INTERSSC_MOUNTOPS

/*
 * setup a work entry in the ssc delayed unmount list.
 */
static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr,
				  struct nfsd4_ssc_umount_item **nsui,
				  struct svc_rqst *rqstp)
{}

static void nfsd4_ssc_update_dul(struct nfsd_net *nn,
				 struct nfsd4_ssc_umount_item *nsui,
				 struct vfsmount *ss_mnt)
{}

static void nfsd4_ssc_cancel_dul(struct nfsd_net *nn,
				 struct nfsd4_ssc_umount_item *nsui)
{}

/*
 * Support one copy source server for now.
 */
static __be32
nfsd4_interssc_connect(struct nl4_server *nss, struct svc_rqst *rqstp,
		       struct nfsd4_ssc_umount_item **nsui)
{}

/*
 * Verify COPY destination stateid.
 *
 * Connect to the source server with NFSv4.1.
 * Create the source struct file for nfsd_copy_range.
 * Called with COPY cstate:
 *    SAVED_FH: source filehandle
 *    CURRENT_FH: destination filehandle
 */
static __be32
nfsd4_setup_inter_ssc(struct svc_rqst *rqstp,
		      struct nfsd4_compound_state *cstate,
		      struct nfsd4_copy *copy)
{}

static void
nfsd4_cleanup_inter_ssc(struct nfsd4_ssc_umount_item *nsui, struct file *filp,
			struct nfsd_file *dst)
{}

#else /* CONFIG_NFSD_V4_2_INTER_SSC */

static __be32
nfsd4_setup_inter_ssc(struct svc_rqst *rqstp,
		      struct nfsd4_compound_state *cstate,
		      struct nfsd4_copy *copy)
{
	return nfserr_inval;
}

static void
nfsd4_cleanup_inter_ssc(struct nfsd4_ssc_umount_item *nsui, struct file *filp,
			struct nfsd_file *dst)
{
}

static struct file *nfs42_ssc_open(struct vfsmount *ss_mnt,
				   struct nfs_fh *src_fh,
				   nfs4_stateid *stateid)
{
	return NULL;
}
#endif /* CONFIG_NFSD_V4_2_INTER_SSC */

static __be32
nfsd4_setup_intra_ssc(struct svc_rqst *rqstp,
		      struct nfsd4_compound_state *cstate,
		      struct nfsd4_copy *copy)
{}

static void nfsd4_cb_offload_release(struct nfsd4_callback *cb)
{}

static int nfsd4_cb_offload_done(struct nfsd4_callback *cb,
				 struct rpc_task *task)
{}

static const struct nfsd4_callback_ops nfsd4_cb_offload_ops =;

static void nfsd4_init_copy_res(struct nfsd4_copy *copy, bool sync)
{}

static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy,
				     struct file *dst,
				     struct file *src)
{}

static __be32 nfsd4_do_copy(struct nfsd4_copy *copy,
			    struct file *src, struct file *dst,
			    bool sync)
{}

static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst)
{}

static void release_copy_files(struct nfsd4_copy *copy)
{}

static void cleanup_async_copy(struct nfsd4_copy *copy)
{}

static void nfsd4_send_cb_offload(struct nfsd4_copy *copy)
{}

/**
 * nfsd4_do_async_copy - kthread function for background server-side COPY
 * @data: arguments for COPY operation
 *
 * Return values:
 *   %0: Copy operation is done.
 */
static int nfsd4_do_async_copy(void *data)
{}

static __be32
nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		union nfsd4_op_u *u)
{}

static struct nfsd4_copy *
find_async_copy_locked(struct nfs4_client *clp, stateid_t *stateid)
{}

static struct nfsd4_copy *
find_async_copy(struct nfs4_client *clp, stateid_t *stateid)
{}

static __be32
nfsd4_offload_cancel(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
		     union nfsd4_op_u *u)
{}

static __be32
nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		  union nfsd4_op_u *u)
{}

static __be32
nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		struct nfsd4_fallocate *fallocate, int flags)
{}

static __be32
nfsd4_offload_status(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
		     union nfsd4_op_u *u)
{}

static __be32
nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	       union nfsd4_op_u *u)
{}

static __be32
nfsd4_deallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		 union nfsd4_op_u *u)
{}

static __be32
nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	   union nfsd4_op_u *u)
{}

/* This routine never returns NFS_OK!  If there are no other errors, it
 * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the
 * attributes matched.  VERIFY is implemented by mapping NFSERR_SAME
 * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK.
 */
static __be32
_nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	     struct nfsd4_verify *verify)
{}

static __be32
nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	      union nfsd4_op_u *u)
{}

static __be32
nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	     union nfsd4_op_u *u)
{}

static __be32
nfsd4_get_dir_delegation(struct svc_rqst *rqstp,
			 struct nfsd4_compound_state *cstate,
			 union nfsd4_op_u *u)
{}

#ifdef CONFIG_NFSD_PNFS
static const struct nfsd4_layout_ops *
nfsd4_layout_verify(struct svc_export *exp, unsigned int layout_type)
{}

static __be32
nfsd4_getdeviceinfo(struct svc_rqst *rqstp,
		struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
{}

static void
nfsd4_getdeviceinfo_release(union nfsd4_op_u *u)
{}

static __be32
nfsd4_layoutget(struct svc_rqst *rqstp,
		struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
{}

static void
nfsd4_layoutget_release(union nfsd4_op_u *u)
{}

static __be32
nfsd4_layoutcommit(struct svc_rqst *rqstp,
		struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
{}

static __be32
nfsd4_layoutreturn(struct svc_rqst *rqstp,
		struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
{}
#endif /* CONFIG_NFSD_PNFS */

static __be32
nfsd4_getxattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	       union nfsd4_op_u *u)
{}

static __be32
nfsd4_setxattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	   union nfsd4_op_u *u)
{}

static __be32
nfsd4_listxattrs(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	   union nfsd4_op_u *u)
{}

static __be32
nfsd4_removexattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	   union nfsd4_op_u *u)
{}

/*
 * NULL call.
 */
static __be32
nfsd4_proc_null(struct svc_rqst *rqstp)
{}

static inline void nfsd4_increment_op_stats(struct nfsd_net *nn, u32 opnum)
{}

static const struct nfsd4_operation nfsd4_ops[];

static const char *nfsd4_op_name(unsigned opnum);

/*
 * Enforce NFSv4.1 COMPOUND ordering rules:
 *
 * Also note, enforced elsewhere:
 *	- SEQUENCE other than as first op results in
 *	  NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().)
 *	- BIND_CONN_TO_SESSION must be the only op in its compound.
 *	  (Enforced in nfsd4_bind_conn_to_session().)
 *	- DESTROY_SESSION must be the final operation in a compound, if
 *	  sessionid's in SEQUENCE and DESTROY_SESSION are the same.
 *	  (Enforced in nfsd4_destroy_session().)
 */
static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args)
{}

const struct nfsd4_operation *OPDESC(struct nfsd4_op *op)
{}

bool nfsd4_cache_this_op(struct nfsd4_op *op)
{}

static bool need_wrongsec_check(struct svc_rqst *rqstp)
{}

#ifdef CONFIG_NFSD_V4_2_INTER_SSC
static void
check_if_stalefh_allowed(struct nfsd4_compoundargs *args)
{}
#else
static void
check_if_stalefh_allowed(struct nfsd4_compoundargs *args)
{
}
#endif

/*
 * COMPOUND call.
 */
static __be32
nfsd4_proc_compound(struct svc_rqst *rqstp)
{}

#define op_encode_hdr_size
#define op_encode_stateid_maxsz
#define op_encode_verifier_maxsz
#define op_encode_change_info_maxsz
#define nfs4_fattr_bitmap_maxsz

/* We'll fall back on returning no lockowner if run out of space: */
#define op_encode_lockowner_maxsz
#define op_encode_lock_denied_maxsz

#define nfs4_owner_maxsz

#define op_encode_ace_maxsz
#define op_encode_delegation_maxsz

#define op_encode_channel_attrs_maxsz

/*
 * The _rsize() helpers are invoked by the NFSv4 COMPOUND decoder, which
 * is called before sunrpc sets rq_res.buflen. Thus we have to compute
 * the maximum payload size here, based on transport limits and the size
 * of the remaining space in the rq_pages array.
 */
static u32 nfsd4_max_payload(const struct svc_rqst *rqstp)
{}

static u32 nfsd4_only_status_rsize(const struct svc_rqst *rqstp,
				   const struct nfsd4_op *op)
{}

static u32 nfsd4_status_stateid_rsize(const struct svc_rqst *rqstp,
				      const struct nfsd4_op *op)
{}

static u32 nfsd4_access_rsize(const struct svc_rqst *rqstp,
			      const struct nfsd4_op *op)
{}

static u32 nfsd4_commit_rsize(const struct svc_rqst *rqstp,
			      const struct nfsd4_op *op)
{}

static u32 nfsd4_create_rsize(const struct svc_rqst *rqstp,
			      const struct nfsd4_op *op)
{}

/*
 * Note since this is an idempotent operation we won't insist on failing
 * the op prematurely if the estimate is too large.  We may turn off splice
 * reads unnecessarily.
 */
static u32 nfsd4_getattr_rsize(const struct svc_rqst *rqstp,
			       const struct nfsd4_op *op)
{}

static u32 nfsd4_getfh_rsize(const struct svc_rqst *rqstp,
			     const struct nfsd4_op *op)
{}

static u32 nfsd4_link_rsize(const struct svc_rqst *rqstp,
			    const struct nfsd4_op *op)
{}

static u32 nfsd4_lock_rsize(const struct svc_rqst *rqstp,
			    const struct nfsd4_op *op)
{}

static u32 nfsd4_open_rsize(const struct svc_rqst *rqstp,
			    const struct nfsd4_op *op)
{}

static u32 nfsd4_read_rsize(const struct svc_rqst *rqstp,
			    const struct nfsd4_op *op)
{}

static u32 nfsd4_read_plus_rsize(const struct svc_rqst *rqstp,
				 const struct nfsd4_op *op)
{}

static u32 nfsd4_readdir_rsize(const struct svc_rqst *rqstp,
			       const struct nfsd4_op *op)
{}

static u32 nfsd4_readlink_rsize(const struct svc_rqst *rqstp,
				const struct nfsd4_op *op)
{}

static u32 nfsd4_remove_rsize(const struct svc_rqst *rqstp,
			      const struct nfsd4_op *op)
{}

static u32 nfsd4_rename_rsize(const struct svc_rqst *rqstp,
			      const struct nfsd4_op *op)
{}

static u32 nfsd4_sequence_rsize(const struct svc_rqst *rqstp,
				const struct nfsd4_op *op)
{}

static u32 nfsd4_test_stateid_rsize(const struct svc_rqst *rqstp,
				    const struct nfsd4_op *op)
{}

static u32 nfsd4_setattr_rsize(const struct svc_rqst *rqstp,
			       const struct nfsd4_op *op)
{}

static u32 nfsd4_secinfo_rsize(const struct svc_rqst *rqstp,
			       const struct nfsd4_op *op)
{}

static u32 nfsd4_setclientid_rsize(const struct svc_rqst *rqstp,
				   const struct nfsd4_op *op)
{}

static u32 nfsd4_write_rsize(const struct svc_rqst *rqstp,
			     const struct nfsd4_op *op)
{}

static u32 nfsd4_exchange_id_rsize(const struct svc_rqst *rqstp,
				   const struct nfsd4_op *op)
{}

static u32 nfsd4_bind_conn_to_session_rsize(const struct svc_rqst *rqstp,
					    const struct nfsd4_op *op)
{}

static u32 nfsd4_create_session_rsize(const struct svc_rqst *rqstp,
				      const struct nfsd4_op *op)
{}

static u32 nfsd4_copy_rsize(const struct svc_rqst *rqstp,
			    const struct nfsd4_op *op)
{}

static u32 nfsd4_offload_status_rsize(const struct svc_rqst *rqstp,
				      const struct nfsd4_op *op)
{}

static u32 nfsd4_copy_notify_rsize(const struct svc_rqst *rqstp,
				   const struct nfsd4_op *op)
{}

static u32 nfsd4_get_dir_delegation_rsize(const struct svc_rqst *rqstp,
					  const struct nfsd4_op *op)
{}

#ifdef CONFIG_NFSD_PNFS
static u32 nfsd4_getdeviceinfo_rsize(const struct svc_rqst *rqstp,
				     const struct nfsd4_op *op)
{}

/*
 * At this stage we don't really know what layout driver will handle the request,
 * so we need to define an arbitrary upper bound here.
 */
#define MAX_LAYOUT_SIZE
static u32 nfsd4_layoutget_rsize(const struct svc_rqst *rqstp,
				 const struct nfsd4_op *op)
{}

static u32 nfsd4_layoutcommit_rsize(const struct svc_rqst *rqstp,
				    const struct nfsd4_op *op)
{}

static u32 nfsd4_layoutreturn_rsize(const struct svc_rqst *rqstp,
				    const struct nfsd4_op *op)
{}
#endif /* CONFIG_NFSD_PNFS */


static u32 nfsd4_seek_rsize(const struct svc_rqst *rqstp,
			    const struct nfsd4_op *op)
{}

static u32 nfsd4_getxattr_rsize(const struct svc_rqst *rqstp,
				const struct nfsd4_op *op)
{}

static u32 nfsd4_setxattr_rsize(const struct svc_rqst *rqstp,
				const struct nfsd4_op *op)
{}
static u32 nfsd4_listxattrs_rsize(const struct svc_rqst *rqstp,
				  const struct nfsd4_op *op)
{}

static u32 nfsd4_removexattr_rsize(const struct svc_rqst *rqstp,
				   const struct nfsd4_op *op)
{}


static const struct nfsd4_operation nfsd4_ops[] =;

/**
 * nfsd4_spo_must_allow - Determine if the compound op contains an
 * operation that is allowed to be sent with machine credentials
 *
 * @rqstp: a pointer to the struct svc_rqst
 *
 * Checks to see if the compound contains a spo_must_allow op
 * and confirms that it was sent with the proper machine creds.
 */

bool nfsd4_spo_must_allow(struct svc_rqst *rqstp)
{}

int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op)
{}

void warn_on_nonidempotent_op(struct nfsd4_op *op)
{}

static const char *nfsd4_op_name(unsigned opnum)
{}

static const struct svc_procedure nfsd_procedures4[2] =;

static DEFINE_PER_CPU_ALIGNED(unsigned long,
			      nfsd_count4[ARRAY_SIZE(nfsd_procedures4)]);
const struct svc_version nfsd_version4 =;