summaryrefslogtreecommitdiffstats
path: root/include/linux/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/nfsd')
-rw-r--r--include/linux/nfsd/auth.h27
-rw-r--r--include/linux/nfsd/cache.h81
-rw-r--r--include/linux/nfsd/const.h45
-rw-r--r--include/linux/nfsd/debug.h48
-rw-r--r--include/linux/nfsd/export.h137
-rw-r--r--include/linux/nfsd/interface.h13
-rw-r--r--include/linux/nfsd/nfsd.h311
-rw-r--r--include/linux/nfsd/nfsfh.h343
-rw-r--r--include/linux/nfsd/state.h298
-rw-r--r--include/linux/nfsd/stats.h44
-rw-r--r--include/linux/nfsd/syscall.h125
-rw-r--r--include/linux/nfsd/xdr.h172
-rw-r--r--include/linux/nfsd/xdr3.h321
-rw-r--r--include/linux/nfsd/xdr4.h463
14 files changed, 2428 insertions, 0 deletions
diff --git a/include/linux/nfsd/auth.h b/include/linux/nfsd/auth.h
new file mode 100644
index 000000000000..0fb9f7212195
--- /dev/null
+++ b/include/linux/nfsd/auth.h
@@ -0,0 +1,27 @@
+/*
+ * include/linux/nfsd/auth.h
+ *
+ * nfsd-specific authentication stuff.
+ * uid/gid mapping not yet implemented.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef LINUX_NFSD_AUTH_H
+#define LINUX_NFSD_AUTH_H
+
+#ifdef __KERNEL__
+
+#define nfsd_luid(rq, uid) ((u32)(uid))
+#define nfsd_lgid(rq, gid) ((u32)(gid))
+#define nfsd_ruid(rq, uid) ((u32)(uid))
+#define nfsd_rgid(rq, gid) ((u32)(gid))
+
+/*
+ * Set the current process's fsuid/fsgid etc to those of the NFS
+ * client user
+ */
+int nfsd_setuser(struct svc_rqst *, struct svc_export *);
+
+#endif /* __KERNEL__ */
+#endif /* LINUX_NFSD_AUTH_H */
diff --git a/include/linux/nfsd/cache.h b/include/linux/nfsd/cache.h
new file mode 100644
index 000000000000..c3a3557c2a5b
--- /dev/null
+++ b/include/linux/nfsd/cache.h
@@ -0,0 +1,81 @@
+/*
+ * include/linux/nfsd/cache.h
+ *
+ * Request reply cache. This was heavily inspired by the
+ * implementation in 4.3BSD/4.4BSD.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef NFSCACHE_H
+#define NFSCACHE_H
+
+#ifdef __KERNEL__
+#include <linux/in.h>
+#include <linux/uio.h>
+
+/*
+ * Representation of a reply cache entry. The first two members *must*
+ * be hash_next and hash_prev.
+ */
+struct svc_cacherep {
+ struct hlist_node c_hash;
+ struct list_head c_lru;
+
+ unsigned char c_state, /* unused, inprog, done */
+ c_type, /* status, buffer */
+ c_secure : 1; /* req came from port < 1024 */
+ struct sockaddr_in c_addr;
+ u32 c_xid;
+ u32 c_prot;
+ u32 c_proc;
+ u32 c_vers;
+ unsigned long c_timestamp;
+ union {
+ struct kvec u_vec;
+ u32 u_status;
+ } c_u;
+};
+
+#define c_replvec c_u.u_vec
+#define c_replstat c_u.u_status
+
+/* cache entry states */
+enum {
+ RC_UNUSED,
+ RC_INPROG,
+ RC_DONE
+};
+
+/* return values */
+enum {
+ RC_DROPIT,
+ RC_REPLY,
+ RC_DOIT,
+ RC_INTR
+};
+
+/*
+ * Cache types.
+ * We may want to add more types one day, e.g. for diropres and
+ * attrstat replies. Using cache entries with fixed length instead
+ * of buffer pointers may be more efficient.
+ */
+enum {
+ RC_NOCACHE,
+ RC_REPLSTAT,
+ RC_REPLBUFF,
+};
+
+/*
+ * If requests are retransmitted within this interval, they're dropped.
+ */
+#define RC_DELAY (HZ/5)
+
+void nfsd_cache_init(void);
+void nfsd_cache_shutdown(void);
+int nfsd_cache_lookup(struct svc_rqst *, int);
+void nfsd_cache_update(struct svc_rqst *, int, u32 *);
+
+#endif /* __KERNEL__ */
+#endif /* NFSCACHE_H */
diff --git a/include/linux/nfsd/const.h b/include/linux/nfsd/const.h
new file mode 100644
index 000000000000..b75bb1b38d09
--- /dev/null
+++ b/include/linux/nfsd/const.h
@@ -0,0 +1,45 @@
+/*
+ * include/linux/nfsd/const.h
+ *
+ * Various constants related to NFS.
+ *
+ * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_NFSD_CONST_H
+#define _LINUX_NFSD_CONST_H
+
+#include <linux/nfs.h>
+#include <linux/nfs2.h>
+#include <linux/nfs3.h>
+#include <linux/nfs4.h>
+
+/*
+ * Maximum protocol version supported by knfsd
+ */
+#define NFSSVC_MAXVERS 3
+
+/*
+ * Maximum blocksize supported by daemon currently at 32K
+ */
+#define NFSSVC_MAXBLKSIZE (32*1024)
+
+#ifdef __KERNEL__
+
+#ifndef NFS_SUPER_MAGIC
+# define NFS_SUPER_MAGIC 0x6969
+#endif
+
+#define NFSD_BUFSIZE (1024 + NFSSVC_MAXBLKSIZE)
+
+#ifdef CONFIG_NFSD_V4
+# define NFSSVC_XDRSIZE NFS4_SVC_XDRSIZE
+#elif defined(CONFIG_NFSD_V3)
+# define NFSSVC_XDRSIZE NFS3_SVC_XDRSIZE
+#else
+# define NFSSVC_XDRSIZE NFS2_SVC_XDRSIZE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_NFSD_CONST_H */
diff --git a/include/linux/nfsd/debug.h b/include/linux/nfsd/debug.h
new file mode 100644
index 000000000000..ee4aa91788e7
--- /dev/null
+++ b/include/linux/nfsd/debug.h
@@ -0,0 +1,48 @@
+/*
+ * linux/include/linux/nfsd/debug.h
+ *
+ * Debugging-related stuff for nfsd
+ *
+ * Copyright (C) 1995 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef LINUX_NFSD_DEBUG_H
+#define LINUX_NFSD_DEBUG_H
+
+#include <linux/sunrpc/debug.h>
+
+/*
+ * Enable debugging for nfsd.
+ * Requires RPC_DEBUG.
+ */
+#ifdef RPC_DEBUG
+# define NFSD_DEBUG 1
+#endif
+
+/*
+ * knfsd debug flags
+ */
+#define NFSDDBG_SOCK 0x0001
+#define NFSDDBG_FH 0x0002
+#define NFSDDBG_EXPORT 0x0004
+#define NFSDDBG_SVC 0x0008
+#define NFSDDBG_PROC 0x0010
+#define NFSDDBG_FILEOP 0x0020
+#define NFSDDBG_AUTH 0x0040
+#define NFSDDBG_REPCACHE 0x0080
+#define NFSDDBG_XDR 0x0100
+#define NFSDDBG_LOCKD 0x0200
+#define NFSDDBG_ALL 0x7FFF
+#define NFSDDBG_NOCHANGE 0xFFFF
+
+
+#ifdef __KERNEL__
+# undef ifdebug
+# ifdef NFSD_DEBUG
+# define ifdebug(flag) if (nfsd_debug & NFSDDBG_##flag)
+# else
+# define ifdebug(flag) if (0)
+# endif
+#endif /* __KERNEL__ */
+
+#endif /* LINUX_NFSD_DEBUG_H */
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
new file mode 100644
index 000000000000..6bad4766d3d9
--- /dev/null
+++ b/include/linux/nfsd/export.h
@@ -0,0 +1,137 @@
+/*
+ * include/linux/nfsd/export.h
+ *
+ * Public declarations for NFS exports. The definitions for the
+ * syscall interface are in nfsctl.h
+ *
+ * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef NFSD_EXPORT_H
+#define NFSD_EXPORT_H
+
+#include <asm/types.h>
+#ifdef __KERNEL__
+# include <linux/types.h>
+# include <linux/in.h>
+#endif
+
+/*
+ * Important limits for the exports stuff.
+ */
+#define NFSCLNT_IDMAX 1024
+#define NFSCLNT_ADDRMAX 16
+#define NFSCLNT_KEYMAX 32
+
+/*
+ * Export flags.
+ */
+#define NFSEXP_READONLY 0x0001
+#define NFSEXP_INSECURE_PORT 0x0002
+#define NFSEXP_ROOTSQUASH 0x0004
+#define NFSEXP_ALLSQUASH 0x0008
+#define NFSEXP_ASYNC 0x0010
+#define NFSEXP_GATHERED_WRITES 0x0020
+/* 40 80 100 currently unused */
+#define NFSEXP_NOHIDE 0x0200
+#define NFSEXP_NOSUBTREECHECK 0x0400
+#define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */
+#define NFSEXP_MSNFS 0x1000 /* do silly things that MS clients expect */
+#define NFSEXP_FSID 0x2000
+#define NFSEXP_CROSSMOUNT 0x4000
+#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */
+#define NFSEXP_ALLFLAGS 0xFE3F
+
+
+#ifdef __KERNEL__
+
+struct svc_export {
+ struct cache_head h;
+ struct auth_domain * ex_client;
+ int ex_flags;
+ struct vfsmount * ex_mnt;
+ struct dentry * ex_dentry;
+ uid_t ex_anon_uid;
+ gid_t ex_anon_gid;
+ int ex_fsid;
+};
+
+/* an "export key" (expkey) maps a filehandlefragement to an
+ * svc_export for a given client. There can be two per export, one
+ * for type 0 (dev/ino), one for type 1 (fsid)
+ */
+struct svc_expkey {
+ struct cache_head h;
+
+ struct auth_domain * ek_client;
+ int ek_fsidtype;
+ u32 ek_fsid[3];
+
+ struct svc_export * ek_export;
+};
+
+#define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT))
+#define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
+#define EX_RDONLY(exp) ((exp)->ex_flags & NFSEXP_READONLY)
+#define EX_NOHIDE(exp) ((exp)->ex_flags & NFSEXP_NOHIDE)
+#define EX_WGATHER(exp) ((exp)->ex_flags & NFSEXP_GATHERED_WRITES)
+
+
+/*
+ * Function declarations
+ */
+void nfsd_export_init(void);
+void nfsd_export_shutdown(void);
+void nfsd_export_flush(void);
+void exp_readlock(void);
+void exp_readunlock(void);
+struct svc_expkey * exp_find_key(struct auth_domain *clp,
+ int fsid_type, u32 *fsidv,
+ struct cache_req *reqp);
+struct svc_export * exp_get_by_name(struct auth_domain *clp,
+ struct vfsmount *mnt,
+ struct dentry *dentry,
+ struct cache_req *reqp);
+struct svc_export * exp_parent(struct auth_domain *clp,
+ struct vfsmount *mnt,
+ struct dentry *dentry,
+ struct cache_req *reqp);
+int exp_rootfh(struct auth_domain *,
+ char *path, struct knfsd_fh *, int maxsize);
+int exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp, struct cache_req *creq);
+int nfserrno(int errno);
+
+extern void expkey_put(struct cache_head *item, struct cache_detail *cd);
+extern void svc_export_put(struct cache_head *item, struct cache_detail *cd);
+extern struct cache_detail svc_export_cache, svc_expkey_cache;
+
+static inline void exp_put(struct svc_export *exp)
+{
+ svc_export_put(&exp->h, &svc_export_cache);
+}
+
+static inline void exp_get(struct svc_export *exp)
+{
+ cache_get(&exp->h);
+}
+static inline struct svc_export *
+exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
+ struct cache_req *reqp)
+{
+ struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv, reqp);
+ if (ek && !IS_ERR(ek)) {
+ struct svc_export *exp = ek->ek_export;
+ int err;
+ exp_get(exp);
+ expkey_put(&ek->h, &svc_expkey_cache);
+ if ((err = cache_check(&svc_export_cache, &exp->h, reqp)))
+ exp = ERR_PTR(err);
+ return exp;
+ } else
+ return ERR_PTR(PTR_ERR(ek));
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* NFSD_EXPORT_H */
+
diff --git a/include/linux/nfsd/interface.h b/include/linux/nfsd/interface.h
new file mode 100644
index 000000000000..af0979704afb
--- /dev/null
+++ b/include/linux/nfsd/interface.h
@@ -0,0 +1,13 @@
+/*
+ * include/linux/nfsd/interface.h
+ *
+ * defines interface between nfsd and other bits of
+ * the kernel. Particularly filesystems (eventually).
+ *
+ * Copyright (C) 2000 Neil Brown <neilb@cse.unsw.edu.au>
+ */
+
+#ifndef LINUX_NFSD_INTERFACE_H
+#define LINUX_NFSD_INTERFACE_H
+
+#endif /* LINUX_NFSD_INTERFACE_H */
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
new file mode 100644
index 000000000000..8f85d9a59607
--- /dev/null
+++ b/include/linux/nfsd/nfsd.h
@@ -0,0 +1,311 @@
+/*
+ * linux/include/linux/nfsd/nfsd.h
+ *
+ * Hodge-podge collection of knfsd-related stuff.
+ * I will sort this out later.
+ *
+ * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef LINUX_NFSD_NFSD_H
+#define LINUX_NFSD_NFSD_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <linux/dirent.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+
+#include <linux/nfsd/debug.h>
+#include <linux/nfsd/nfsfh.h>
+#include <linux/nfsd/export.h>
+#include <linux/nfsd/auth.h>
+#include <linux/nfsd/stats.h>
+#include <linux/nfsd/interface.h>
+/*
+ * nfsd version
+ */
+#define NFSD_VERSION "0.5"
+#define NFSD_SUPPORTED_MINOR_VERSION 0
+
+#ifdef __KERNEL__
+/*
+ * Special flags for nfsd_permission. These must be different from MAY_READ,
+ * MAY_WRITE, and MAY_EXEC.
+ */
+#define MAY_NOP 0
+#define MAY_SATTR 8
+#define MAY_TRUNC 16
+#define MAY_LOCK 32
+#define MAY_OWNER_OVERRIDE 64
+#define MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/
+#if (MAY_SATTR | MAY_TRUNC | MAY_LOCK | MAY_OWNER_OVERRIDE | MAY_LOCAL_ACCESS) & (MAY_READ | MAY_WRITE | MAY_EXEC)
+# error "please use a different value for MAY_SATTR or MAY_TRUNC or MAY_LOCK or MAY_LOCAL_ACCESS or MAY_OWNER_OVERRIDE."
+#endif
+#define MAY_CREATE (MAY_EXEC|MAY_WRITE)
+#define MAY_REMOVE (MAY_EXEC|MAY_WRITE|MAY_TRUNC)
+
+/*
+ * Callback function for readdir
+ */
+struct readdir_cd {
+ int err; /* 0, nfserr, or nfserr_eof */
+};
+typedef int (*encode_dent_fn)(struct readdir_cd *, const char *,
+ int, loff_t, ino_t, unsigned int);
+typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int);
+
+extern struct svc_program nfsd_program;
+extern struct svc_version nfsd_version2, nfsd_version3,
+ nfsd_version4;
+
+/*
+ * Function prototypes.
+ */
+int nfsd_svc(unsigned short port, int nrservs);
+int nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp);
+
+/* nfsd/vfs.c */
+int fh_lock_parent(struct svc_fh *, struct dentry *);
+int nfsd_racache_init(int);
+void nfsd_racache_shutdown(void);
+int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
+ struct svc_export **expp);
+int nfsd_lookup(struct svc_rqst *, struct svc_fh *,
+ const char *, int, struct svc_fh *);
+int nfsd_setattr(struct svc_rqst *, struct svc_fh *,
+ struct iattr *, int, time_t);
+#ifdef CONFIG_NFSD_V4
+int nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
+ struct nfs4_acl *);
+int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **);
+#endif /* CONFIG_NFSD_V4 */
+int nfsd_create(struct svc_rqst *, struct svc_fh *,
+ char *name, int len, struct iattr *attrs,
+ int type, dev_t rdev, struct svc_fh *res);
+#ifdef CONFIG_NFSD_V3
+int nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
+int nfsd_create_v3(struct svc_rqst *, struct svc_fh *,
+ char *name, int len, struct iattr *attrs,
+ struct svc_fh *res, int createmode,
+ u32 *verifier, int *truncp);
+int nfsd_commit(struct svc_rqst *, struct svc_fh *,
+ loff_t, unsigned long);
+#endif /* CONFIG_NFSD_V3 */
+int nfsd_open(struct svc_rqst *, struct svc_fh *, int,
+ int, struct file **);
+void nfsd_close(struct file *);
+int nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *,
+ loff_t, struct kvec *, int, unsigned long *);
+int nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
+ loff_t, struct kvec *,int, unsigned long, int *);
+int nfsd_readlink(struct svc_rqst *, struct svc_fh *,
+ char *, int *);
+int nfsd_symlink(struct svc_rqst *, struct svc_fh *,
+ char *name, int len, char *path, int plen,
+ struct svc_fh *res, struct iattr *);
+int nfsd_link(struct svc_rqst *, struct svc_fh *,
+ char *, int, struct svc_fh *);
+int nfsd_rename(struct svc_rqst *,
+ struct svc_fh *, char *, int,
+ struct svc_fh *, char *, int);
+int nfsd_remove(struct svc_rqst *,
+ struct svc_fh *, char *, int);
+int nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type,
+ char *name, int len);
+int nfsd_truncate(struct svc_rqst *, struct svc_fh *,
+ unsigned long size);
+int nfsd_readdir(struct svc_rqst *, struct svc_fh *,
+ loff_t *, struct readdir_cd *, encode_dent_fn);
+int nfsd_statfs(struct svc_rqst *, struct svc_fh *,
+ struct kstatfs *);
+
+int nfsd_notify_change(struct inode *, struct iattr *);
+int nfsd_permission(struct svc_export *, struct dentry *, int);
+
+
+/*
+ * NFSv4 State
+ */
+#ifdef CONFIG_NFSD_V4
+int nfs4_state_init(void);
+void nfs4_state_shutdown(void);
+time_t nfs4_lease_time(void);
+void nfs4_reset_lease(time_t leasetime);
+#else
+static inline int nfs4_state_init(void){return 0;}
+static inline void nfs4_state_shutdown(void){}
+static inline time_t nfs4_lease_time(void){return 0;}
+static inline void nfs4_reset_lease(time_t leasetime){}
+#endif
+
+/*
+ * lockd binding
+ */
+void nfsd_lockd_init(void);
+void nfsd_lockd_shutdown(void);
+
+
+/*
+ * These macros provide pre-xdr'ed values for faster operation.
+ */
+#define nfs_ok __constant_htonl(NFS_OK)
+#define nfserr_perm __constant_htonl(NFSERR_PERM)
+#define nfserr_noent __constant_htonl(NFSERR_NOENT)
+#define nfserr_io __constant_htonl(NFSERR_IO)
+#define nfserr_nxio __constant_htonl(NFSERR_NXIO)
+#define nfserr_eagain __constant_htonl(NFSERR_EAGAIN)
+#define nfserr_acces __constant_htonl(NFSERR_ACCES)
+#define nfserr_exist __constant_htonl(NFSERR_EXIST)
+#define nfserr_xdev __constant_htonl(NFSERR_XDEV)
+#define nfserr_nodev __constant_htonl(NFSERR_NODEV)
+#define nfserr_notdir __constant_htonl(NFSERR_NOTDIR)
+#define nfserr_isdir __constant_htonl(NFSERR_ISDIR)
+#define nfserr_inval __constant_htonl(NFSERR_INVAL)
+#define nfserr_fbig __constant_htonl(NFSERR_FBIG)
+#define nfserr_nospc __constant_htonl(NFSERR_NOSPC)
+#define nfserr_rofs __constant_htonl(NFSERR_ROFS)
+#define nfserr_mlink __constant_htonl(NFSERR_MLINK)
+#define nfserr_opnotsupp __constant_htonl(NFSERR_OPNOTSUPP)
+#define nfserr_nametoolong __constant_htonl(NFSERR_NAMETOOLONG)
+#define nfserr_notempty __constant_htonl(NFSERR_NOTEMPTY)
+#define nfserr_dquot __constant_htonl(NFSERR_DQUOT)
+#define nfserr_stale __constant_htonl(NFSERR_STALE)
+#define nfserr_remote __constant_htonl(NFSERR_REMOTE)
+#define nfserr_wflush __constant_htonl(NFSERR_WFLUSH)
+#define nfserr_badhandle __constant_htonl(NFSERR_BADHANDLE)
+#define nfserr_notsync __constant_htonl(NFSERR_NOT_SYNC)
+#define nfserr_badcookie __constant_htonl(NFSERR_BAD_COOKIE)
+#define nfserr_notsupp __constant_htonl(NFSERR_NOTSUPP)
+#define nfserr_toosmall __constant_htonl(NFSERR_TOOSMALL)
+#define nfserr_serverfault __constant_htonl(NFSERR_SERVERFAULT)
+#define nfserr_badtype __constant_htonl(NFSERR_BADTYPE)
+#define nfserr_jukebox __constant_htonl(NFSERR_JUKEBOX)
+#define nfserr_denied __constant_htonl(NFSERR_DENIED)
+#define nfserr_deadlock __constant_htonl(NFSERR_DEADLOCK)
+#define nfserr_expired __constant_htonl(NFSERR_EXPIRED)
+#define nfserr_bad_cookie __constant_htonl(NFSERR_BAD_COOKIE)
+#define nfserr_same __constant_htonl(NFSERR_SAME)
+#define nfserr_clid_inuse __constant_htonl(NFSERR_CLID_INUSE)
+#define nfserr_stale_clientid __constant_htonl(NFSERR_STALE_CLIENTID)
+#define nfserr_resource __constant_htonl(NFSERR_RESOURCE)
+#define nfserr_nofilehandle __constant_htonl(NFSERR_NOFILEHANDLE)
+#define nfserr_minor_vers_mismatch __constant_htonl(NFSERR_MINOR_VERS_MISMATCH)
+#define nfserr_share_denied __constant_htonl(NFSERR_SHARE_DENIED)
+#define nfserr_stale_stateid __constant_htonl(NFSERR_STALE_STATEID)
+#define nfserr_old_stateid __constant_htonl(NFSERR_OLD_STATEID)
+#define nfserr_bad_stateid __constant_htonl(NFSERR_BAD_STATEID)
+#define nfserr_bad_seqid __constant_htonl(NFSERR_BAD_SEQID)
+#define nfserr_symlink __constant_htonl(NFSERR_SYMLINK)
+#define nfserr_not_same __constant_htonl(NFSERR_NOT_SAME)
+#define nfserr_restorefh __constant_htonl(NFSERR_RESTOREFH)
+#define nfserr_attrnotsupp __constant_htonl(NFSERR_ATTRNOTSUPP)
+#define nfserr_bad_xdr __constant_htonl(NFSERR_BAD_XDR)
+#define nfserr_openmode __constant_htonl(NFSERR_OPENMODE)
+#define nfserr_locks_held __constant_htonl(NFSERR_LOCKS_HELD)
+#define nfserr_op_illegal __constant_htonl(NFSERR_OP_ILLEGAL)
+#define nfserr_grace __constant_htonl(NFSERR_GRACE)
+#define nfserr_no_grace __constant_htonl(NFSERR_NO_GRACE)
+#define nfserr_reclaim_bad __constant_htonl(NFSERR_RECLAIM_BAD)
+#define nfserr_badname __constant_htonl(NFSERR_BADNAME)
+#define nfserr_cb_path_down __constant_htonl(NFSERR_CB_PATH_DOWN)
+
+/* error codes for internal use */
+/* if a request fails due to kmalloc failure, it gets dropped.
+ * Client should resend eventually
+ */
+#define nfserr_dropit __constant_htonl(30000)
+/* end-of-file indicator in readdir */
+#define nfserr_eof __constant_htonl(30001)
+
+/* Check for dir entries '.' and '..' */
+#define isdotent(n, l) (l < 3 && n[0] == '.' && (l == 1 || n[1] == '.'))
+
+/*
+ * Time of server startup
+ */
+extern struct timeval nfssvc_boot;
+
+static inline int is_fsid(struct svc_fh *fh, struct knfsd_fh *reffh)
+{
+ if (fh->fh_export->ex_flags & NFSEXP_FSID) {
+ struct vfsmount *mnt = fh->fh_export->ex_mnt;
+ if (!old_valid_dev(mnt->mnt_sb->s_dev) ||
+ (reffh->fh_version == 1 && reffh->fh_fsid_type == 1))
+ return 1;
+ }
+ return 0;
+}
+
+
+#ifdef CONFIG_NFSD_V4
+
+/* before processing a COMPOUND operation, we have to check that there
+ * is enough space in the buffer for XDR encode to succeed. otherwise,
+ * we might process an operation with side effects, and be unable to
+ * tell the client that the operation succeeded.
+ *
+ * COMPOUND_SLACK_SPACE - this is the minimum amount of buffer space
+ * needed to encode an "ordinary" _successful_ operation. (GETATTR,
+ * READ, READDIR, and READLINK have their own buffer checks.) if we
+ * fall below this level, we fail the next operation with NFS4ERR_RESOURCE.
+ *
+ * COMPOUND_ERR_SLACK_SPACE - this is the minimum amount of buffer space
+ * needed to encode an operation which has failed with NFS4ERR_RESOURCE.
+ * care is taken to ensure that we never fall below this level for any
+ * reason.
+ */
+#define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */
+#define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */
+
+#define NFSD_LEASE_TIME (nfs4_lease_time())
+#define NFSD_LAUNDROMAT_MINTIMEOUT 10 /* seconds */
+
+/*
+ * The following attributes are currently not supported by the NFSv4 server:
+ * ARCHIVE (deprecated anyway)
+ * FS_LOCATIONS (will be supported eventually)
+ * HIDDEN (unlikely to be supported any time soon)
+ * MIMETYPE (unlikely to be supported any time soon)
+ * QUOTA_* (will be supported in a forthcoming patch)
+ * SYSTEM (unlikely to be supported any time soon)
+ * TIME_BACKUP (unlikely to be supported any time soon)
+ * TIME_CREATE (unlikely to be supported any time soon)
+ */
+#define NFSD_SUPPORTED_ATTRS_WORD0 \
+(FATTR4_WORD0_SUPPORTED_ATTRS | FATTR4_WORD0_TYPE | FATTR4_WORD0_FH_EXPIRE_TYPE \
+ | FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE | FATTR4_WORD0_LINK_SUPPORT \
+ | FATTR4_WORD0_SYMLINK_SUPPORT | FATTR4_WORD0_NAMED_ATTR | FATTR4_WORD0_FSID \
+ | FATTR4_WORD0_UNIQUE_HANDLES | FATTR4_WORD0_LEASE_TIME | FATTR4_WORD0_RDATTR_ERROR \
+ | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_CANSETTIME | FATTR4_WORD0_CASE_INSENSITIVE \
+ | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED \
+ | FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FILEID | FATTR4_WORD0_FILES_AVAIL \
+ | FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_HOMOGENEOUS \
+ | FATTR4_WORD0_MAXFILESIZE | FATTR4_WORD0_MAXLINK | FATTR4_WORD0_MAXNAME \
+ | FATTR4_WORD0_MAXREAD | FATTR4_WORD0_MAXWRITE | FATTR4_WORD0_ACL)
+
+#define NFSD_SUPPORTED_ATTRS_WORD1 \
+(FATTR4_WORD1_MODE | FATTR4_WORD1_NO_TRUNC | FATTR4_WORD1_NUMLINKS \
+ | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_RAWDEV \
+ | FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL \
+ | FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | FATTR4_WORD1_TIME_ACCESS_SET \
+ | FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA \
+ | FATTR4_WORD1_TIME_MODIFY | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID)
+
+/* These will return ERR_INVAL if specified in GETATTR or READDIR. */
+#define NFSD_WRITEONLY_ATTRS_WORD1 \
+(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
+
+/* These are the only attrs allowed in CREATE/OPEN/SETATTR. */
+#define NFSD_WRITEABLE_ATTRS_WORD0 \
+(FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL )
+#define NFSD_WRITEABLE_ATTRS_WORD1 \
+(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \
+ | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY_SET)
+
+#endif /* CONFIG_NFSD_V4 */
+
+#endif /* __KERNEL__ */
+
+#endif /* LINUX_NFSD_NFSD_H */
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
new file mode 100644
index 000000000000..bb842ea41033
--- /dev/null
+++ b/include/linux/nfsd/nfsfh.h
@@ -0,0 +1,343 @@
+/*
+ * include/linux/nfsd/nfsfh.h
+ *
+ * This file describes the layout of the file handles as passed
+ * over the wire.
+ *
+ * Earlier versions of knfsd used to sign file handles using keyed MD5
+ * or SHA. I've removed this code, because it doesn't give you more
+ * security than blocking external access to port 2049 on your firewall.
+ *
+ * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_NFSD_FH_H
+#define _LINUX_NFSD_FH_H
+
+#include <asm/types.h>
+#ifdef __KERNEL__
+# include <linux/config.h>
+# include <linux/types.h>
+# include <linux/string.h>
+# include <linux/fs.h>
+#endif
+#include <linux/nfsd/const.h>
+#include <linux/nfsd/debug.h>
+
+/*
+ * This is the old "dentry style" Linux NFSv2 file handle.
+ *
+ * The xino and xdev fields are currently used to transport the
+ * ino/dev of the exported inode.
+ */
+struct nfs_fhbase_old {
+ __u32 fb_dcookie; /* dentry cookie - always 0xfeebbaca */
+ __u32 fb_ino; /* our inode number */
+ __u32 fb_dirino; /* dir inode number, 0 for directories */
+ __u32 fb_dev; /* our device */
+ __u32 fb_xdev;
+ __u32 fb_xino;
+ __u32 fb_generation;
+};
+
+/*
+ * This is the new flexible, extensible style NFSv2/v3 file handle.
+ * by Neil Brown <neilb@cse.unsw.edu.au> - March 2000
+ *
+ * The file handle is seens as a list of 4byte words.
+ * The first word contains a version number (1) and four descriptor bytes
+ * that tell how the remaining 3 variable length fields should be handled.
+ * These three bytes are auth_type, fsid_type and fileid_type.
+ *
+ * All 4byte values are in host-byte-order.
+ *
+ * The auth_type field specifies how the filehandle can be authenticated
+ * This might allow a file to be confirmed to be in a writable part of a
+ * filetree without checking the path from it upto the root.
+ * Current values:
+ * 0 - No authentication. fb_auth is 0 bytes long
+ * Possible future values:
+ * 1 - 4 bytes taken from MD5 hash of the remainer of the file handle
+ * prefixed by a secret and with the important export flags.
+ *
+ * The fsid_type identifies how the filesystem (or export point) is
+ * encoded.
+ * Current values:
+ * 0 - 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4byte inode number
+ * NOTE: we cannot use the kdev_t device id value, because kdev_t.h
+ * says we mustn't. We must break it up and reassemble.
+ * 1 - 4 byte user specified identifier
+ * 2 - 4 byte major, 4 byte minor, 4 byte inode number - DEPRECATED
+ * 3 - 4 byte device id, encoded for user-space, 4 byte inode number
+ *
+ * The fileid_type identified how the file within the filesystem is encoded.
+ * This is (will be) passed to, and set by, the underlying filesystem if it supports
+ * filehandle operations. The filesystem must not use the value '0' or '0xff' and may
+ * only use the values 1 and 2 as defined below:
+ * Current values:
+ * 0 - The root, or export point, of the filesystem. fb_fileid is 0 bytes.
+ * 1 - 32bit inode number, 32 bit generation number.
+ * 2 - 32bit inode number, 32 bit generation number, 32 bit parent directory inode number.
+ *
+ */
+struct nfs_fhbase_new {
+ __u8 fb_version; /* == 1, even => nfs_fhbase_old */
+ __u8 fb_auth_type;
+ __u8 fb_fsid_type;
+ __u8 fb_fileid_type;
+ __u32 fb_auth[1];
+/* __u32 fb_fsid[0]; floating */
+/* __u32 fb_fileid[0]; floating */
+};
+
+struct knfsd_fh {
+ unsigned int fh_size; /* significant for NFSv3.
+ * Points to the current size while building
+ * a new file handle
+ */
+ union {
+ struct nfs_fhbase_old fh_old;
+ __u32 fh_pad[NFS4_FHSIZE/4];
+ struct nfs_fhbase_new fh_new;
+ } fh_base;
+};
+
+#define ofh_dcookie fh_base.fh_old.fb_dcookie
+#define ofh_ino fh_base.fh_old.fb_ino
+#define ofh_dirino fh_base.fh_old.fb_dirino
+#define ofh_dev fh_base.fh_old.fb_dev
+#define ofh_xdev fh_base.fh_old.fb_xdev
+#define ofh_xino fh_base.fh_old.fb_xino
+#define ofh_generation fh_base.fh_old.fb_generation
+
+#define fh_version fh_base.fh_new.fb_version
+#define fh_fsid_type fh_base.fh_new.fb_fsid_type
+#define fh_auth_type fh_base.fh_new.fb_auth_type
+#define fh_fileid_type fh_base.fh_new.fb_fileid_type
+#define fh_auth fh_base.fh_new.fb_auth
+#define fh_fsid fh_base.fh_new.fb_auth
+
+#ifdef __KERNEL__
+
+static inline __u32 ino_t_to_u32(ino_t ino)
+{
+ return (__u32) ino;
+}
+
+static inline ino_t u32_to_ino_t(__u32 uino)
+{
+ return (ino_t) uino;
+}
+
+/*
+ * This is the internal representation of an NFS handle used in knfsd.
+ * pre_mtime/post_version will be used to support wcc_attr's in NFSv3.
+ */
+typedef struct svc_fh {
+ struct knfsd_fh fh_handle; /* FH data */
+ struct dentry * fh_dentry; /* validated dentry */
+ struct svc_export * fh_export; /* export pointer */
+ int fh_maxsize; /* max size for fh_handle */
+
+ unsigned char fh_locked; /* inode locked by us */
+
+#ifdef CONFIG_NFSD_V3
+ unsigned char fh_post_saved; /* post-op attrs saved */
+ unsigned char fh_pre_saved; /* pre-op attrs saved */
+
+ /* Pre-op attributes saved during fh_lock */
+ __u64 fh_pre_size; /* size before operation */
+ struct timespec fh_pre_mtime; /* mtime before oper */
+ struct timespec fh_pre_ctime; /* ctime before oper */
+
+ /* Post-op attributes saved in fh_unlock */
+ umode_t fh_post_mode; /* i_mode */
+ nlink_t fh_post_nlink; /* i_nlink */
+ uid_t fh_post_uid; /* i_uid */
+ gid_t fh_post_gid; /* i_gid */
+ __u64 fh_post_size; /* i_size */
+ unsigned long fh_post_blocks; /* i_blocks */
+ unsigned long fh_post_blksize;/* i_blksize */
+ __u32 fh_post_rdev[2];/* i_rdev */
+ struct timespec fh_post_atime; /* i_atime */
+ struct timespec fh_post_mtime; /* i_mtime */
+ struct timespec fh_post_ctime; /* i_ctime */
+#endif /* CONFIG_NFSD_V3 */
+
+} svc_fh;
+
+static inline void mk_fsid_v0(u32 *fsidv, dev_t dev, ino_t ino)
+{
+ fsidv[0] = htonl((MAJOR(dev)<<16) |
+ MINOR(dev));
+ fsidv[1] = ino_t_to_u32(ino);
+}
+
+static inline void mk_fsid_v1(u32 *fsidv, u32 fsid)
+{
+ fsidv[0] = fsid;
+}
+
+static inline void mk_fsid_v2(u32 *fsidv, dev_t dev, ino_t ino)
+{
+ fsidv[0] = htonl(MAJOR(dev));
+ fsidv[1] = htonl(MINOR(dev));
+ fsidv[2] = ino_t_to_u32(ino);
+}
+
+static inline void mk_fsid_v3(u32 *fsidv, dev_t dev, ino_t ino)
+{
+ fsidv[0] = new_encode_dev(dev);
+ fsidv[1] = ino_t_to_u32(ino);
+}
+
+static inline int key_len(int type)
+{
+ switch(type) {
+ case 0: return 8;
+ case 1: return 4;
+ case 2: return 12;
+ case 3: return 8;
+ default: return 0;
+ }
+}
+
+/*
+ * Shorthand for dprintk()'s
+ */
+extern char * SVCFH_fmt(struct svc_fh *fhp);
+
+/*
+ * Function prototypes
+ */
+u32 fh_verify(struct svc_rqst *, struct svc_fh *, int, int);
+int fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
+int fh_update(struct svc_fh *);
+void fh_put(struct svc_fh *);
+
+static __inline__ struct svc_fh *
+fh_copy(struct svc_fh *dst, struct svc_fh *src)
+{
+ if (src->fh_dentry || src->fh_locked) {
+ struct dentry *dentry = src->fh_dentry;
+ printk(KERN_ERR "fh_copy: copying %s/%s, already verified!\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name);
+ }
+
+ *dst = *src;
+ return dst;
+}
+
+static __inline__ struct svc_fh *
+fh_init(struct svc_fh *fhp, int maxsize)
+{
+ memset(fhp, 0, sizeof(*fhp));
+ fhp->fh_maxsize = maxsize;
+ return fhp;
+}
+
+#ifdef CONFIG_NFSD_V3
+/*
+ * Fill in the pre_op attr for the wcc data
+ */
+static inline void
+fill_pre_wcc(struct svc_fh *fhp)
+{
+ struct inode *inode;
+
+ inode = fhp->fh_dentry->d_inode;
+ if (!fhp->fh_pre_saved) {
+ fhp->fh_pre_mtime = inode->i_mtime;
+ fhp->fh_pre_ctime = inode->i_ctime;
+ fhp->fh_pre_size = inode->i_size;
+ fhp->fh_pre_saved = 1;
+ }
+}
+
+/*
+ * Fill in the post_op attr for the wcc data
+ */
+static inline void
+fill_post_wcc(struct svc_fh *fhp)
+{
+ struct inode *inode = fhp->fh_dentry->d_inode;
+
+ if (fhp->fh_post_saved)
+ printk("nfsd: inode locked twice during operation.\n");
+
+ fhp->fh_post_mode = inode->i_mode;
+ fhp->fh_post_nlink = inode->i_nlink;
+ fhp->fh_post_uid = inode->i_uid;
+ fhp->fh_post_gid = inode->i_gid;
+ fhp->fh_post_size = inode->i_size;
+ if (inode->i_blksize) {
+ fhp->fh_post_blksize = inode->i_blksize;
+ fhp->fh_post_blocks = inode->i_blocks;
+ } else {
+ fhp->fh_post_blksize = BLOCK_SIZE;
+ /* how much do we care for accuracy with MinixFS? */
+ fhp->fh_post_blocks = (inode->i_size+511) >> 9;
+ }
+ fhp->fh_post_rdev[0] = htonl((u32)imajor(inode));
+ fhp->fh_post_rdev[1] = htonl((u32)iminor(inode));
+ fhp->fh_post_atime = inode->i_atime;
+ fhp->fh_post_mtime = inode->i_mtime;
+ fhp->fh_post_ctime = inode->i_ctime;
+ fhp->fh_post_saved = 1;
+}
+#else
+#define fill_pre_wcc(ignored)
+#define fill_post_wcc(notused)
+#endif /* CONFIG_NFSD_V3 */
+
+
+/*
+ * Lock a file handle/inode
+ * NOTE: both fh_lock and fh_unlock are done "by hand" in
+ * vfs.c:nfsd_rename as it needs to grab 2 i_sem's at once
+ * so, any changes here should be reflected there.
+ */
+static inline void
+fh_lock(struct svc_fh *fhp)
+{
+ struct dentry *dentry = fhp->fh_dentry;
+ struct inode *inode;
+
+ dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n",
+ SVCFH_fmt(fhp), fhp->fh_locked);
+
+ if (!fhp->fh_dentry) {
+ printk(KERN_ERR "fh_lock: fh not verified!\n");
+ return;
+ }
+ if (fhp->fh_locked) {
+ printk(KERN_WARNING "fh_lock: %s/%s already locked!\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name);
+ return;
+ }
+
+ inode = dentry->d_inode;
+ down(&inode->i_sem);
+ fill_pre_wcc(fhp);
+ fhp->fh_locked = 1;
+}
+
+/*
+ * Unlock a file handle/inode
+ */
+static inline void
+fh_unlock(struct svc_fh *fhp)
+{
+ if (!fhp->fh_dentry)
+ printk(KERN_ERR "fh_unlock: fh not verified!\n");
+
+ if (fhp->fh_locked) {
+ fill_post_wcc(fhp);
+ up(&fhp->fh_dentry->d_inode->i_sem);
+ fhp->fh_locked = 0;
+ }
+}
+#endif /* __KERNEL__ */
+
+
+#endif /* _LINUX_NFSD_FH_H */
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
new file mode 100644
index 000000000000..b6b2fe1e7c63
--- /dev/null
+++ b/include/linux/nfsd/state.h
@@ -0,0 +1,298 @@
+/*
+ * linux/include/nfsd/state.h
+ *
+ * Copyright (c) 2001 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Kendrick Smith <kmsmith@umich.edu>
+ * Andy Adamson <andros@umich.edu>
+ *
+ * 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.
+ *
+ */
+
+#ifndef _NFSD4_STATE_H
+#define _NFSD4_STATE_H
+
+#include <linux/list.h>
+#include <linux/kref.h>
+#include <linux/sunrpc/clnt.h>
+
+#define NFS4_OPAQUE_LIMIT 1024
+typedef struct {
+ u32 cl_boot;
+ u32 cl_id;
+} clientid_t;
+
+typedef struct {
+ u32 so_boot;
+ u32 so_stateownerid;
+ u32 so_fileid;
+} stateid_opaque_t;
+
+typedef struct {
+ u32 si_generation;
+ stateid_opaque_t si_opaque;
+} stateid_t;
+#define si_boot si_opaque.so_boot
+#define si_stateownerid si_opaque.so_stateownerid
+#define si_fileid si_opaque.so_fileid
+
+extern stateid_t zerostateid;
+extern stateid_t onestateid;
+
+#define ZERO_STATEID(stateid) (!memcmp((stateid), &zerostateid, sizeof(stateid_t)))
+#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
+
+struct nfs4_cb_recall {
+ u32 cbr_ident;
+ int cbr_trunc;
+ stateid_t cbr_stateid;
+ u32 cbr_fhlen;
+ u32 cbr_fhval[NFS4_FHSIZE];
+ struct nfs4_delegation *cbr_dp;
+};
+
+struct nfs4_delegation {
+ struct list_head dl_del_perfile; /* nfs4_file->fi_del_perfile */
+ struct list_head dl_del_perclnt; /* nfs4_client->cl_del_perclnt*/
+ struct list_head dl_recall_lru; /* delegation recalled */
+ atomic_t dl_count; /* ref count */
+ struct nfs4_client *dl_client;
+ struct nfs4_file *dl_file;
+ struct file_lock *dl_flock;
+ struct file *dl_vfs_file;
+ u32 dl_type;
+ time_t dl_time;
+ struct nfs4_cb_recall dl_recall;
+};
+
+#define dl_stateid dl_recall.cbr_stateid
+#define dl_fhlen dl_recall.cbr_fhlen
+#define dl_fhval dl_recall.cbr_fhval
+
+/* client delegation callback info */
+struct nfs4_callback {
+ /* SETCLIENTID info */
+ u32 cb_parsed; /* addr parsed */
+ u32 cb_addr;
+ unsigned short cb_port;
+ u32 cb_prog;
+ u32 cb_ident;
+ /* RPC client info */
+ atomic_t cb_set; /* successful CB_NULL call */
+ struct rpc_program cb_program;
+ struct rpc_stat cb_stat;
+ struct rpc_clnt * cb_client;
+};
+
+/*
+ * struct nfs4_client - one per client. Clientids live here.
+ * o Each nfs4_client is hashed by clientid.
+ *
+ * o Each nfs4_clients is also hashed by name
+ * (the opaque quantity initially sent by the client to identify itself).
+ *
+ * o cl_perclient list is used to ensure no dangling stateowner references
+ * when we expire the nfs4_client
+ */
+struct nfs4_client {
+ struct list_head cl_idhash; /* hash by cl_clientid.id */
+ struct list_head cl_strhash; /* hash by cl_name */
+ struct list_head cl_perclient; /* list: stateowners */
+ struct list_head cl_del_perclnt; /* list: delegations */
+ struct list_head cl_lru; /* tail queue */
+ struct xdr_netobj cl_name; /* id generated by client */
+ nfs4_verifier cl_verifier; /* generated by client */
+ time_t cl_time; /* time of last lease renewal */
+ u32 cl_addr; /* client ipaddress */
+ struct svc_cred cl_cred; /* setclientid principal */
+ clientid_t cl_clientid; /* generated by server */
+ nfs4_verifier cl_confirm; /* generated by server */
+ struct nfs4_callback cl_callback; /* callback info */
+ atomic_t cl_count; /* ref count */
+};
+
+/* struct nfs4_client_reset
+ * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl
+ * upon lease reset, or from upcall to state_daemon (to read in state
+ * from non-volitile storage) upon reboot.
+ */
+struct nfs4_client_reclaim {
+ struct list_head cr_strhash; /* hash by cr_name */
+ struct xdr_netobj cr_name; /* id generated by client */
+};
+
+static inline void
+update_stateid(stateid_t *stateid)
+{
+ stateid->si_generation++;
+}
+
+/* A reasonable value for REPLAY_ISIZE was estimated as follows:
+ * The OPEN response, typically the largest, requires
+ * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) +
+ * 4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) +
+ * 20(deleg. space limit) + ~32(deleg. ace) = 112 bytes
+ */
+
+#define NFSD4_REPLAY_ISIZE 112
+
+/*
+ * Replay buffer, where the result of the last seqid-mutating operation
+ * is cached.
+ */
+struct nfs4_replay {
+ u32 rp_status;
+ unsigned int rp_buflen;
+ char *rp_buf;
+ unsigned intrp_allocated;
+ int rp_openfh_len;
+ char rp_openfh[NFS4_FHSIZE];
+ char rp_ibuf[NFSD4_REPLAY_ISIZE];
+};
+
+/*
+* nfs4_stateowner can either be an open_owner, or a lock_owner
+*
+* so_idhash: stateid_hashtbl[] for open owner, lockstateid_hashtbl[]
+* for lock_owner
+* so_strhash: ownerstr_hashtbl[] for open_owner, lock_ownerstr_hashtbl[]
+* for lock_owner
+* so_perclient: nfs4_client->cl_perclient entry - used when nfs4_client
+* struct is reaped.
+* so_perfilestate: heads the list of nfs4_stateid (either open or lock)
+* and is used to ensure no dangling nfs4_stateid references when we
+* release a stateowner.
+* so_perlockowner: (open) nfs4_stateid->st_perlockowner entry - used when
+* close is called to reap associated byte-range locks
+* so_close_lru: (open) stateowner is placed on this list instead of being
+* reaped (when so_perfilestate is empty) to hold the last close replay.
+* reaped by laundramat thread after lease period.
+*/
+struct nfs4_stateowner {
+ struct kref so_ref;
+ struct list_head so_idhash; /* hash by so_id */
+ struct list_head so_strhash; /* hash by op_name */
+ struct list_head so_perclient; /* nfs4_client->cl_perclient */
+ struct list_head so_perfilestate; /* list: nfs4_stateid */
+ struct list_head so_perlockowner; /* nfs4_stateid->st_perlockowner */
+ struct list_head so_close_lru; /* tail queue */
+ time_t so_time; /* time of placement on so_close_lru */
+ int so_is_open_owner; /* 1=openowner,0=lockowner */
+ u32 so_id;
+ struct nfs4_client * so_client;
+ u32 so_seqid;
+ struct xdr_netobj so_owner; /* open owner name */
+ int so_confirmed; /* successful OPEN_CONFIRM? */
+ struct nfs4_replay so_replay;
+};
+
+/*
+* nfs4_file: a file opened by some number of (open) nfs4_stateowners.
+* o fi_perfile list is used to search for conflicting
+* share_acces, share_deny on the file.
+*/
+struct nfs4_file {
+ struct list_head fi_hash; /* hash by "struct inode *" */
+ struct list_head fi_perfile; /* list: nfs4_stateid */
+ struct list_head fi_del_perfile; /* list: nfs4_delegation */
+ struct inode *fi_inode;
+ u32 fi_id; /* used with stateowner->so_id
+ * for stateid_hashtbl hash */
+};
+
+/*
+* nfs4_stateid can either be an open stateid or (eventually) a lock stateid
+*
+* (open)nfs4_stateid: one per (open)nfs4_stateowner, nfs4_file
+*
+* st_hash: stateid_hashtbl[] entry or lockstateid_hashtbl entry
+* st_perfile: file_hashtbl[] entry.
+* st_perfile_state: nfs4_stateowner->so_perfilestate
+* st_perlockowner: (open stateid) list of lock nfs4_stateowners
+* st_access_bmap: used only for open stateid
+* st_deny_bmap: used only for open stateid
+*/
+
+struct nfs4_stateid {
+ struct list_head st_hash;
+ struct list_head st_perfile;
+ struct list_head st_perfilestate;
+ struct list_head st_perlockowner;
+ struct nfs4_stateowner * st_stateowner;
+ struct nfs4_file * st_file;
+ stateid_t st_stateid;
+ struct file * st_vfs_file;
+ unsigned long st_access_bmap;
+ unsigned long st_deny_bmap;
+};
+
+/* flags for preprocess_seqid_op() */
+#define CHECK_FH 0x00000001
+#define CONFIRM 0x00000002
+#define OPEN_STATE 0x00000004
+#define LOCK_STATE 0x00000008
+#define RD_STATE 0x00000010
+#define WR_STATE 0x00000020
+#define CLOSE_STATE 0x00000040
+#define DELEG_RET 0x00000080
+
+#define seqid_mutating_err(err) \
+ (((err) != nfserr_stale_clientid) && \
+ ((err) != nfserr_bad_seqid) && \
+ ((err) != nfserr_stale_stateid) && \
+ ((err) != nfserr_bad_stateid))
+
+extern time_t nfs4_laundromat(void);
+extern int nfsd4_renew(clientid_t *clid);
+extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh,
+ stateid_t *stateid, int flags, struct file **filp);
+extern int nfs4_share_conflict(struct svc_fh *current_fh,
+ unsigned int deny_type);
+extern void nfs4_lock_state(void);
+extern void nfs4_unlock_state(void);
+extern int nfs4_in_grace(void);
+extern int nfs4_check_open_reclaim(clientid_t *clid);
+extern void put_nfs4_client(struct nfs4_client *clp);
+extern void nfs4_free_stateowner(struct kref *kref);
+extern void nfsd4_probe_callback(struct nfs4_client *clp);
+extern void nfsd4_cb_recall(struct nfs4_delegation *dp);
+extern void nfs4_put_delegation(struct nfs4_delegation *dp);
+
+static inline void
+nfs4_put_stateowner(struct nfs4_stateowner *so)
+{
+ kref_put(&so->so_ref, nfs4_free_stateowner);
+}
+
+static inline void
+nfs4_get_stateowner(struct nfs4_stateowner *so)
+{
+ kref_get(&so->so_ref);
+}
+
+#endif /* NFSD4_STATE_H */
diff --git a/include/linux/nfsd/stats.h b/include/linux/nfsd/stats.h
new file mode 100644
index 000000000000..b6f1e0cda4f2
--- /dev/null
+++ b/include/linux/nfsd/stats.h
@@ -0,0 +1,44 @@
+/*
+ * linux/include/nfsd/stats.h
+ *
+ * Statistics for NFS server.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef LINUX_NFSD_STATS_H
+#define LINUX_NFSD_STATS_H
+
+struct nfsd_stats {
+ unsigned int rchits; /* repcache hits */
+ unsigned int rcmisses; /* repcache hits */
+ unsigned int rcnocache; /* uncached reqs */
+ unsigned int fh_stale; /* FH stale error */
+ unsigned int fh_lookup; /* dentry cached */
+ unsigned int fh_anon; /* anon file dentry returned */
+ unsigned int fh_nocache_dir; /* filehandle not found in dcache */
+ unsigned int fh_nocache_nondir; /* filehandle not found in dcache */
+ unsigned int io_read; /* bytes returned to read requests */
+ unsigned int io_write; /* bytes passed in write requests */
+ unsigned int th_cnt; /* number of available threads */
+ unsigned int th_usage[10]; /* number of ticks during which n perdeciles
+ * of available threads were in use */
+ unsigned int th_fullcnt; /* number of times last free thread was used */
+ unsigned int ra_size; /* size of ra cache */
+ unsigned int ra_depth[11]; /* number of times ra entry was found that deep
+ * in the cache (10percentiles). [10] = not found */
+};
+
+/* thread usage wraps very million seconds (approx one fortnight) */
+#define NFSD_USAGE_WRAP (HZ*1000000)
+
+#ifdef __KERNEL__
+
+extern struct nfsd_stats nfsdstats;
+extern struct svc_stat nfsd_svcstats;
+
+void nfsd_stat_init(void);
+void nfsd_stat_shutdown(void);
+
+#endif /* __KERNEL__ */
+#endif /* LINUX_NFSD_STATS_H */
diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h
new file mode 100644
index 000000000000..e65c9db6d13f
--- /dev/null
+++ b/include/linux/nfsd/syscall.h
@@ -0,0 +1,125 @@
+/*
+ * include/linux/nfsd/syscall.h
+ *
+ * This file holds all declarations for the knfsd syscall interface.
+ *
+ * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef NFSD_SYSCALL_H
+#define NFSD_SYSCALL_H
+
+#include <asm/types.h>
+#ifdef __KERNEL__
+# include <linux/config.h>
+# include <linux/types.h>
+# include <linux/in.h>
+#endif
+#include <linux/posix_types.h>
+#include <linux/nfsd/const.h>
+#include <linux/nfsd/export.h>
+#include <linux/nfsd/nfsfh.h>
+#include <linux/nfsd/auth.h>
+
+/*
+ * Version of the syscall interface
+ */
+#define NFSCTL_VERSION 0x0201
+
+/*
+ * These are the commands understood by nfsctl().
+ */
+#define NFSCTL_SVC 0 /* This is a server process. */
+#define NFSCTL_ADDCLIENT 1 /* Add an NFS client. */
+#define NFSCTL_DELCLIENT 2 /* Remove an NFS client. */
+#define NFSCTL_EXPORT 3 /* export a file system. */
+#define NFSCTL_UNEXPORT 4 /* unexport a file system. */
+/*#define NFSCTL_UGIDUPDATE 5 / * update a client's uid/gid map. DISCARDED */
+/*#define NFSCTL_GETFH 6 / * get an fh by ino DISCARDED */
+#define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */
+#define NFSCTL_GETFS 8 /* get an fh by path with max FH len */
+
+/* SVC */
+struct nfsctl_svc {
+ unsigned short svc_port;
+ int svc_nthreads;
+};
+
+/* ADDCLIENT/DELCLIENT */
+struct nfsctl_client {
+ char cl_ident[NFSCLNT_IDMAX+1];
+ int cl_naddr;
+ struct in_addr cl_addrlist[NFSCLNT_ADDRMAX];
+ int cl_fhkeytype;
+ int cl_fhkeylen;
+ unsigned char cl_fhkey[NFSCLNT_KEYMAX];
+};
+
+/* EXPORT/UNEXPORT */
+struct nfsctl_export {
+ char ex_client[NFSCLNT_IDMAX+1];
+ char ex_path[NFS_MAXPATHLEN+1];
+ __kernel_old_dev_t ex_dev;
+ __kernel_ino_t ex_ino;
+ int ex_flags;
+ __kernel_uid_t ex_anon_uid;
+ __kernel_gid_t ex_anon_gid;
+};
+
+/* GETFD */
+struct nfsctl_fdparm {
+ struct sockaddr gd_addr;
+ char gd_path[NFS_MAXPATHLEN+1];
+ int gd_version;
+};
+
+/* GETFS - GET Filehandle with Size */
+struct nfsctl_fsparm {
+ struct sockaddr gd_addr;
+ char gd_path[NFS_MAXPATHLEN+1];
+ int gd_maxlen;
+};
+
+/*
+ * This is the argument union.
+ */
+struct nfsctl_arg {
+ int ca_version; /* safeguard */
+ union {
+ struct nfsctl_svc u_svc;
+ struct nfsctl_client u_client;
+ struct nfsctl_export u_export;
+ struct nfsctl_fdparm u_getfd;
+ struct nfsctl_fsparm u_getfs;
+ /*
+ * The following dummy member is needed to preserve binary compatibility
+ * on platforms where alignof(void*)>alignof(int). It's needed because
+ * this union used to contain a member (u_umap) which contained a
+ * pointer.
+ */
+ void *u_ptr;
+ } u;
+#define ca_svc u.u_svc
+#define ca_client u.u_client
+#define ca_export u.u_export
+#define ca_getfd u.u_getfd
+#define ca_getfs u.u_getfs
+};
+
+union nfsctl_res {
+ __u8 cr_getfh[NFS_FHSIZE];
+ struct knfsd_fh cr_getfs;
+};
+
+#ifdef __KERNEL__
+/*
+ * Kernel syscall implementation.
+ */
+extern int exp_addclient(struct nfsctl_client *ncp);
+extern int exp_delclient(struct nfsctl_client *ncp);
+extern int exp_export(struct nfsctl_export *nxp);
+extern int exp_unexport(struct nfsctl_export *nxp);
+
+#endif /* __KERNEL__ */
+
+#endif /* NFSD_SYSCALL_H */
diff --git a/include/linux/nfsd/xdr.h b/include/linux/nfsd/xdr.h
new file mode 100644
index 000000000000..ecccef777dae
--- /dev/null
+++ b/include/linux/nfsd/xdr.h
@@ -0,0 +1,172 @@
+/*
+ * linux/inxlude/linux/nfsd/xdr.h
+ *
+ * XDR types for nfsd. This is mainly a typing exercise.
+ */
+
+#ifndef LINUX_NFSD_H
+#define LINUX_NFSD_H
+
+#include <linux/fs.h>
+#include <linux/vfs.h>
+#include <linux/nfs.h>
+
+struct nfsd_fhandle {
+ struct svc_fh fh;
+};
+
+struct nfsd_sattrargs {
+ struct svc_fh fh;
+ struct iattr attrs;
+};
+
+struct nfsd_diropargs {
+ struct svc_fh fh;
+ char * name;
+ int len;
+};
+
+struct nfsd_readargs {
+ struct svc_fh fh;
+ __u32 offset;
+ __u32 count;
+ struct kvec vec[RPCSVC_MAXPAGES];
+ int vlen;
+};
+
+struct nfsd_writeargs {
+ svc_fh fh;
+ __u32 offset;
+ int len;
+ struct kvec vec[RPCSVC_MAXPAGES];
+ int vlen;
+};
+
+struct nfsd_createargs {
+ struct svc_fh fh;
+ char * name;
+ int len;
+ struct iattr attrs;
+};
+
+struct nfsd_renameargs {
+ struct svc_fh ffh;
+ char * fname;
+ int flen;
+ struct svc_fh tfh;
+ char * tname;
+ int tlen;
+};
+
+struct nfsd_readlinkargs {
+ struct svc_fh fh;
+ char * buffer;
+};
+
+struct nfsd_linkargs {
+ struct svc_fh ffh;
+ struct svc_fh tfh;
+ char * tname;
+ int tlen;
+};
+
+struct nfsd_symlinkargs {
+ struct svc_fh ffh;
+ char * fname;
+ int flen;
+ char * tname;
+ int tlen;
+ struct iattr attrs;
+};
+
+struct nfsd_readdirargs {
+ struct svc_fh fh;
+ __u32 cookie;
+ __u32 count;
+ u32 * buffer;
+};
+
+struct nfsd_attrstat {
+ struct svc_fh fh;
+};
+
+struct nfsd_diropres {
+ struct svc_fh fh;
+};
+
+struct nfsd_readlinkres {
+ int len;
+};
+
+struct nfsd_readres {
+ struct svc_fh fh;
+ unsigned long count;
+};
+
+struct nfsd_readdirres {
+ int count;
+
+ struct readdir_cd common;
+ u32 * buffer;
+ int buflen;
+ u32 * offset;
+};
+
+struct nfsd_statfsres {
+ struct kstatfs stats;
+};
+
+/*
+ * Storage requirements for XDR arguments and results.
+ */
+union nfsd_xdrstore {
+ struct nfsd_sattrargs sattr;
+ struct nfsd_diropargs dirop;
+ struct nfsd_readargs read;
+ struct nfsd_writeargs write;
+ struct nfsd_createargs create;
+ struct nfsd_renameargs rename;
+ struct nfsd_linkargs link;
+ struct nfsd_symlinkargs symlink;
+ struct nfsd_readdirargs readdir;
+};
+
+#define NFS2_SVC_XDRSIZE sizeof(union nfsd_xdrstore)
+
+
+int nfssvc_decode_void(struct svc_rqst *, u32 *, void *);
+int nfssvc_decode_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
+int nfssvc_decode_sattrargs(struct svc_rqst *, u32 *,
+ struct nfsd_sattrargs *);
+int nfssvc_decode_diropargs(struct svc_rqst *, u32 *,
+ struct nfsd_diropargs *);
+int nfssvc_decode_readargs(struct svc_rqst *, u32 *,
+ struct nfsd_readargs *);
+int nfssvc_decode_writeargs(struct svc_rqst *, u32 *,
+ struct nfsd_writeargs *);
+int nfssvc_decode_createargs(struct svc_rqst *, u32 *,
+ struct nfsd_createargs *);
+int nfssvc_decode_renameargs(struct svc_rqst *, u32 *,
+ struct nfsd_renameargs *);
+int nfssvc_decode_readlinkargs(struct svc_rqst *, u32 *,
+ struct nfsd_readlinkargs *);
+int nfssvc_decode_linkargs(struct svc_rqst *, u32 *,
+ struct nfsd_linkargs *);
+int nfssvc_decode_symlinkargs(struct svc_rqst *, u32 *,
+ struct nfsd_symlinkargs *);
+int nfssvc_decode_readdirargs(struct svc_rqst *, u32 *,
+ struct nfsd_readdirargs *);
+int nfssvc_encode_void(struct svc_rqst *, u32 *, void *);
+int nfssvc_encode_attrstat(struct svc_rqst *, u32 *, struct nfsd_attrstat *);
+int nfssvc_encode_diropres(struct svc_rqst *, u32 *, struct nfsd_diropres *);
+int nfssvc_encode_readlinkres(struct svc_rqst *, u32 *, struct nfsd_readlinkres *);
+int nfssvc_encode_readres(struct svc_rqst *, u32 *, struct nfsd_readres *);
+int nfssvc_encode_statfsres(struct svc_rqst *, u32 *, struct nfsd_statfsres *);
+int nfssvc_encode_readdirres(struct svc_rqst *, u32 *, struct nfsd_readdirres *);
+
+int nfssvc_encode_entry(struct readdir_cd *, const char *name,
+ int namlen, loff_t offset, ino_t ino, unsigned int);
+
+int nfssvc_release_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
+
+#endif /* LINUX_NFSD_H */
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h
new file mode 100644
index 000000000000..0ae9e0ef5f68
--- /dev/null
+++ b/include/linux/nfsd/xdr3.h
@@ -0,0 +1,321 @@
+/*
+ * linux/include/linux/nfsd/xdr3.h
+ *
+ * XDR types for NFSv3 in nfsd.
+ *
+ * Copyright (C) 1996-1998, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _LINUX_NFSD_XDR3_H
+#define _LINUX_NFSD_XDR3_H
+
+#include <linux/nfsd/xdr.h>
+
+struct nfsd3_sattrargs {
+ struct svc_fh fh;
+ struct iattr attrs;
+ int check_guard;
+ time_t guardtime;
+};
+
+struct nfsd3_diropargs {
+ struct svc_fh fh;
+ char * name;
+ int len;
+};
+
+struct nfsd3_accessargs {
+ struct svc_fh fh;
+ unsigned int access;
+};
+
+struct nfsd3_readargs {
+ struct svc_fh fh;
+ __u64 offset;
+ __u32 count;
+ struct kvec vec[RPCSVC_MAXPAGES];
+ int vlen;
+};
+
+struct nfsd3_writeargs {
+ svc_fh fh;
+ __u64 offset;
+ __u32 count;
+ int stable;
+ int len;
+ struct kvec vec[RPCSVC_MAXPAGES];
+ int vlen;
+};
+
+struct nfsd3_createargs {
+ struct svc_fh fh;
+ char * name;
+ int len;
+ int createmode;
+ struct iattr attrs;
+ __u32 * verf;
+};
+
+struct nfsd3_mknodargs {
+ struct svc_fh fh;
+ char * name;
+ int len;
+ __u32 ftype;
+ __u32 major, minor;
+ struct iattr attrs;
+};
+
+struct nfsd3_renameargs {
+ struct svc_fh ffh;
+ char * fname;
+ int flen;
+ struct svc_fh tfh;
+ char * tname;
+ int tlen;
+};
+
+struct nfsd3_readlinkargs {
+ struct svc_fh fh;
+ char * buffer;
+};
+
+struct nfsd3_linkargs {
+ struct svc_fh ffh;
+ struct svc_fh tfh;
+ char * tname;
+ int tlen;
+};
+
+struct nfsd3_symlinkargs {
+ struct svc_fh ffh;
+ char * fname;
+ int flen;
+ char * tname;
+ int tlen;
+ struct iattr attrs;
+};
+
+struct nfsd3_readdirargs {
+ struct svc_fh fh;
+ __u64 cookie;
+ __u32 dircount;
+ __u32 count;
+ __u32 * verf;
+ u32 * buffer;
+};
+
+struct nfsd3_commitargs {
+ struct svc_fh fh;
+ __u64 offset;
+ __u32 count;
+};
+
+struct nfsd3_attrstat {
+ __u32 status;
+ struct svc_fh fh;
+};
+
+/* LOOKUP, CREATE, MKDIR, SYMLINK, MKNOD */
+struct nfsd3_diropres {
+ __u32 status;
+ struct svc_fh dirfh;
+ struct svc_fh fh;
+};
+
+struct nfsd3_accessres {
+ __u32 status;
+ struct svc_fh fh;
+ __u32 access;
+};
+
+struct nfsd3_readlinkres {
+ __u32 status;
+ struct svc_fh fh;
+ __u32 len;
+};
+
+struct nfsd3_readres {
+ __u32 status;
+ struct svc_fh fh;
+ unsigned long count;
+ int eof;
+};
+
+struct nfsd3_writeres {
+ __u32 status;
+ struct svc_fh fh;
+ unsigned long count;
+ int committed;
+};
+
+struct nfsd3_renameres {
+ __u32 status;
+ struct svc_fh ffh;
+ struct svc_fh tfh;
+};
+
+struct nfsd3_linkres {
+ __u32 status;
+ struct svc_fh tfh;
+ struct svc_fh fh;
+};
+
+struct nfsd3_readdirres {
+ __u32 status;
+ struct svc_fh fh;
+ int count;
+ __u32 verf[2];
+
+ struct readdir_cd common;
+ u32 * buffer;
+ int buflen;
+ u32 * offset;
+ u32 * offset1;
+ struct svc_rqst * rqstp;
+
+};
+
+struct nfsd3_fsstatres {
+ __u32 status;
+ struct kstatfs stats;
+ __u32 invarsec;
+};
+
+struct nfsd3_fsinfores {
+ __u32 status;
+ __u32 f_rtmax;
+ __u32 f_rtpref;
+ __u32 f_rtmult;
+ __u32 f_wtmax;
+ __u32 f_wtpref;
+ __u32 f_wtmult;
+ __u32 f_dtpref;
+ __u64 f_maxfilesize;
+ __u32 f_properties;
+};
+
+struct nfsd3_pathconfres {
+ __u32 status;
+ __u32 p_link_max;
+ __u32 p_name_max;
+ __u32 p_no_trunc;
+ __u32 p_chown_restricted;
+ __u32 p_case_insensitive;
+ __u32 p_case_preserving;
+};
+
+struct nfsd3_commitres {
+ __u32 status;
+ struct svc_fh fh;
+};
+
+/* dummy type for release */
+struct nfsd3_fhandle_pair {
+ __u32 dummy;
+ struct svc_fh fh1;
+ struct svc_fh fh2;
+};
+
+/*
+ * Storage requirements for XDR arguments and results.
+ */
+union nfsd3_xdrstore {
+ struct nfsd3_sattrargs sattrargs;
+ struct nfsd3_diropargs diropargs;
+ struct nfsd3_readargs readargs;
+ struct nfsd3_writeargs writeargs;
+ struct nfsd3_createargs createargs;
+ struct nfsd3_renameargs renameargs;
+ struct nfsd3_linkargs linkargs;
+ struct nfsd3_symlinkargs symlinkargs;
+ struct nfsd3_readdirargs readdirargs;
+ struct nfsd3_diropres diropres;
+ struct nfsd3_accessres accessres;
+ struct nfsd3_readlinkres readlinkres;
+ struct nfsd3_readres readres;
+ struct nfsd3_writeres writeres;
+ struct nfsd3_renameres renameres;
+ struct nfsd3_linkres linkres;
+ struct nfsd3_readdirres readdirres;
+ struct nfsd3_fsstatres fsstatres;
+ struct nfsd3_fsinfores fsinfores;
+ struct nfsd3_pathconfres pathconfres;
+ struct nfsd3_commitres commitres;
+};
+
+#define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore)
+
+int nfs3svc_decode_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
+int nfs3svc_decode_sattrargs(struct svc_rqst *, u32 *,
+ struct nfsd3_sattrargs *);
+int nfs3svc_decode_diropargs(struct svc_rqst *, u32 *,
+ struct nfsd3_diropargs *);
+int nfs3svc_decode_accessargs(struct svc_rqst *, u32 *,
+ struct nfsd3_accessargs *);
+int nfs3svc_decode_readargs(struct svc_rqst *, u32 *,
+ struct nfsd3_readargs *);
+int nfs3svc_decode_writeargs(struct svc_rqst *, u32 *,
+ struct nfsd3_writeargs *);
+int nfs3svc_decode_createargs(struct svc_rqst *, u32 *,
+ struct nfsd3_createargs *);
+int nfs3svc_decode_mkdirargs(struct svc_rqst *, u32 *,
+ struct nfsd3_createargs *);
+int nfs3svc_decode_mknodargs(struct svc_rqst *, u32 *,
+ struct nfsd3_mknodargs *);
+int nfs3svc_decode_renameargs(struct svc_rqst *, u32 *,
+ struct nfsd3_renameargs *);
+int nfs3svc_decode_readlinkargs(struct svc_rqst *, u32 *,
+ struct nfsd3_readlinkargs *);
+int nfs3svc_decode_linkargs(struct svc_rqst *, u32 *,
+ struct nfsd3_linkargs *);
+int nfs3svc_decode_symlinkargs(struct svc_rqst *, u32 *,
+ struct nfsd3_symlinkargs *);
+int nfs3svc_decode_readdirargs(struct svc_rqst *, u32 *,
+ struct nfsd3_readdirargs *);
+int nfs3svc_decode_readdirplusargs(struct svc_rqst *, u32 *,
+ struct nfsd3_readdirargs *);
+int nfs3svc_decode_commitargs(struct svc_rqst *, u32 *,
+ struct nfsd3_commitargs *);
+int nfs3svc_encode_voidres(struct svc_rqst *, u32 *, void *);
+int nfs3svc_encode_attrstat(struct svc_rqst *, u32 *,
+ struct nfsd3_attrstat *);
+int nfs3svc_encode_wccstat(struct svc_rqst *, u32 *,
+ struct nfsd3_attrstat *);
+int nfs3svc_encode_diropres(struct svc_rqst *, u32 *,
+ struct nfsd3_diropres *);
+int nfs3svc_encode_accessres(struct svc_rqst *, u32 *,
+ struct nfsd3_accessres *);
+int nfs3svc_encode_readlinkres(struct svc_rqst *, u32 *,
+ struct nfsd3_readlinkres *);
+int nfs3svc_encode_readres(struct svc_rqst *, u32 *, struct nfsd3_readres *);
+int nfs3svc_encode_writeres(struct svc_rqst *, u32 *, struct nfsd3_writeres *);
+int nfs3svc_encode_createres(struct svc_rqst *, u32 *,
+ struct nfsd3_diropres *);
+int nfs3svc_encode_renameres(struct svc_rqst *, u32 *,
+ struct nfsd3_renameres *);
+int nfs3svc_encode_linkres(struct svc_rqst *, u32 *,
+ struct nfsd3_linkres *);
+int nfs3svc_encode_readdirres(struct svc_rqst *, u32 *,
+ struct nfsd3_readdirres *);
+int nfs3svc_encode_fsstatres(struct svc_rqst *, u32 *,
+ struct nfsd3_fsstatres *);
+int nfs3svc_encode_fsinfores(struct svc_rqst *, u32 *,
+ struct nfsd3_fsinfores *);
+int nfs3svc_encode_pathconfres(struct svc_rqst *, u32 *,
+ struct nfsd3_pathconfres *);
+int nfs3svc_encode_commitres(struct svc_rqst *, u32 *,
+ struct nfsd3_commitres *);
+
+int nfs3svc_release_fhandle(struct svc_rqst *, u32 *,
+ struct nfsd3_attrstat *);
+int nfs3svc_release_fhandle2(struct svc_rqst *, u32 *,
+ struct nfsd3_fhandle_pair *);
+int nfs3svc_encode_entry(struct readdir_cd *, const char *name,
+ int namlen, loff_t offset, ino_t ino,
+ unsigned int);
+int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name,
+ int namlen, loff_t offset, ino_t ino,
+ unsigned int);
+
+
+#endif /* _LINUX_NFSD_XDR3_H */
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
new file mode 100644
index 000000000000..a1f5ad0be1bf
--- /dev/null
+++ b/include/linux/nfsd/xdr4.h
@@ -0,0 +1,463 @@
+/*
+ * include/linux/nfsd/xdr4.h
+ *
+ * Server-side types for NFSv4.
+ *
+ * Copyright (c) 2002 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Kendrick Smith <kmsmith@umich.edu>
+ * Andy Adamson <andros@umich.edu>
+ *
+ * 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.
+ *
+ */
+
+#ifndef _LINUX_NFSD_XDR4_H
+#define _LINUX_NFSD_XDR4_H
+
+#include <linux/nfs4.h>
+
+#define NFSD4_MAX_TAGLEN 128
+#define XDR_LEN(n) (((n) + 3) & ~3)
+
+struct nfsd4_change_info {
+ u32 atomic;
+ u32 before_ctime_sec;
+ u32 before_ctime_nsec;
+ u32 after_ctime_sec;
+ u32 after_ctime_nsec;
+};
+
+struct nfsd4_access {
+ u32 ac_req_access; /* request */
+ u32 ac_supported; /* response */
+ u32 ac_resp_access; /* response */
+};
+
+struct nfsd4_close {
+ u32 cl_seqid; /* request */
+ stateid_t cl_stateid; /* request+response */
+ struct nfs4_stateowner * cl_stateowner; /* response */
+};
+
+struct nfsd4_commit {
+ u64 co_offset; /* request */
+ u32 co_count; /* request */
+ nfs4_verifier co_verf; /* response */
+};
+
+struct nfsd4_create {
+ u32 cr_namelen; /* request */
+ char * cr_name; /* request */
+ u32 cr_type; /* request */
+ union { /* request */
+ struct {
+ u32 namelen;
+ char *name;
+ } link; /* NF4LNK */
+ struct {
+ u32 specdata1;
+ u32 specdata2;
+ } dev; /* NF4BLK, NF4CHR */
+ } u;
+ u32 cr_bmval[2]; /* request */
+ struct iattr cr_iattr; /* request */
+ struct nfsd4_change_info cr_cinfo; /* response */
+ struct nfs4_acl *cr_acl;
+};
+#define cr_linklen u.link.namelen
+#define cr_linkname u.link.name
+#define cr_specdata1 u.dev.specdata1
+#define cr_specdata2 u.dev.specdata2
+
+struct nfsd4_delegreturn {
+ stateid_t dr_stateid;
+};
+
+struct nfsd4_getattr {
+ u32 ga_bmval[2]; /* request */
+ struct svc_fh *ga_fhp; /* response */
+};
+
+struct nfsd4_link {
+ u32 li_namelen; /* request */
+ char * li_name; /* request */
+ struct nfsd4_change_info li_cinfo; /* response */
+};
+
+struct nfsd4_lock_denied {
+ clientid_t ld_clientid;
+ struct nfs4_stateowner *ld_sop;
+ u64 ld_start;
+ u64 ld_length;
+ u32 ld_type;
+};
+
+struct nfsd4_lock {
+ /* request */
+ u32 lk_type;
+ u32 lk_reclaim; /* boolean */
+ u64 lk_offset;
+ u64 lk_length;
+ u32 lk_is_new;
+ union {
+ struct {
+ u32 open_seqid;
+ stateid_t open_stateid;
+ u32 lock_seqid;
+ clientid_t clientid;
+ struct xdr_netobj owner;
+ } new;
+ struct {
+ stateid_t lock_stateid;
+ u32 lock_seqid;
+ } old;
+ } v;
+
+ /* response */
+ union {
+ struct {
+ stateid_t stateid;
+ } ok;
+ struct nfsd4_lock_denied denied;
+ } u;
+
+ struct nfs4_stateowner *lk_stateowner;
+};
+#define lk_new_open_seqid v.new.open_seqid
+#define lk_new_open_stateid v.new.open_stateid
+#define lk_new_lock_seqid v.new.lock_seqid
+#define lk_new_clientid v.new.clientid
+#define lk_new_owner v.new.owner
+#define lk_old_lock_stateid v.old.lock_stateid
+#define lk_old_lock_seqid v.old.lock_seqid
+
+#define lk_rflags u.ok.rflags
+#define lk_resp_stateid u.ok.stateid
+#define lk_denied u.denied
+
+
+struct nfsd4_lockt {
+ u32 lt_type;
+ clientid_t lt_clientid;
+ struct xdr_netobj lt_owner;
+ u64 lt_offset;
+ u64 lt_length;
+ struct nfs4_stateowner * lt_stateowner;
+ struct nfsd4_lock_denied lt_denied;
+};
+
+
+struct nfsd4_locku {
+ u32 lu_type;
+ u32 lu_seqid;
+ stateid_t lu_stateid;
+ u64 lu_offset;
+ u64 lu_length;
+ struct nfs4_stateowner *lu_stateowner;
+};
+
+
+struct nfsd4_lookup {
+ u32 lo_len; /* request */
+ char * lo_name; /* request */
+};
+
+struct nfsd4_putfh {
+ u32 pf_fhlen; /* request */
+ char *pf_fhval; /* request */
+};
+
+struct nfsd4_open {
+ u32 op_claim_type; /* request */
+ struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */
+ u32 op_delegate_type; /* request - CLAIM_PREV only */
+ stateid_t op_delegate_stateid; /* request - response */
+ u32 op_create; /* request */
+ u32 op_createmode; /* request */
+ u32 op_bmval[2]; /* request */
+ union { /* request */
+ struct iattr iattr; /* UNCHECKED4,GUARDED4 */
+ nfs4_verifier verf; /* EXCLUSIVE4 */
+ } u;
+ clientid_t op_clientid; /* request */
+ struct xdr_netobj op_owner; /* request */
+ u32 op_seqid; /* request */
+ u32 op_share_access; /* request */
+ u32 op_share_deny; /* request */
+ stateid_t op_stateid; /* response */
+ struct nfsd4_change_info op_cinfo; /* response */
+ u32 op_rflags; /* response */
+ int op_truncate; /* used during processing */
+ struct nfs4_stateowner *op_stateowner; /* used during processing */
+ struct nfs4_acl *op_acl;
+};
+#define op_iattr u.iattr
+#define op_verf u.verf
+
+struct nfsd4_open_confirm {
+ stateid_t oc_req_stateid /* request */;
+ u32 oc_seqid /* request */;
+ stateid_t oc_resp_stateid /* response */;
+ struct nfs4_stateowner * oc_stateowner; /* response */
+};
+
+struct nfsd4_open_downgrade {
+ stateid_t od_stateid;
+ u32 od_seqid;
+ u32 od_share_access;
+ u32 od_share_deny;
+ struct nfs4_stateowner *od_stateowner;
+};
+
+
+struct nfsd4_read {
+ stateid_t rd_stateid; /* request */
+ u64 rd_offset; /* request */
+ u32 rd_length; /* request */
+ struct kvec rd_iov[RPCSVC_MAXPAGES];
+ int rd_vlen;
+ struct file *rd_filp;
+
+ struct svc_rqst *rd_rqstp; /* response */
+ struct svc_fh * rd_fhp; /* response */
+};
+
+struct nfsd4_readdir {
+ u64 rd_cookie; /* request */
+ nfs4_verifier rd_verf; /* request */
+ u32 rd_dircount; /* request */
+ u32 rd_maxcount; /* request */
+ u32 rd_bmval[2]; /* request */
+ struct svc_rqst *rd_rqstp; /* response */
+ struct svc_fh * rd_fhp; /* response */
+
+ struct readdir_cd common;
+ u32 * buffer;
+ int buflen;
+ u32 * offset;
+};
+
+struct nfsd4_release_lockowner {
+ clientid_t rl_clientid;
+ struct xdr_netobj rl_owner;
+};
+struct nfsd4_readlink {
+ struct svc_rqst *rl_rqstp; /* request */
+ struct svc_fh * rl_fhp; /* request */
+};
+
+struct nfsd4_remove {
+ u32 rm_namelen; /* request */
+ char * rm_name; /* request */
+ struct nfsd4_change_info rm_cinfo; /* response */
+};
+
+struct nfsd4_rename {
+ u32 rn_snamelen; /* request */
+ char * rn_sname; /* request */
+ u32 rn_tnamelen; /* request */
+ char * rn_tname; /* request */
+ struct nfsd4_change_info rn_sinfo; /* response */
+ struct nfsd4_change_info rn_tinfo; /* response */
+};
+
+struct nfsd4_setattr {
+ stateid_t sa_stateid; /* request */
+ u32 sa_bmval[2]; /* request */
+ struct iattr sa_iattr; /* request */
+ struct nfs4_acl *sa_acl;
+};
+
+struct nfsd4_setclientid {
+ nfs4_verifier se_verf; /* request */
+ u32 se_namelen; /* request */
+ char * se_name; /* request */
+ u32 se_callback_prog; /* request */
+ u32 se_callback_netid_len; /* request */
+ char * se_callback_netid_val; /* request */
+ u32 se_callback_addr_len; /* request */
+ char * se_callback_addr_val; /* request */
+ u32 se_callback_ident; /* request */
+ clientid_t se_clientid; /* response */
+ nfs4_verifier se_confirm; /* response */
+};
+
+struct nfsd4_setclientid_confirm {
+ clientid_t sc_clientid;
+ nfs4_verifier sc_confirm;
+};
+
+/* also used for NVERIFY */
+struct nfsd4_verify {
+ u32 ve_bmval[2]; /* request */
+ u32 ve_attrlen; /* request */
+ char * ve_attrval; /* request */
+};
+
+struct nfsd4_write {
+ stateid_t wr_stateid; /* request */
+ u64 wr_offset; /* request */
+ u32 wr_stable_how; /* request */
+ u32 wr_buflen; /* request */
+ struct kvec wr_vec[RPCSVC_MAXPAGES]; /* request */
+ int wr_vlen;
+
+ u32 wr_bytes_written; /* response */
+ u32 wr_how_written; /* response */
+ nfs4_verifier wr_verifier; /* response */
+};
+
+struct nfsd4_op {
+ int opnum;
+ int status;
+ union {
+ struct nfsd4_access access;
+ struct nfsd4_close close;
+ struct nfsd4_commit commit;
+ struct nfsd4_create create;
+ struct nfsd4_delegreturn delegreturn;
+ struct nfsd4_getattr getattr;
+ struct svc_fh * getfh;
+ struct nfsd4_link link;
+ struct nfsd4_lock lock;
+ struct nfsd4_lockt lockt;
+ struct nfsd4_locku locku;
+ struct nfsd4_lookup lookup;
+ struct nfsd4_verify nverify;
+ struct nfsd4_open open;
+ struct nfsd4_open_confirm open_confirm;
+ struct nfsd4_open_downgrade open_downgrade;
+ struct nfsd4_putfh putfh;
+ struct nfsd4_read read;
+ struct nfsd4_readdir readdir;
+ struct nfsd4_readlink readlink;
+ struct nfsd4_remove remove;
+ struct nfsd4_rename rename;
+ clientid_t renew;
+ struct nfsd4_setattr setattr;
+ struct nfsd4_setclientid setclientid;
+ struct nfsd4_setclientid_confirm setclientid_confirm;
+ struct nfsd4_verify verify;
+ struct nfsd4_write write;
+ struct nfsd4_release_lockowner release_lockowner;
+ } u;
+ struct nfs4_replay * replay;
+};
+
+struct nfsd4_compoundargs {
+ /* scratch variables for XDR decode */
+ u32 * p;
+ u32 * end;
+ struct page ** pagelist;
+ int pagelen;
+ u32 tmp[8];
+ u32 * tmpp;
+ struct tmpbuf {
+ struct tmpbuf *next;
+ void (*release)(const void *);
+ void *buf;
+ } *to_free;
+
+ struct svc_rqst *rqstp;
+
+ u32 taglen;
+ char * tag;
+ u32 minorversion;
+ u32 opcnt;
+ struct nfsd4_op *ops;
+ struct nfsd4_op iops[8];
+};
+
+struct nfsd4_compoundres {
+ /* scratch variables for XDR encode */
+ u32 * p;
+ u32 * end;
+ struct xdr_buf * xbuf;
+ struct svc_rqst * rqstp;
+
+ u32 taglen;
+ char * tag;
+ u32 opcnt;
+ u32 * tagp; /* where to encode tag and opcount */
+};
+
+#define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs)
+
+static inline void
+set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
+{
+ BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
+ cinfo->atomic = 1;
+ cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
+ cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
+ cinfo->after_ctime_sec = fhp->fh_post_ctime.tv_sec;
+ cinfo->after_ctime_nsec = fhp->fh_post_ctime.tv_nsec;
+}
+
+int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *);
+int nfs4svc_decode_compoundargs(struct svc_rqst *, u32 *,
+ struct nfsd4_compoundargs *);
+int nfs4svc_encode_compoundres(struct svc_rqst *, u32 *,
+ struct nfsd4_compoundres *);
+void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
+void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op);
+int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
+ struct dentry *dentry, u32 *buffer, int *countp,
+ u32 *bmval, struct svc_rqst *);
+extern int nfsd4_setclientid(struct svc_rqst *rqstp,
+ struct nfsd4_setclientid *setclid);
+extern int nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
+ struct nfsd4_setclientid_confirm *setclientid_confirm);
+extern int nfsd4_process_open1(struct nfsd4_open *open);
+extern int nfsd4_process_open2(struct svc_rqst *rqstp,
+ struct svc_fh *current_fh, struct nfsd4_open *open);
+extern int nfsd4_open_confirm(struct svc_rqst *rqstp,
+ struct svc_fh *current_fh, struct nfsd4_open_confirm *oc);
+extern int nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh,
+ struct nfsd4_close *close);
+extern int nfsd4_open_downgrade(struct svc_rqst *rqstp,
+ struct svc_fh *current_fh, struct nfsd4_open_downgrade *od);
+extern int nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh,
+ struct nfsd4_lock *lock);
+extern int nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh,
+ struct nfsd4_lockt *lockt);
+extern int nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh,
+ struct nfsd4_locku *locku);
+extern int
+nfsd4_release_lockowner(struct svc_rqst *rqstp,
+ struct nfsd4_release_lockowner *rlockowner);
+extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *);
+extern int nfsd4_delegreturn(struct svc_rqst *rqstp,
+ struct svc_fh *current_fh, struct nfsd4_delegreturn *dr);
+#endif
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */