Creation of Cybook 2416 (actually Gen4) repository
This commit is contained in:
7
include/linux/nfsd/Kbuild
Normal file
7
include/linux/nfsd/Kbuild
Normal file
@@ -0,0 +1,7 @@
|
||||
unifdef-y += const.h
|
||||
unifdef-y += export.h
|
||||
unifdef-y += stats.h
|
||||
unifdef-y += syscall.h
|
||||
unifdef-y += nfsfh.h
|
||||
unifdef-y += debug.h
|
||||
unifdef-y += auth.h
|
||||
27
include/linux/nfsd/auth.h
Normal file
27
include/linux/nfsd/auth.h
Normal file
@@ -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 */
|
||||
81
include/linux/nfsd/cache.h
Normal file
81
include/linux/nfsd/cache.h
Normal file
@@ -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;
|
||||
__be32 c_xid;
|
||||
u32 c_prot;
|
||||
u32 c_proc;
|
||||
u32 c_vers;
|
||||
unsigned long c_timestamp;
|
||||
union {
|
||||
struct kvec u_vec;
|
||||
__be32 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, __be32 *);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* NFSCACHE_H */
|
||||
55
include/linux/nfsd/const.h
Normal file
55
include/linux/nfsd/const.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 blocksizes supported by daemon under various circumstances.
|
||||
*/
|
||||
#define NFSSVC_MAXBLKSIZE RPCSVC_MAXPAYLOAD
|
||||
/* NFSv2 is limited by the protocol specification, see RFC 1094 */
|
||||
#define NFSSVC_MAXBLKSIZE_V2 (8*1024)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/sunrpc/msg_prot.h>
|
||||
|
||||
/*
|
||||
* Largest number of bytes we need to allocate for an NFS
|
||||
* call or reply. Used to control buffer sizes. We use
|
||||
* the length of v3 WRITE, READDIR and READDIR replies
|
||||
* which are an RPC header, up to 26 XDR units of reply
|
||||
* data, and some page data.
|
||||
*
|
||||
* Note that accuracy here doesn't matter too much as the
|
||||
* size is rounded up to a page size when allocating space.
|
||||
*/
|
||||
#define NFSD_BUFSIZE ((RPC_MAX_HEADER_WITH_AUTH+26)*XDR_UNIT + 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 */
|
||||
48
include/linux/nfsd/debug.h
Normal file
48
include/linux/nfsd/debug.h
Normal file
@@ -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 */
|
||||
142
include/linux/nfsd/export.h
Normal file
142
include/linux/nfsd/export.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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__
|
||||
|
||||
/*
|
||||
* FS Locations
|
||||
*/
|
||||
|
||||
#define MAX_FS_LOCATIONS 128
|
||||
|
||||
struct nfsd4_fs_location {
|
||||
char *hosts; /* colon separated list of hosts */
|
||||
char *path; /* slash separated list of path components */
|
||||
};
|
||||
|
||||
struct nfsd4_fs_locations {
|
||||
uint32_t locations_count;
|
||||
struct nfsd4_fs_location *locations;
|
||||
/* If we're not actually serving this data ourselves (only providing a
|
||||
* list of replicas that do serve it) then we set "migrated": */
|
||||
int migrated;
|
||||
};
|
||||
|
||||
struct svc_export {
|
||||
struct cache_head h;
|
||||
struct auth_domain * ex_client;
|
||||
int ex_flags;
|
||||
struct vfsmount * ex_mnt;
|
||||
struct dentry * ex_dentry;
|
||||
char * ex_path;
|
||||
uid_t ex_anon_uid;
|
||||
gid_t ex_anon_gid;
|
||||
int ex_fsid;
|
||||
unsigned char * ex_uuid; /* 16 byte fsid */
|
||||
struct nfsd4_fs_locations ex_fslocs;
|
||||
};
|
||||
|
||||
/* an "export key" (expkey) maps a filehandlefragement to an
|
||||
* svc_export for a given client. There can be several per export,
|
||||
* for the different fsid types.
|
||||
*/
|
||||
struct svc_expkey {
|
||||
struct cache_head h;
|
||||
|
||||
struct auth_domain * ek_client;
|
||||
int ek_fsidtype;
|
||||
u32 ek_fsid[6];
|
||||
|
||||
struct vfsmount * ek_mnt;
|
||||
struct dentry * ek_dentry;
|
||||
};
|
||||
|
||||
#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_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);
|
||||
__be32 exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp, struct cache_req *creq);
|
||||
__be32 nfserrno(int errno);
|
||||
|
||||
extern struct cache_detail svc_export_cache;
|
||||
|
||||
static inline void exp_put(struct svc_export *exp)
|
||||
{
|
||||
cache_put(&exp->h, &svc_export_cache);
|
||||
}
|
||||
|
||||
static inline void exp_get(struct svc_export *exp)
|
||||
{
|
||||
cache_get(&exp->h);
|
||||
}
|
||||
extern struct svc_export *
|
||||
exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
|
||||
struct cache_req *reqp);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* NFSD_EXPORT_H */
|
||||
|
||||
13
include/linux/nfsd/interface.h
Normal file
13
include/linux/nfsd/interface.h
Normal file
@@ -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 */
|
||||
325
include/linux/nfsd/nfsd.h
Normal file
325
include/linux/nfsd/nfsd.h
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* 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/types.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/dirent.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/posix_acl.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 {
|
||||
__be32 err; /* 0, nfserr, or nfserr_eof */
|
||||
};
|
||||
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;
|
||||
extern struct svc_serv *nfsd_serv;
|
||||
/*
|
||||
* Function prototypes.
|
||||
*/
|
||||
int nfsd_svc(unsigned short port, int nrservs);
|
||||
int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *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);
|
||||
__be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *,
|
||||
const char *, int, struct svc_fh *);
|
||||
__be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *,
|
||||
struct iattr *, int, time_t);
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
__be32 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 */
|
||||
__be32 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
|
||||
__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
|
||||
__be32 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 *created);
|
||||
__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
|
||||
loff_t, unsigned long);
|
||||
#endif /* CONFIG_NFSD_V3 */
|
||||
__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int,
|
||||
int, struct file **);
|
||||
void nfsd_close(struct file *);
|
||||
__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *,
|
||||
loff_t, struct kvec *, int, unsigned long *);
|
||||
__be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
|
||||
loff_t, struct kvec *,int, unsigned long, int *);
|
||||
__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *,
|
||||
char *, int *);
|
||||
__be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *,
|
||||
char *name, int len, char *path, int plen,
|
||||
struct svc_fh *res, struct iattr *);
|
||||
__be32 nfsd_link(struct svc_rqst *, struct svc_fh *,
|
||||
char *, int, struct svc_fh *);
|
||||
__be32 nfsd_rename(struct svc_rqst *,
|
||||
struct svc_fh *, char *, int,
|
||||
struct svc_fh *, char *, int);
|
||||
__be32 nfsd_remove(struct svc_rqst *,
|
||||
struct svc_fh *, char *, int);
|
||||
__be32 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);
|
||||
__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
|
||||
loff_t *, struct readdir_cd *, filldir_t);
|
||||
__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
|
||||
struct kstatfs *);
|
||||
|
||||
int nfsd_notify_change(struct inode *, struct iattr *);
|
||||
__be32 nfsd_permission(struct svc_export *, struct dentry *, int);
|
||||
int nfsd_sync_dir(struct dentry *dp);
|
||||
|
||||
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
|
||||
#ifdef CONFIG_NFSD_V2_ACL
|
||||
extern struct svc_version nfsd_acl_version2;
|
||||
#else
|
||||
#define nfsd_acl_version2 NULL
|
||||
#endif
|
||||
#ifdef CONFIG_NFSD_V3_ACL
|
||||
extern struct svc_version nfsd_acl_version3;
|
||||
#else
|
||||
#define nfsd_acl_version3 NULL
|
||||
#endif
|
||||
struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
|
||||
int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
|
||||
#endif
|
||||
|
||||
enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
|
||||
int nfsd_vers(int vers, enum vers_op change);
|
||||
void nfsd_reset_versions(void);
|
||||
int nfsd_create_serv(void);
|
||||
|
||||
extern int nfsd_max_blksize;
|
||||
|
||||
/*
|
||||
* NFSv4 State
|
||||
*/
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
void nfs4_state_init(void);
|
||||
int nfs4_state_start(void);
|
||||
void nfs4_state_shutdown(void);
|
||||
time_t nfs4_lease_time(void);
|
||||
void nfs4_reset_lease(time_t leasetime);
|
||||
int nfs4_reset_recoverydir(char *recdir);
|
||||
#else
|
||||
static inline void nfs4_state_init(void){};
|
||||
static inline int nfs4_state_start(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){}
|
||||
static inline int nfs4_reset_recoverydir(char *recdir) {return 0;}
|
||||
#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_moved __constant_htonl(NFSERR_MOVED)
|
||||
#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)
|
||||
#define nfserr_locked __constant_htonl(NFSERR_LOCKED)
|
||||
#define nfserr_replay_me __constant_htonl(NFSERR_REPLAY_ME)
|
||||
|
||||
/* 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;
|
||||
|
||||
#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 bytes 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 bytes 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)
|
||||
* 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_FS_LOCATIONS | 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 */
|
||||
389
include/linux/nfsd/nfsfh.h
Normal file
389
include/linux/nfsd/nfsfh.h
Normal file
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
* 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/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 */
|
||||
__be32 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;
|
||||
|
||||
enum nfsd_fsid {
|
||||
FSID_DEV = 0,
|
||||
FSID_NUM,
|
||||
FSID_MAJOR_MINOR,
|
||||
FSID_ENCODE_DEV,
|
||||
FSID_UUID4_INUM,
|
||||
FSID_UUID8,
|
||||
FSID_UUID16,
|
||||
FSID_UUID16_INUM,
|
||||
};
|
||||
|
||||
enum fsid_source {
|
||||
FSIDSOURCE_DEV,
|
||||
FSIDSOURCE_FSID,
|
||||
FSIDSOURCE_UUID,
|
||||
};
|
||||
extern enum fsid_source fsid_source(struct svc_fh *fhp);
|
||||
|
||||
|
||||
/* This might look a little large to "inline" but in all calls except
|
||||
* one, 'vers' is constant so moste of the function disappears.
|
||||
*/
|
||||
static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino,
|
||||
u32 fsid, unsigned char *uuid)
|
||||
{
|
||||
u32 *up;
|
||||
switch(vers) {
|
||||
case FSID_DEV:
|
||||
fsidv[0] = htonl((MAJOR(dev)<<16) |
|
||||
MINOR(dev));
|
||||
fsidv[1] = ino_t_to_u32(ino);
|
||||
break;
|
||||
case FSID_NUM:
|
||||
fsidv[0] = fsid;
|
||||
break;
|
||||
case FSID_MAJOR_MINOR:
|
||||
fsidv[0] = htonl(MAJOR(dev));
|
||||
fsidv[1] = htonl(MINOR(dev));
|
||||
fsidv[2] = ino_t_to_u32(ino);
|
||||
break;
|
||||
|
||||
case FSID_ENCODE_DEV:
|
||||
fsidv[0] = new_encode_dev(dev);
|
||||
fsidv[1] = ino_t_to_u32(ino);
|
||||
break;
|
||||
|
||||
case FSID_UUID4_INUM:
|
||||
/* 4 byte fsid and inode number */
|
||||
up = (u32*)uuid;
|
||||
fsidv[0] = ino_t_to_u32(ino);
|
||||
fsidv[1] = up[0] ^ up[1] ^ up[2] ^ up[3];
|
||||
break;
|
||||
|
||||
case FSID_UUID8:
|
||||
/* 8 byte fsid */
|
||||
up = (u32*)uuid;
|
||||
fsidv[0] = up[0] ^ up[2];
|
||||
fsidv[1] = up[1] ^ up[3];
|
||||
break;
|
||||
|
||||
case FSID_UUID16:
|
||||
/* 16 byte fsid - NFSv3+ only */
|
||||
memcpy(fsidv, uuid, 16);
|
||||
break;
|
||||
|
||||
case FSID_UUID16_INUM:
|
||||
/* 8 byte inode and 16 byte fsid */
|
||||
*(u64*)fsidv = (u64)ino;
|
||||
memcpy(fsidv+2, uuid, 16);
|
||||
break;
|
||||
default: BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline int key_len(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case FSID_DEV: return 8;
|
||||
case FSID_NUM: return 4;
|
||||
case FSID_MAJOR_MINOR: return 12;
|
||||
case FSID_ENCODE_DEV: return 8;
|
||||
case FSID_UUID4_INUM: return 8;
|
||||
case FSID_UUID8: return 8;
|
||||
case FSID_UUID16: return 16;
|
||||
case FSID_UUID16_INUM: return 24;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Shorthand for dprintk()'s
|
||||
*/
|
||||
extern char * SVCFH_fmt(struct svc_fh *fhp);
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
__be32 fh_verify(struct svc_rqst *, struct svc_fh *, int, int);
|
||||
__be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
|
||||
__be32 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)
|
||||
{
|
||||
WARN_ON(src->fh_dentry || src->fh_locked);
|
||||
|
||||
*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;
|
||||
fhp->fh_post_blksize = BLOCK_SIZE;
|
||||
fhp->fh_post_blocks = inode->i_blocks;
|
||||
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_mutex's at once
|
||||
* so, any changes here should be reflected there.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
|
||||
{
|
||||
struct dentry *dentry = fhp->fh_dentry;
|
||||
struct inode *inode;
|
||||
|
||||
dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n",
|
||||
SVCFH_fmt(fhp), fhp->fh_locked);
|
||||
|
||||
BUG_ON(!dentry);
|
||||
|
||||
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;
|
||||
mutex_lock_nested(&inode->i_mutex, subclass);
|
||||
fill_pre_wcc(fhp);
|
||||
fhp->fh_locked = 1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fh_lock(struct svc_fh *fhp)
|
||||
{
|
||||
fh_lock_nested(fhp, I_MUTEX_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlock a file handle/inode
|
||||
*/
|
||||
static inline void
|
||||
fh_unlock(struct svc_fh *fhp)
|
||||
{
|
||||
BUG_ON(!fhp->fh_dentry);
|
||||
|
||||
if (fhp->fh_locked) {
|
||||
fill_post_wcc(fhp);
|
||||
mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex);
|
||||
fhp->fh_locked = 0;
|
||||
}
|
||||
}
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
||||
#endif /* _LINUX_NFSD_FH_H */
|
||||
309
include/linux/nfsd/state.h
Normal file
309
include/linux/nfsd/state.h
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
||||
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_perfile;
|
||||
struct list_head dl_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_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;
|
||||
};
|
||||
|
||||
#define HEXDIR_LEN 33 /* hex version of 16 byte md5 of cl_name plus '\0' */
|
||||
|
||||
/*
|
||||
* 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_openowners;
|
||||
struct list_head cl_delegations;
|
||||
struct list_head cl_lru; /* tail queue */
|
||||
struct xdr_netobj cl_name; /* id generated by client */
|
||||
char cl_recdir[HEXDIR_LEN]; /* recovery dir */
|
||||
nfs4_verifier cl_verifier; /* generated by client */
|
||||
time_t cl_time; /* time of last lease renewal */
|
||||
__be32 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 */
|
||||
u32 cl_firststate; /* recovery dir creation */
|
||||
};
|
||||
|
||||
/* 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 */
|
||||
char cr_recdir[HEXDIR_LEN]; /* recover dir */
|
||||
};
|
||||
|
||||
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 {
|
||||
__be32 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;
|
||||
struct list_head so_stateids;
|
||||
struct list_head so_perstateid; /* for lockowners only */
|
||||
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;
|
||||
/* after increment in ENCODE_SEQID_OP_TAIL, represents the next
|
||||
* sequence id expected from the 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 kref fi_ref;
|
||||
struct list_head fi_hash; /* hash by "struct inode *" */
|
||||
struct list_head fi_stateids;
|
||||
struct list_head fi_delegations;
|
||||
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
|
||||
* st_openstp: open stateid lock stateid was derived from
|
||||
*
|
||||
* XXX: open stateids and lock stateids have diverged sufficiently that
|
||||
* we should consider defining separate structs for the two cases.
|
||||
*/
|
||||
|
||||
struct nfs4_stateid {
|
||||
struct list_head st_hash;
|
||||
struct list_head st_perfile;
|
||||
struct list_head st_perstateowner;
|
||||
struct list_head st_lockowners;
|
||||
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;
|
||||
struct nfs4_stateid * st_openstp;
|
||||
};
|
||||
|
||||
/* 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 __be32 nfs4_preprocess_stateid_op(struct svc_fh *current_fh,
|
||||
stateid_t *stateid, int flags, struct file **filp);
|
||||
extern void nfs4_lock_state(void);
|
||||
extern void nfs4_unlock_state(void);
|
||||
extern int nfs4_in_grace(void);
|
||||
extern __be32 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);
|
||||
extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname);
|
||||
extern void nfsd4_init_recdir(char *recdir_name);
|
||||
extern int nfsd4_recdir_load(void);
|
||||
extern void nfsd4_shutdown_recdir(void);
|
||||
extern int nfs4_client_to_reclaim(const char *name);
|
||||
extern int nfs4_has_reclaimed_state(const char *name);
|
||||
extern void nfsd4_recdir_purge_old(void);
|
||||
extern int nfsd4_create_clid_dir(struct nfs4_client *clp);
|
||||
extern void nfsd4_remove_clid_dir(struct nfs4_client *clp);
|
||||
|
||||
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 */
|
||||
50
include/linux/nfsd/stats.h
Normal file
50
include/linux/nfsd/stats.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* linux/include/linux/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
|
||||
|
||||
#include <linux/nfs4.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 */
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
unsigned int nfs4_opcount[LAST_NFS4_OP + 1]; /* count of individual nfsv4 operations */
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/* 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 */
|
||||
124
include/linux/nfsd/syscall.h
Normal file
124
include/linux/nfsd/syscall.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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/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 */
|
||||
177
include/linux/nfsd/xdr.h
Normal file
177
include/linux/nfsd/xdr.h
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* linux/include/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;
|
||||
int vlen;
|
||||
};
|
||||
|
||||
struct nfsd_writeargs {
|
||||
svc_fh fh;
|
||||
__u32 offset;
|
||||
int len;
|
||||
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;
|
||||
__be32 * buffer;
|
||||
};
|
||||
|
||||
struct nfsd_attrstat {
|
||||
struct svc_fh fh;
|
||||
struct kstat stat;
|
||||
};
|
||||
|
||||
struct nfsd_diropres {
|
||||
struct svc_fh fh;
|
||||
struct kstat stat;
|
||||
};
|
||||
|
||||
struct nfsd_readlinkres {
|
||||
int len;
|
||||
};
|
||||
|
||||
struct nfsd_readres {
|
||||
struct svc_fh fh;
|
||||
unsigned long count;
|
||||
struct kstat stat;
|
||||
};
|
||||
|
||||
struct nfsd_readdirres {
|
||||
int count;
|
||||
|
||||
struct readdir_cd common;
|
||||
__be32 * buffer;
|
||||
int buflen;
|
||||
__be32 * 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 *, __be32 *, void *);
|
||||
int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *);
|
||||
int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd_sattrargs *);
|
||||
int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd_diropargs *);
|
||||
int nfssvc_decode_readargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd_readargs *);
|
||||
int nfssvc_decode_writeargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd_writeargs *);
|
||||
int nfssvc_decode_createargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd_createargs *);
|
||||
int nfssvc_decode_renameargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd_renameargs *);
|
||||
int nfssvc_decode_readlinkargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd_readlinkargs *);
|
||||
int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd_linkargs *);
|
||||
int nfssvc_decode_symlinkargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd_symlinkargs *);
|
||||
int nfssvc_decode_readdirargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd_readdirargs *);
|
||||
int nfssvc_encode_void(struct svc_rqst *, __be32 *, void *);
|
||||
int nfssvc_encode_attrstat(struct svc_rqst *, __be32 *, struct nfsd_attrstat *);
|
||||
int nfssvc_encode_diropres(struct svc_rqst *, __be32 *, struct nfsd_diropres *);
|
||||
int nfssvc_encode_readlinkres(struct svc_rqst *, __be32 *, struct nfsd_readlinkres *);
|
||||
int nfssvc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd_readres *);
|
||||
int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *);
|
||||
int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *);
|
||||
|
||||
int nfssvc_encode_entry(void *, const char *name,
|
||||
int namlen, loff_t offset, u64 ino, unsigned int);
|
||||
|
||||
int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *);
|
||||
|
||||
/* Helper functions for NFSv2 ACL code */
|
||||
__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp);
|
||||
__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp);
|
||||
|
||||
#endif /* LINUX_NFSD_H */
|
||||
346
include/linux/nfsd/xdr3.h
Normal file
346
include/linux/nfsd/xdr3.h
Normal file
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* 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;
|
||||
int vlen;
|
||||
};
|
||||
|
||||
struct nfsd3_writeargs {
|
||||
svc_fh fh;
|
||||
__u64 offset;
|
||||
__u32 count;
|
||||
int stable;
|
||||
__u32 len;
|
||||
int vlen;
|
||||
};
|
||||
|
||||
struct nfsd3_createargs {
|
||||
struct svc_fh fh;
|
||||
char * name;
|
||||
int len;
|
||||
int createmode;
|
||||
struct iattr attrs;
|
||||
__be32 * 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;
|
||||
__be32 * verf;
|
||||
__be32 * buffer;
|
||||
};
|
||||
|
||||
struct nfsd3_commitargs {
|
||||
struct svc_fh fh;
|
||||
__u64 offset;
|
||||
__u32 count;
|
||||
};
|
||||
|
||||
struct nfsd3_getaclargs {
|
||||
struct svc_fh fh;
|
||||
int mask;
|
||||
};
|
||||
|
||||
struct posix_acl;
|
||||
struct nfsd3_setaclargs {
|
||||
struct svc_fh fh;
|
||||
int mask;
|
||||
struct posix_acl *acl_access;
|
||||
struct posix_acl *acl_default;
|
||||
};
|
||||
|
||||
struct nfsd3_attrstat {
|
||||
__be32 status;
|
||||
struct svc_fh fh;
|
||||
struct kstat stat;
|
||||
};
|
||||
|
||||
/* LOOKUP, CREATE, MKDIR, SYMLINK, MKNOD */
|
||||
struct nfsd3_diropres {
|
||||
__be32 status;
|
||||
struct svc_fh dirfh;
|
||||
struct svc_fh fh;
|
||||
};
|
||||
|
||||
struct nfsd3_accessres {
|
||||
__be32 status;
|
||||
struct svc_fh fh;
|
||||
__u32 access;
|
||||
};
|
||||
|
||||
struct nfsd3_readlinkres {
|
||||
__be32 status;
|
||||
struct svc_fh fh;
|
||||
__u32 len;
|
||||
};
|
||||
|
||||
struct nfsd3_readres {
|
||||
__be32 status;
|
||||
struct svc_fh fh;
|
||||
unsigned long count;
|
||||
int eof;
|
||||
};
|
||||
|
||||
struct nfsd3_writeres {
|
||||
__be32 status;
|
||||
struct svc_fh fh;
|
||||
unsigned long count;
|
||||
int committed;
|
||||
};
|
||||
|
||||
struct nfsd3_renameres {
|
||||
__be32 status;
|
||||
struct svc_fh ffh;
|
||||
struct svc_fh tfh;
|
||||
};
|
||||
|
||||
struct nfsd3_linkres {
|
||||
__be32 status;
|
||||
struct svc_fh tfh;
|
||||
struct svc_fh fh;
|
||||
};
|
||||
|
||||
struct nfsd3_readdirres {
|
||||
__be32 status;
|
||||
struct svc_fh fh;
|
||||
int count;
|
||||
__be32 verf[2];
|
||||
|
||||
struct readdir_cd common;
|
||||
__be32 * buffer;
|
||||
int buflen;
|
||||
__be32 * offset;
|
||||
__be32 * offset1;
|
||||
struct svc_rqst * rqstp;
|
||||
|
||||
};
|
||||
|
||||
struct nfsd3_fsstatres {
|
||||
__be32 status;
|
||||
struct kstatfs stats;
|
||||
__u32 invarsec;
|
||||
};
|
||||
|
||||
struct nfsd3_fsinfores {
|
||||
__be32 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 {
|
||||
__be32 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 {
|
||||
__be32 status;
|
||||
struct svc_fh fh;
|
||||
};
|
||||
|
||||
struct nfsd3_getaclres {
|
||||
__be32 status;
|
||||
struct svc_fh fh;
|
||||
int mask;
|
||||
struct posix_acl *acl_access;
|
||||
struct posix_acl *acl_default;
|
||||
};
|
||||
|
||||
/* 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;
|
||||
struct nfsd3_getaclres getaclres;
|
||||
};
|
||||
|
||||
#define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore)
|
||||
|
||||
int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *);
|
||||
int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_sattrargs *);
|
||||
int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_diropargs *);
|
||||
int nfs3svc_decode_accessargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_accessargs *);
|
||||
int nfs3svc_decode_readargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_readargs *);
|
||||
int nfs3svc_decode_writeargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_writeargs *);
|
||||
int nfs3svc_decode_createargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_createargs *);
|
||||
int nfs3svc_decode_mkdirargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_createargs *);
|
||||
int nfs3svc_decode_mknodargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_mknodargs *);
|
||||
int nfs3svc_decode_renameargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_renameargs *);
|
||||
int nfs3svc_decode_readlinkargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_readlinkargs *);
|
||||
int nfs3svc_decode_linkargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_linkargs *);
|
||||
int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_symlinkargs *);
|
||||
int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_readdirargs *);
|
||||
int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_readdirargs *);
|
||||
int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_commitargs *);
|
||||
int nfs3svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
|
||||
int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_attrstat *);
|
||||
int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_attrstat *);
|
||||
int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_diropres *);
|
||||
int nfs3svc_encode_accessres(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_accessres *);
|
||||
int nfs3svc_encode_readlinkres(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_readlinkres *);
|
||||
int nfs3svc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd3_readres *);
|
||||
int nfs3svc_encode_writeres(struct svc_rqst *, __be32 *, struct nfsd3_writeres *);
|
||||
int nfs3svc_encode_createres(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_diropres *);
|
||||
int nfs3svc_encode_renameres(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_renameres *);
|
||||
int nfs3svc_encode_linkres(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_linkres *);
|
||||
int nfs3svc_encode_readdirres(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_readdirres *);
|
||||
int nfs3svc_encode_fsstatres(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_fsstatres *);
|
||||
int nfs3svc_encode_fsinfores(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_fsinfores *);
|
||||
int nfs3svc_encode_pathconfres(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_pathconfres *);
|
||||
int nfs3svc_encode_commitres(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_commitres *);
|
||||
|
||||
int nfs3svc_release_fhandle(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_attrstat *);
|
||||
int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *,
|
||||
struct nfsd3_fhandle_pair *);
|
||||
int nfs3svc_encode_entry(void *, const char *name,
|
||||
int namlen, loff_t offset, u64 ino,
|
||||
unsigned int);
|
||||
int nfs3svc_encode_entry_plus(void *, const char *name,
|
||||
int namlen, loff_t offset, u64 ino,
|
||||
unsigned int);
|
||||
/* Helper functions for NFSv3 ACL code */
|
||||
__be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p,
|
||||
struct svc_fh *fhp);
|
||||
__be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp);
|
||||
|
||||
|
||||
#endif /* _LINUX_NFSD_XDR3_H */
|
||||
478
include/linux/nfsd/xdr4.h
Normal file
478
include/linux/nfsd/xdr4.h
Normal file
@@ -0,0 +1,478 @@
|
||||
/*
|
||||
* 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_compound_state {
|
||||
struct svc_fh current_fh;
|
||||
struct svc_fh save_fh;
|
||||
struct nfs4_stateowner *replay_owner;
|
||||
};
|
||||
|
||||
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;
|
||||
/* The lk_replay_owner is the open owner in the open_to_lock_owner
|
||||
* case and the lock owner otherwise: */
|
||||
struct nfs4_stateowner *lk_replay_owner;
|
||||
};
|
||||
#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 */
|
||||
u32 op_recall; /* recall */
|
||||
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 */
|
||||
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;
|
||||
__be32 * buffer;
|
||||
int buflen;
|
||||
__be32 * 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 */
|
||||
int wr_vlen;
|
||||
|
||||
u32 wr_bytes_written; /* response */
|
||||
u32 wr_how_written; /* response */
|
||||
nfs4_verifier wr_verifier; /* response */
|
||||
};
|
||||
|
||||
struct nfsd4_op {
|
||||
int opnum;
|
||||
__be32 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 */
|
||||
__be32 * p;
|
||||
__be32 * end;
|
||||
struct page ** pagelist;
|
||||
int pagelen;
|
||||
__be32 tmp[8];
|
||||
__be32 * 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 */
|
||||
__be32 * p;
|
||||
__be32 * end;
|
||||
struct xdr_buf * xbuf;
|
||||
struct svc_rqst * rqstp;
|
||||
|
||||
u32 taglen;
|
||||
char * tag;
|
||||
u32 opcnt;
|
||||
__be32 * 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 *, __be32 *, void *);
|
||||
int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *,
|
||||
struct nfsd4_compoundargs *);
|
||||
int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *,
|
||||
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);
|
||||
__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
|
||||
struct dentry *dentry, __be32 *buffer, int *countp,
|
||||
u32 *bmval, struct svc_rqst *);
|
||||
extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *,
|
||||
struct nfsd4_setclientid *setclid);
|
||||
extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *,
|
||||
struct nfsd4_setclientid_confirm *setclientid_confirm);
|
||||
extern __be32 nfsd4_process_open1(struct nfsd4_open *open);
|
||||
extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
|
||||
struct svc_fh *current_fh, struct nfsd4_open *open);
|
||||
extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc);
|
||||
extern __be32 nfsd4_close(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *,
|
||||
struct nfsd4_close *close);
|
||||
extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *,
|
||||
struct nfsd4_open_downgrade *od);
|
||||
extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
|
||||
struct nfsd4_lock *lock);
|
||||
extern __be32 nfsd4_lockt(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *,
|
||||
struct nfsd4_lockt *lockt);
|
||||
extern __be32 nfsd4_locku(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *,
|
||||
struct nfsd4_locku *locku);
|
||||
extern __be32
|
||||
nfsd4_release_lockowner(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *,
|
||||
struct nfsd4_release_lockowner *rlockowner);
|
||||
extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *);
|
||||
extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr);
|
||||
extern __be32 nfsd4_renew(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *, clientid_t *clid);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
Reference in New Issue
Block a user