summaryrefslogtreecommitdiffstats
path: root/include/linux/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/nfsd')
-rw-r--r--include/linux/nfsd/auth.h45
-rw-r--r--include/linux/nfsd/cache.h79
-rw-r--r--include/linux/nfsd/const.h86
-rw-r--r--include/linux/nfsd/debug.h48
-rw-r--r--include/linux/nfsd/export.h109
-rw-r--r--include/linux/nfsd/nfsd.h169
-rw-r--r--include/linux/nfsd/nfsfh.h170
-rw-r--r--include/linux/nfsd/stats.h27
-rw-r--r--include/linux/nfsd/syscall.h127
-rw-r--r--include/linux/nfsd/xdr.h158
-rw-r--r--include/linux/nfsd/xdr3.h268
11 files changed, 1286 insertions, 0 deletions
diff --git a/include/linux/nfsd/auth.h b/include/linux/nfsd/auth.h
new file mode 100644
index 000000000..ec2c9d7bf
--- /dev/null
+++ b/include/linux/nfsd/auth.h
@@ -0,0 +1,45 @@
+/*
+ * 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
+ */
+void nfsd_setuser(struct svc_rqst *, struct svc_export *);
+
+#if 0
+/*
+ * These must match the actual size of uid_t and gid_t
+ */
+#define UGID_BITS (8 * sizeof(uid_t))
+#define UGID_SHIFT 8
+#define UGID_MASK ((1 << UGID_SHIFT) - 1)
+#define UGID_NRENTRIES ((1 << (UGID_BITS - UGID_SHIFT)) + 1)
+#define UGID_NONE ((unsigned short)-1)
+
+typedef struct svc_uidmap {
+ uid_t * um_ruid[UGID_NRENTRIES];
+ uid_t * um_luid[UGID_NRENTRIES];
+ gid_t * um_rgid[UGID_NRENTRIES];
+ gid_t * um_lgid[UGID_NRENTRIES];
+} svc_uidmap;
+#endif
+
+#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 000000000..8e675705e
--- /dev/null
+++ b/include/linux/nfsd/cache.h
@@ -0,0 +1,79 @@
+/*
+ * 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/sched.h>
+
+/*
+ * Representation of a reply cache entry. The first two members *must*
+ * be hash_next and hash_prev.
+ */
+struct svc_cacherep {
+ struct svc_cacherep * c_hash_next;
+ struct svc_cacherep * c_hash_prev;
+ struct svc_cacherep * c_lru_next;
+ struct svc_cacherep * c_lru_prev;
+ unsigned char c_state, /* unused, inprog, done */
+ c_type, /* status, buffer */
+ c_secure : 1; /* req came from port < 1024 */
+ struct in_addr c_client;
+ u32 c_xid;
+ u32 c_proc;
+ unsigned long c_timestamp;
+ union {
+ struct svc_buf u_buffer;
+ u32 u_status;
+ } c_u;
+};
+
+#define c_replbuf c_u.u_buffer
+#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 000000000..0727e1288
--- /dev/null
+++ b/include/linux/nfsd/const.h
@@ -0,0 +1,86 @@
+/*
+ * include/linux/nfsd/nfsconst.h
+ *
+ * Various constants related to NFS.
+ *
+ * Copyright (C) 1995 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef __NFSCONST_H__
+#define __NFSCONST_H__
+
+#include <linux/limits.h>
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <linux/dirent.h>
+#include <linux/fs.h>
+#include <linux/nfs.h>
+
+/*
+ * Maximum protocol version supported by knfsd
+ */
+#define NFSSVC_MAXVERS 3
+
+/*
+ * Maximum blocksize supported by daemon currently at 8K
+ */
+#define NFSSVC_MAXBLKSIZE 8192
+
+#define NFS2_MAXPATHLEN 1024
+#define NFS2_MAXNAMLEN 255
+#define NFS2_FHSIZE NFS_FHSIZE
+#define NFS2_COOKIESIZE 4
+
+#define NFS3_MAXPATHLEN PATH_MAX
+#define NFS3_MAXNAMLEN NAME_MAX
+#define NFS3_FHSIZE NFS_FHSIZE
+#define NFS3_COOKIEVERFSIZE 8
+#define NFS3_CREATEVERFSIZE 8
+#define NFS3_WRITEVERFSIZE 8
+
+#ifdef __KERNEL__
+
+#ifndef NFS_SUPER_MAGIC
+# define NFS_SUPER_MAGIC 0x6969
+#endif
+
+/*
+ * NFS stats. The good thing with these values is that NFSv3 errors are
+ * a superset of NFSv2 errors (with the exception of NFSERR_WFLUSH which
+ * no-one uses anyway), so we can happily mix code as long as we make sure
+ * no NFSv3 errors are returned to NFSv2 clients.
+ */
+#define NFS_OK 0 /* v2 v3 */
+#define NFSERR_PERM 1 /* v2 v3 */
+#define NFSERR_NOENT 2 /* v2 v3 */
+#define NFSERR_IO 5 /* v2 v3 */
+#define NFSERR_NXIO 6 /* v2 v3 */
+#define NFSERR_ACCES 13 /* v2 v3 */
+#define NFSERR_EXIST 17 /* v2 v3 */
+#define NFSERR_XDEV 18 /* v3 */
+#define NFSERR_NODEV 19 /* v2 v3 */
+#define NFSERR_NOTDIR 20 /* v2 v3 */
+#define NFSERR_ISDIR 21 /* v2 v3 */
+#define NFSERR_INVAL 22 /* v3 */
+#define NFSERR_FBIG 27 /* v2 v3 */
+#define NFSERR_NOSPC 28 /* v2 v3 */
+#define NFSERR_ROFS 30 /* v2 v3 */
+#define NFSERR_MLINK 31 /* v3 */
+#define NFSERR_NAMETOOLONG 63 /* v2 v3 */
+#define NFSERR_NOTEMPTY 66 /* v2 v3 */
+#define NFSERR_DQUOT 69 /* v2 v3 */
+#define NFSERR_STALE 70 /* v2 v3 */
+#define NFSERR_REMOTE 71 /* v3 */
+#define NFSERR_WFLUSH 99 /* v2 */
+#define NFSERR_BADHANDLE 10001 /* v3 */
+#define NFSERR_NOT_SYNC 10002 /* v3 */
+#define NFSERR_BAD_COOKIE 10003 /* v3 */
+#define NFSERR_NOTSUPP 10004 /* v3 */
+#define NFSERR_TOOSMALL 10005 /* v3 */
+#define NFSERR_SERVERFAULT 10006 /* v3 */
+#define NFSERR_BADTYPE 10007 /* v3 */
+#define NFSERR_JUKEBOX 10008 /* v3 */
+
+#endif /* __KERNEL__ */
+
+#endif /* __NFSCONST_H__ */
diff --git a/include/linux/nfsd/debug.h b/include/linux/nfsd/debug.h
new file mode 100644
index 000000000..ee4aa9178
--- /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 000000000..b0e3499ec
--- /dev/null
+++ b/include/linux/nfsd/export.h
@@ -0,0 +1,109 @@
+/*
+ * include/linux/nfsd/export.h
+ *
+ * Public declarations for NFS exports. The definitions for the
+ * syscall interface are in nfsctl.h
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef NFSD_EXPORT_H
+#define NFSD_EXPORT_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/fs.h>
+
+/*
+ * 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
+#define NFSEXP_UIDMAP 0x0040
+#define NFSEXP_KERBEROS 0x0080 /* not available */
+#define NFSEXP_SUNSECURE 0x0100
+#define NFSEXP_CROSSMNT 0x0200 /* not available */
+#define NFSEXP_ALLFLAGS 0x03FF
+
+
+#ifdef __KERNEL__
+
+/* The following are hashtable sizes and must be powers of 2 */
+#define NFSCLNT_EXPMAX 16
+
+struct svc_client {
+ struct svc_client * cl_next;
+ char cl_ident[NFSCLNT_IDMAX];
+ int cl_idlen;
+ int cl_naddr;
+ struct in_addr cl_addr[NFSCLNT_ADDRMAX];
+ struct svc_uidmap * cl_umap;
+ struct svc_export * cl_export[NFSCLNT_EXPMAX];
+};
+
+struct svc_export {
+ struct svc_export * ex_next;
+ char ex_path[NFS_MAXPATHLEN+1];
+ struct svc_export * ex_parent;
+ struct svc_client * ex_client;
+ int ex_flags;
+ struct inode * ex_inode;
+ dev_t ex_dev;
+ ino_t ex_ino;
+ uid_t ex_anon_uid;
+ gid_t ex_anon_gid;
+};
+
+#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_CROSSMNT(exp) ((exp)->ex_flags & NFSEXP_CROSSMNT)
+#define EX_SUNSECURE(exp) ((exp)->ex_flags & NFSEXP_SUNSECURE)
+#define EX_WGATHER(exp) ((exp)->ex_flags & NFSEXP_GATHERED_WRITES)
+
+
+/*
+ * Function declarations
+ */
+void nfsd_export_init(void);
+void nfsd_export_shutdown(void);
+void exp_readlock(void);
+int exp_writelock(void);
+void exp_unlock(void);
+struct svc_client * exp_getclient(struct sockaddr_in *sin);
+void exp_putclient(struct svc_client *clp);
+struct svc_export * exp_get(struct svc_client *clp, dev_t dev, ino_t ino);
+int exp_rootfh(struct svc_client *, dev_t, ino_t,
+ struct knfs_fh *);
+int nfserrno(int errno);
+void exp_nlmdetach(void);
+
+
+extern __inline__ int
+exp_checkaddr(struct svc_client *clp, struct in_addr addr)
+{
+ struct in_addr *ap = clp->cl_addr;
+ int i;
+
+ for (i = clp->cl_naddr; i--; ap++)
+ if (ap->s_addr == addr.s_addr)
+ return 1;
+ return 0;
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* NFSD_EXPORT_H */
+
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
new file mode 100644
index 000000000..ed42bb042
--- /dev/null
+++ b/include/linux/nfsd/nfsd.h
@@ -0,0 +1,169 @@
+/*
+ * linux/include/linux/nfsd/nfsd.h
+ *
+ * Hodge-podge collection of knfsd-related stuff.
+ * I will sort this out later.
+ *
+ * Copyright (C) 1995 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef LINUX_NFSD_NFSD_H
+#define LINUX_NFSD_NFSD_H
+
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <linux/dirent.h>
+#include <linux/fs.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>
+
+/*
+ * nfsd version
+ */
+#define NFSD_VERSION "0.4"
+
+/*
+ * Maximum number of nfsd processes
+ */
+#define NFSD_MAXSERVS 16
+
+#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
+#if (MAY_SATTR | MAY_TRUNC) & (MAY_READ | MAY_WRITE | MAY_EXEC)
+# error "please use a different value for MAY_SATTR or MAY_TRUNC."
+#endif
+#define MAY_CREATE (MAY_EXEC|MAY_WRITE)
+#define MAY_REMOVE (MAY_EXEC|MAY_WRITE|MAY_TRUNC)
+
+/*
+ * Callback function for readdir
+ */
+struct readdir_cd {
+ struct svc_rqst * rqstp;
+ struct svc_fh * dirfh;
+ u32 * buffer;
+ int buflen;
+ u32 * offset; /* previous dirent->d_next */
+ char plus; /* readdirplus */
+ char eob; /* end of buffer */
+ char dotonly;
+};
+typedef int (*encode_dent_fn)(struct readdir_cd *, const char *,
+ int, off_t, ino_t);
+
+/*
+ * Procedure table for NFSv2
+ */
+extern struct svc_procedure nfsd_procedures2[];
+extern struct svc_program nfsd_program;
+
+/*
+ * Function prototypes.
+ */
+int nfsd_svc(unsigned short port, int nrservs);
+
+void nfsd_racache_init(void);
+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 nfsd_create(struct svc_rqst *, struct svc_fh *,
+ char *name, int len, struct iattr *attrs,
+ int type, dev_t rdev, struct svc_fh *res);
+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 *,
+ loff_t, char *, unsigned long *);
+int nfsd_write(struct svc_rqst *, struct svc_fh *,
+ loff_t, char *, 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);
+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, encode_dent_fn,
+ u32 *buffer, int *countp);
+int nfsd_statfs(struct svc_rqst *, struct svc_fh *,
+ struct statfs *);
+int nfsd_notify_change(struct inode *, struct iattr *);
+int nfsd_permission(struct svc_export *, struct inode *, int);
+void nfsd_write_inode(struct inode *);
+struct inode * nfsd_iget(dev_t dev, ino_t ino);
+int nfsd_parentdev(dev_t *devp);
+
+/*
+ * lockd binding
+ */
+void nfsd_lockd_init(void);
+void nfsd_lockd_shutdown(void);
+void nfsd_lockd_unexport(struct svc_client *);
+
+
+#ifndef makedev
+#define makedev(maj, min) (((maj) << 8) | (min))
+#endif
+
+/*
+ * These variables contain pre-xdr'ed values for faster operation.
+ * FIXME: should be replaced by macros for big-endian machines.
+ */
+extern u32 nfs_ok,
+ nfserr_perm,
+ nfserr_noent,
+ nfserr_io,
+ nfserr_nxio,
+ nfserr_acces,
+ nfserr_exist,
+ nfserr_xdev,
+ nfserr_nodev,
+ nfserr_notdir,
+ nfserr_isdir,
+ nfserr_inval,
+ nfserr_fbig,
+ nfserr_nospc,
+ nfserr_rofs,
+ nfserr_mlink,
+ nfserr_nametoolong,
+ nfserr_dquot,
+ nfserr_stale,
+ nfserr_remote,
+ nfserr_badhandle,
+ nfserr_notsync,
+ nfserr_badcookie,
+ nfserr_notsupp,
+ nfserr_toosmall,
+ nfserr_serverfault,
+ nfserr_badtype,
+ nfserr_jukebox;
+
+/*
+ * Time of server startup
+ */
+extern struct timeval nfssvc_boot;
+
+#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 000000000..320a2816c
--- /dev/null
+++ b/include/linux/nfsd/nfsfh.h
@@ -0,0 +1,170 @@
+/*
+ * 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 NFSD_FH_H
+#define NFSD_FH_H
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/nfsd/const.h>
+#include <linux/nfsd/debug.h>
+
+/*
+ * This is our NFSv2 file handle.
+ *
+ * The xdev and xino fields are currently used to transport the dev/ino
+ * of the exported inode. The xdev field is redundant, though, because
+ * we do not allow mount point crossing.
+ */
+struct nfs_fhbase {
+ dev_t fb_dev;
+ dev_t fb_xdev;
+ ino_t fb_ino;
+ ino_t fb_xino;
+ __u32 fb_version;
+};
+
+#define NFS_FH_PADDING (NFS_FHSIZE - sizeof(struct nfs_fhbase))
+struct knfs_fh {
+ struct nfs_fhbase fh_base;
+ __u8 fh_cookie[NFS_FH_PADDING];
+};
+
+#define fh_dev fh_base.fb_dev
+#define fh_xdev fh_base.fb_xdev
+#define fh_ino fh_base.fb_ino
+#define fh_xino fh_base.fb_xino
+#define fh_version fh_base.fb_version
+
+
+#ifdef __KERNEL__
+
+/*
+ * 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 knfs_fh fh_handle; /* FH data */
+ struct svc_export * fh_export; /* export pointer */
+ struct inode * fh_inode; /* inode */
+ size_t fh_pre_size; /* size before operation */
+ time_t fh_pre_mtime; /* mtime before oper */
+ time_t fh_pre_ctime; /* ctime before oper */
+ unsigned long fh_post_version;/* inode version after oper */
+ unsigned char fh_locked; /* inode locked by us */
+} svc_fh;
+
+/*
+ * Shorthands for dprintk()'s
+ */
+#define SVCFH_INO(f) ((f)->fh_handle.fh_ino)
+#define SVCFH_DEV(f) ((f)->fh_handle.fh_dev)
+
+/*
+ * Function prototypes
+ */
+u32 fh_lookup(struct svc_rqst *, struct svc_fh *, int, int);
+void fh_compose(struct svc_fh *, struct svc_export *,
+ struct inode *);
+
+static __inline__ struct svc_fh *
+fh_copy(struct svc_fh *dst, struct svc_fh *src)
+{
+ *dst = *src;
+ return dst;
+}
+
+static __inline__ struct svc_fh *
+fh_init(struct svc_fh *fhp)
+{
+ memset(fhp, 0, sizeof(*fhp));
+ return fhp;
+}
+
+/*
+ * Lock a file handle/inode
+ */
+static inline void
+fh_lock(struct svc_fh *fhp)
+{
+ struct inode *inode = fhp->fh_inode;
+
+ /*
+ dfprintk(FILEOP, "nfsd: fh_lock(%x/%ld) locked = %d\n",
+ SVCFH_DEV(fhp), SVCFH_INO(fhp), fhp->fh_locked);
+ */
+ if (!fhp->fh_locked) {
+ down(&inode->i_sem);
+ if (!fhp->fh_pre_mtime)
+ fhp->fh_pre_mtime = inode->i_mtime;
+ fhp->fh_locked = 1;
+ }
+}
+
+/*
+ * Unlock a file handle/inode
+ */
+static inline void
+fh_unlock(struct svc_fh *fhp)
+{
+ struct inode *inode = fhp->fh_inode;
+
+ if (fhp->fh_locked) {
+ if (!fhp->fh_post_version)
+ fhp->fh_post_version = inode->i_version;
+ fhp->fh_locked = 0;
+ up(&inode->i_sem);
+ }
+}
+
+/*
+ * Release an inode
+ */
+#ifndef NFSD_DEBUG
+static inline void
+fh_put(struct svc_fh *fhp)
+{
+ if (fhp->fh_inode) {
+ fh_unlock(fhp);
+ iput(fhp->fh_inode);
+ }
+}
+#else
+#define fh_put(fhp) __fh_put(fhp, __FILE__, __LINE__)
+
+static inline void
+__fh_put(struct svc_fh *fhp, char *file, int line)
+{
+ struct inode *inode;
+
+ if (!(inode = fhp->fh_inode))
+ return;
+
+ if (!inode->i_count) {
+ printk("nfsd: trying to free free inode in %s:%d\n"
+ " dev %04x ino %ld, mode %07o\n",
+ file, line, inode->i_dev,
+ inode->i_ino, inode->i_mode);
+ } else {
+ fh_unlock(fhp);
+ iput(inode);
+ }
+}
+#endif
+
+
+
+#endif /* __KERNEL__ */
+
+#endif /* NFSD_FH_H */
diff --git a/include/linux/nfsd/stats.h b/include/linux/nfsd/stats.h
new file mode 100644
index 000000000..ab4bd68c0
--- /dev/null
+++ b/include/linux/nfsd/stats.h
@@ -0,0 +1,27 @@
+/*
+ * 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 */
+};
+
+#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 000000000..98c5d5a6e
--- /dev/null
+++ b/include/linux/nfsd/syscall.h
@@ -0,0 +1,127 @@
+/*
+ * include/linux/nfsd/syscall.h
+ *
+ * This file holds all declarations for the knfsd syscall interface.
+ *
+ * Copyright (C) 1995 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef NFSD_SYSCALL_H
+#define NFSD_SYSCALL_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/socket.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. */
+#define NFSCTL_GETFH 6 /* get an fh (used by mountd) */
+
+
+/* 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];
+ dev_t ex_dev;
+ ino_t ex_ino;
+ int ex_flags;
+ uid_t ex_anon_uid;
+ gid_t ex_anon_gid;
+};
+
+/* UGIDUPDATE */
+struct nfsctl_uidmap {
+ char * ug_ident;
+ uid_t ug_uidbase;
+ int ug_uidlen;
+ uid_t * ug_udimap;
+ uid_t ug_gidbase;
+ int ug_gidlen;
+ gid_t * ug_gdimap;
+};
+
+/* GETFH */
+struct nfsctl_fhparm {
+ struct sockaddr gf_addr;
+ dev_t gf_dev;
+ ino_t gf_ino;
+ int gf_version;
+};
+
+/*
+ * 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_uidmap u_umap;
+ struct nfsctl_fhparm u_getfh;
+ unsigned int u_debug;
+ } u;
+#define ca_svc u.u_svc
+#define ca_client u.u_client
+#define ca_export u.u_export
+#define ca_umap u.u_umap
+#define ca_getfh u.u_getfh
+#define ca_authd u.u_authd
+#define ca_debug u.u_debug
+};
+
+union nfsctl_res {
+ struct knfs_fh cr_getfh;
+ unsigned int cr_debug;
+};
+
+#ifdef __KERNEL__
+/*
+ * Kernel syscall implementation.
+ */
+#ifdef CONFIG_NFSD
+extern asmlinkage int sys_nfsservctl(int, struct nfsctl_arg *,
+ union nfsctl_res *);
+#else
+# define sys_nfsservctl sys_ni_syscall
+#endif
+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 000000000..3ff82382e
--- /dev/null
+++ b/include/linux/nfsd/xdr.h
@@ -0,0 +1,158 @@
+/*
+ * 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/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;
+ __u32 totalsize;
+};
+
+struct nfsd_writeargs {
+ svc_fh fh;
+ __u32 beginoffset;
+ __u32 offset;
+ __u32 totalcount;
+ __u8 * data;
+ int len;
+};
+
+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_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;
+};
+
+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 nfsd_statfsres {
+ struct statfs 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 NFSSVC_XDRSIZE sizeof(union nfsd_xdrstore)
+
+void nfsd_xdr_init(void);
+
+int nfssvc_decode_void(struct svc_rqst *, u32 *, void *);
+int nfssvc_decode_fhandle(struct svc_rqst *, u32 *, struct svc_fh *);
+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_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_release_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
+
+int nfssvc_encode_entry(struct readdir_cd *, const char *name,
+ int namlen, off_t offset, ino_t ino);
+
+#endif /* LINUX_NFSD_H */
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h
new file mode 100644
index 000000000..54e11c549
--- /dev/null
+++ b/include/linux/nfsd/xdr3.h
@@ -0,0 +1,268 @@
+/*
+ * linux/include/linux/nfsd/xdr3.h
+ *
+ * XDR types for NFSv3 in nfsd.
+ *
+ * Copyright (C) 1996, 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;
+ 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 nfsd3_writeargs {
+ svc_fh fh;
+ __u64 offset;
+ __u32 count;
+ int stable;
+ __u8 * data;
+ int len;
+};
+
+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_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;
+ __u32 cookie;
+ __u32 dircount;
+ __u32 count;
+ __u32 * verf;
+};
+
+struct nfsd3_commitargs {
+ struct svc_fh fh;
+ __u64 offset;
+ __u64 count;
+};
+
+struct nfsd3_attrstat {
+ __u32 status;
+ struct svc_fh fh;
+};
+
+struct nfsd3_lookupres {
+ __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_createres {
+ __u32 status;
+ struct svc_fh dirfh;
+ struct svc_fh fh;
+};
+
+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;
+ __u32 * list_end;
+};
+
+struct nfsd3_statfsres {
+ __u32 status;
+ struct statfs 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_case_insensitive;
+ __u32 p_case_preserving;
+};
+
+struct nfsd3_commitres {
+ __u32 status;
+ struct svc_fh fh;
+};
+
+/* dummy type for release */
+struct nfsd3_fhandle2 {
+ __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_lookupres lookupres;
+ struct nfsd3_accessres accessres;
+ struct nfsd3_readlinkres readlinkres;
+ struct nfsd3_readres readres;
+ struct nfsd3_writeres writeres;
+ struct nfsd3_createres createres;
+ struct nfsd3_renameres renameres;
+ struct nfsd3_linkres linkres;
+ struct nfsd3_readdirres readdirres;
+ struct nfsd3_statfsres statfsres;
+ struct nfsd3_fsinfores fsinfores;
+ struct nfsd3_pathconfres pathconfres;
+ struct nfsd3_commitres commitres;
+};
+
+#define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore)
+
+void nfsxdr_init(void);
+
+int nfs3svc_decode_fhandle(struct svc_rqst *, u32 *, struct svc_fh *);
+int nfs3svc_decode_sattr3args(struct svc_rqst *, u32 *,
+ struct nfsd3_sattrargs *);
+int nfs3svc_decode_dirop3args(struct svc_rqst *, u32 *,
+ struct nfsd3_diropargs *);
+int nfs3svc_decode_read3args(struct svc_rqst *, u32 *,
+ struct nfsd3_readargs *);
+int nfs3svc_decode_write3args(struct svc_rqst *, u32 *,
+ struct nfsd3_writeargs *);
+int nfs3svc_decode_create3args(struct svc_rqst *, u32 *,
+ struct nfsd3_createargs *);
+int nfs3svc_decode_rename3args(struct svc_rqst *, u32 *,
+ struct nfsd3_renameargs *);
+int nfs3svc_decode_link3args(struct svc_rqst *, u32 *,
+ struct nfsd3_linkargs *);
+int nfs3svc_decode_symlink3args(struct svc_rqst *, u32 *,
+ struct nfsd3_symlinkargs *);
+int nfs3svc_decode_readdir3args(struct svc_rqst *, u32 *,
+ struct nfsd3_readdirargs *);
+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_statfsres(struct svc_rqst *, u32 *,
+ struct nfsd3_statfsres *);
+int nfs3svc_encode_readdirres(struct svc_rqst *, u32 *,
+ struct nfsd3_readdirres *);
+int nfs3svc_release_fhandle(struct svc_rqst *, u32 *,
+ struct nfsd_fhandle *);
+int nfs3svc_release_fhandle2(struct svc_rqst *, u32 *,
+ struct nfsd3_fhandle2 *);
+int nfs3svc_encode_entry(struct readdir_cd *, const char *name,
+ int namlen, unsigned long offset, ino_t ino);
+
+#endif /* LINUX_NFSD_XDR3_H */