Merge rsync://client.linux-nfs.org/pub/linux/nfs-2.6
This commit is contained in:
commit
9092131f7e
68 changed files with 4142 additions and 1011 deletions
|
@ -674,6 +674,7 @@ struct file_lock {
|
|||
struct lock_manager_operations *fl_lmops; /* Callbacks for lockmanagers */
|
||||
union {
|
||||
struct nfs_lock_info nfs_fl;
|
||||
struct nfs4_lock_info nfs4_fl;
|
||||
} fl_u;
|
||||
};
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ struct nlm_lockowner {
|
|||
uint32_t pid;
|
||||
};
|
||||
|
||||
struct nlm_wait;
|
||||
|
||||
/*
|
||||
* Memory chunk for NLM client RPC request.
|
||||
*/
|
||||
|
@ -81,6 +83,7 @@ struct nlm_rqst {
|
|||
struct nlm_host * a_host; /* host handle */
|
||||
struct nlm_args a_args; /* arguments */
|
||||
struct nlm_res a_res; /* result */
|
||||
struct nlm_wait * a_block;
|
||||
char a_owner[NLMCLNT_OHSIZE];
|
||||
};
|
||||
|
||||
|
@ -142,7 +145,9 @@ extern unsigned long nlmsvc_timeout;
|
|||
* Lockd client functions
|
||||
*/
|
||||
struct nlm_rqst * nlmclnt_alloc_call(void);
|
||||
int nlmclnt_block(struct nlm_host *, struct file_lock *, u32 *);
|
||||
int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl);
|
||||
void nlmclnt_finish_block(struct nlm_rqst *req);
|
||||
long nlmclnt_block(struct nlm_rqst *req, long timeout);
|
||||
int nlmclnt_cancel(struct nlm_host *, struct file_lock *);
|
||||
u32 nlmclnt_grant(struct nlm_lock *);
|
||||
void nlmclnt_recovery(struct nlm_host *, u32);
|
||||
|
|
|
@ -382,6 +382,8 @@ enum {
|
|||
NFSPROC4_CLNT_READDIR,
|
||||
NFSPROC4_CLNT_SERVER_CAPS,
|
||||
NFSPROC4_CLNT_DELEGRETURN,
|
||||
NFSPROC4_CLNT_GETACL,
|
||||
NFSPROC4_CLNT_SETACL,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <linux/pagemap.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/uio.h>
|
||||
|
||||
#include <linux/nfs_fs_sb.h>
|
||||
|
||||
|
@ -29,7 +28,6 @@
|
|||
#include <linux/nfs4.h>
|
||||
#include <linux/nfs_xdr.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mempool.h>
|
||||
|
||||
/*
|
||||
|
@ -43,13 +41,6 @@
|
|||
#define NFS_MAX_FILE_IO_BUFFER_SIZE 32768
|
||||
#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096
|
||||
|
||||
/*
|
||||
* The upper limit on timeouts for the exponential backoff algorithm.
|
||||
*/
|
||||
#define NFS_WRITEBACK_DELAY (5*HZ)
|
||||
#define NFS_WRITEBACK_LOCKDELAY (60*HZ)
|
||||
#define NFS_COMMIT_DELAY (5*HZ)
|
||||
|
||||
/*
|
||||
* superblock magic number for NFS
|
||||
*/
|
||||
|
@ -60,9 +51,6 @@
|
|||
*/
|
||||
#define NFS_RPC_SWAPFLAGS (RPC_TASK_SWAPPER|RPC_TASK_ROOTCREDS)
|
||||
|
||||
#define NFS_RW_SYNC 0x0001 /* O_SYNC handling */
|
||||
#define NFS_RW_SWAP 0x0002 /* This is a swap request */
|
||||
|
||||
/*
|
||||
* When flushing a cluster of dirty pages, there can be different
|
||||
* strategies:
|
||||
|
@ -96,7 +84,8 @@ struct nfs_open_context {
|
|||
int error;
|
||||
|
||||
struct list_head list;
|
||||
wait_queue_head_t waitq;
|
||||
|
||||
__u64 dir_cookie;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -104,6 +93,8 @@ struct nfs_open_context {
|
|||
*/
|
||||
struct nfs_delegation;
|
||||
|
||||
struct posix_acl;
|
||||
|
||||
/*
|
||||
* nfs fs inode data in memory
|
||||
*/
|
||||
|
@ -140,7 +131,6 @@ struct nfs_inode {
|
|||
*
|
||||
* mtime != read_cache_mtime
|
||||
*/
|
||||
unsigned long readdir_timestamp;
|
||||
unsigned long read_cache_jiffies;
|
||||
unsigned long attrtimeo;
|
||||
unsigned long attrtimeo_timestamp;
|
||||
|
@ -158,6 +148,10 @@ struct nfs_inode {
|
|||
atomic_t data_updates;
|
||||
|
||||
struct nfs_access_entry cache_access;
|
||||
#ifdef CONFIG_NFS_V3_ACL
|
||||
struct posix_acl *acl_access;
|
||||
struct posix_acl *acl_default;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the cookie verifier used for NFSv3 readdir
|
||||
|
@ -183,13 +177,13 @@ struct nfs_inode {
|
|||
wait_queue_head_t nfs_i_wait;
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
struct nfs4_cached_acl *nfs4_acl;
|
||||
/* NFSv4 state */
|
||||
struct list_head open_states;
|
||||
struct nfs_delegation *delegation;
|
||||
int delegation_state;
|
||||
struct rw_semaphore rwsem;
|
||||
#endif /* CONFIG_NFS_V4*/
|
||||
|
||||
struct inode vfs_inode;
|
||||
};
|
||||
|
||||
|
@ -203,6 +197,8 @@ struct nfs_inode {
|
|||
#define NFS_INO_INVALID_DATA 0x0010 /* cached data is invalid */
|
||||
#define NFS_INO_INVALID_ATIME 0x0020 /* cached atime is invalid */
|
||||
#define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */
|
||||
#define NFS_INO_INVALID_ACL 0x0080 /* cached acls are invalid */
|
||||
#define NFS_INO_REVAL_PAGECACHE 0x1000 /* must revalidate pagecache */
|
||||
|
||||
static inline struct nfs_inode *NFS_I(struct inode *inode)
|
||||
{
|
||||
|
@ -294,12 +290,12 @@ extern int nfs_release(struct inode *, struct file *);
|
|||
extern int nfs_attribute_timeout(struct inode *inode);
|
||||
extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
|
||||
extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
|
||||
extern void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
|
||||
extern int nfs_setattr(struct dentry *, struct iattr *);
|
||||
extern void nfs_begin_attr_update(struct inode *);
|
||||
extern void nfs_end_attr_update(struct inode *);
|
||||
extern void nfs_begin_data_update(struct inode *);
|
||||
extern void nfs_end_data_update(struct inode *);
|
||||
extern void nfs_end_data_update_defer(struct inode *);
|
||||
extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred);
|
||||
extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
|
||||
extern void put_nfs_open_context(struct nfs_open_context *ctx);
|
||||
|
@ -314,6 +310,9 @@ extern u32 root_nfs_parse_addr(char *name); /*__init*/
|
|||
* linux/fs/nfs/file.c
|
||||
*/
|
||||
extern struct inode_operations nfs_file_inode_operations;
|
||||
#ifdef CONFIG_NFS_V3
|
||||
extern struct inode_operations nfs3_file_inode_operations;
|
||||
#endif /* CONFIG_NFS_V3 */
|
||||
extern struct file_operations nfs_file_operations;
|
||||
extern struct address_space_operations nfs_file_aops;
|
||||
|
||||
|
@ -328,6 +327,22 @@ static inline struct rpc_cred *nfs_file_cred(struct file *file)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* linux/fs/nfs/xattr.c
|
||||
*/
|
||||
#ifdef CONFIG_NFS_V3_ACL
|
||||
extern ssize_t nfs3_listxattr(struct dentry *, char *, size_t);
|
||||
extern ssize_t nfs3_getxattr(struct dentry *, const char *, void *, size_t);
|
||||
extern int nfs3_setxattr(struct dentry *, const char *,
|
||||
const void *, size_t, int);
|
||||
extern int nfs3_removexattr (struct dentry *, const char *name);
|
||||
#else
|
||||
# define nfs3_listxattr NULL
|
||||
# define nfs3_getxattr NULL
|
||||
# define nfs3_setxattr NULL
|
||||
# define nfs3_removexattr NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* linux/fs/nfs/direct.c
|
||||
*/
|
||||
|
@ -342,6 +357,9 @@ extern ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf,
|
|||
* linux/fs/nfs/dir.c
|
||||
*/
|
||||
extern struct inode_operations nfs_dir_inode_operations;
|
||||
#ifdef CONFIG_NFS_V3
|
||||
extern struct inode_operations nfs3_dir_inode_operations;
|
||||
#endif /* CONFIG_NFS_V3 */
|
||||
extern struct file_operations nfs_dir_operations;
|
||||
extern struct dentry_operations nfs_dentry_operations;
|
||||
|
||||
|
@ -377,10 +395,10 @@ extern void nfs_commit_done(struct rpc_task *);
|
|||
*/
|
||||
extern int nfs_sync_inode(struct inode *, unsigned long, unsigned int, int);
|
||||
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
|
||||
extern int nfs_commit_inode(struct inode *, unsigned long, unsigned int, int);
|
||||
extern int nfs_commit_inode(struct inode *, int);
|
||||
#else
|
||||
static inline int
|
||||
nfs_commit_inode(struct inode *inode, unsigned long idx_start, unsigned int npages, int how)
|
||||
nfs_commit_inode(struct inode *inode, int how)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -434,11 +452,6 @@ static inline void nfs_writedata_free(struct nfs_write_data *p)
|
|||
mempool_free(p, nfs_wdata_mempool);
|
||||
}
|
||||
|
||||
/* Hack for future NFS swap support */
|
||||
#ifndef IS_SWAPFILE
|
||||
# define IS_SWAPFILE(inode) (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* linux/fs/nfs/read.c
|
||||
*/
|
||||
|
@ -467,6 +480,29 @@ static inline void nfs_readdata_free(struct nfs_read_data *p)
|
|||
|
||||
extern void nfs_readdata_release(struct rpc_task *task);
|
||||
|
||||
/*
|
||||
* linux/fs/nfs3proc.c
|
||||
*/
|
||||
#ifdef CONFIG_NFS_V3_ACL
|
||||
extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type);
|
||||
extern int nfs3_proc_setacl(struct inode *inode, int type,
|
||||
struct posix_acl *acl);
|
||||
extern int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
|
||||
mode_t mode);
|
||||
extern void nfs3_forget_cached_acls(struct inode *inode);
|
||||
#else
|
||||
static inline int nfs3_proc_set_default_acl(struct inode *dir,
|
||||
struct inode *inode,
|
||||
mode_t mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void nfs3_forget_cached_acls(struct inode *inode)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_NFS_V3_ACL */
|
||||
|
||||
/*
|
||||
* linux/fs/mount_clnt.c
|
||||
* (Used only by nfsroot module)
|
||||
|
@ -515,230 +551,6 @@ extern void * nfs_root_data(void);
|
|||
|
||||
#define NFS_JUKEBOX_RETRY_TIME (5 * HZ)
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
|
||||
struct idmap;
|
||||
|
||||
/*
|
||||
* In a seqid-mutating op, this macro controls which error return
|
||||
* values trigger incrementation of the seqid.
|
||||
*
|
||||
* from rfc 3010:
|
||||
* The client MUST monotonically increment the sequence number for the
|
||||
* CLOSE, LOCK, LOCKU, OPEN, OPEN_CONFIRM, and OPEN_DOWNGRADE
|
||||
* operations. This is true even in the event that the previous
|
||||
* operation that used the sequence number received an error. The only
|
||||
* exception to this rule is if the previous operation received one of
|
||||
* the following errors: NFSERR_STALE_CLIENTID, NFSERR_STALE_STATEID,
|
||||
* NFSERR_BAD_STATEID, NFSERR_BAD_SEQID, NFSERR_BADXDR,
|
||||
* NFSERR_RESOURCE, NFSERR_NOFILEHANDLE.
|
||||
*
|
||||
*/
|
||||
#define seqid_mutating_err(err) \
|
||||
(((err) != NFSERR_STALE_CLIENTID) && \
|
||||
((err) != NFSERR_STALE_STATEID) && \
|
||||
((err) != NFSERR_BAD_STATEID) && \
|
||||
((err) != NFSERR_BAD_SEQID) && \
|
||||
((err) != NFSERR_BAD_XDR) && \
|
||||
((err) != NFSERR_RESOURCE) && \
|
||||
((err) != NFSERR_NOFILEHANDLE))
|
||||
|
||||
enum nfs4_client_state {
|
||||
NFS4CLNT_OK = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
* The nfs4_client identifies our client state to the server.
|
||||
*/
|
||||
struct nfs4_client {
|
||||
struct list_head cl_servers; /* Global list of servers */
|
||||
struct in_addr cl_addr; /* Server identifier */
|
||||
u64 cl_clientid; /* constant */
|
||||
nfs4_verifier cl_confirm;
|
||||
unsigned long cl_state;
|
||||
|
||||
u32 cl_lockowner_id;
|
||||
|
||||
/*
|
||||
* The following rwsem ensures exclusive access to the server
|
||||
* while we recover the state following a lease expiration.
|
||||
*/
|
||||
struct rw_semaphore cl_sem;
|
||||
|
||||
struct list_head cl_delegations;
|
||||
struct list_head cl_state_owners;
|
||||
struct list_head cl_unused;
|
||||
int cl_nunused;
|
||||
spinlock_t cl_lock;
|
||||
atomic_t cl_count;
|
||||
|
||||
struct rpc_clnt * cl_rpcclient;
|
||||
struct rpc_cred * cl_cred;
|
||||
|
||||
struct list_head cl_superblocks; /* List of nfs_server structs */
|
||||
|
||||
unsigned long cl_lease_time;
|
||||
unsigned long cl_last_renewal;
|
||||
struct work_struct cl_renewd;
|
||||
struct work_struct cl_recoverd;
|
||||
|
||||
wait_queue_head_t cl_waitq;
|
||||
struct rpc_wait_queue cl_rpcwaitq;
|
||||
|
||||
/* used for the setclientid verifier */
|
||||
struct timespec cl_boot_time;
|
||||
|
||||
/* idmapper */
|
||||
struct idmap * cl_idmap;
|
||||
|
||||
/* Our own IP address, as a null-terminated string.
|
||||
* This is used to generate the clientid, and the callback address.
|
||||
*/
|
||||
char cl_ipaddr[16];
|
||||
unsigned char cl_id_uniquifier;
|
||||
};
|
||||
|
||||
/*
|
||||
* NFS4 state_owners and lock_owners are simply labels for ordered
|
||||
* sequences of RPC calls. Their sole purpose is to provide once-only
|
||||
* semantics by allowing the server to identify replayed requests.
|
||||
*
|
||||
* The ->so_sema is held during all state_owner seqid-mutating operations:
|
||||
* OPEN, OPEN_DOWNGRADE, and CLOSE. Its purpose is to properly serialize
|
||||
* so_seqid.
|
||||
*/
|
||||
struct nfs4_state_owner {
|
||||
struct list_head so_list; /* per-clientid list of state_owners */
|
||||
struct nfs4_client *so_client;
|
||||
u32 so_id; /* 32-bit identifier, unique */
|
||||
struct semaphore so_sema;
|
||||
u32 so_seqid; /* protected by so_sema */
|
||||
atomic_t so_count;
|
||||
|
||||
struct rpc_cred *so_cred; /* Associated cred */
|
||||
struct list_head so_states;
|
||||
struct list_head so_delegations;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct nfs4_state maintains the client-side state for a given
|
||||
* (state_owner,inode) tuple (OPEN) or state_owner (LOCK).
|
||||
*
|
||||
* OPEN:
|
||||
* In order to know when to OPEN_DOWNGRADE or CLOSE the state on the server,
|
||||
* we need to know how many files are open for reading or writing on a
|
||||
* given inode. This information too is stored here.
|
||||
*
|
||||
* LOCK: one nfs4_state (LOCK) to hold the lock stateid nfs4_state(OPEN)
|
||||
*/
|
||||
|
||||
struct nfs4_lock_state {
|
||||
struct list_head ls_locks; /* Other lock stateids */
|
||||
fl_owner_t ls_owner; /* POSIX lock owner */
|
||||
#define NFS_LOCK_INITIALIZED 1
|
||||
int ls_flags;
|
||||
u32 ls_seqid;
|
||||
u32 ls_id;
|
||||
nfs4_stateid ls_stateid;
|
||||
atomic_t ls_count;
|
||||
};
|
||||
|
||||
/* bits for nfs4_state->flags */
|
||||
enum {
|
||||
LK_STATE_IN_USE,
|
||||
NFS_DELEGATED_STATE,
|
||||
};
|
||||
|
||||
struct nfs4_state {
|
||||
struct list_head open_states; /* List of states for the same state_owner */
|
||||
struct list_head inode_states; /* List of states for the same inode */
|
||||
struct list_head lock_states; /* List of subservient lock stateids */
|
||||
|
||||
struct nfs4_state_owner *owner; /* Pointer to the open owner */
|
||||
struct inode *inode; /* Pointer to the inode */
|
||||
|
||||
unsigned long flags; /* Do we hold any locks? */
|
||||
struct semaphore lock_sema; /* Serializes file locking operations */
|
||||
rwlock_t state_lock; /* Protects the lock_states list */
|
||||
|
||||
nfs4_stateid stateid;
|
||||
|
||||
unsigned int nreaders;
|
||||
unsigned int nwriters;
|
||||
int state; /* State on the server (R,W, or RW) */
|
||||
atomic_t count;
|
||||
};
|
||||
|
||||
|
||||
struct nfs4_exception {
|
||||
long timeout;
|
||||
int retry;
|
||||
};
|
||||
|
||||
struct nfs4_state_recovery_ops {
|
||||
int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
|
||||
int (*recover_lock)(struct nfs4_state *, struct file_lock *);
|
||||
};
|
||||
|
||||
extern struct dentry_operations nfs4_dentry_operations;
|
||||
extern struct inode_operations nfs4_dir_inode_operations;
|
||||
|
||||
/* nfs4proc.c */
|
||||
extern int nfs4_map_errors(int err);
|
||||
extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
|
||||
extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
|
||||
extern int nfs4_proc_async_renew(struct nfs4_client *);
|
||||
extern int nfs4_proc_renew(struct nfs4_client *);
|
||||
extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
|
||||
extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
|
||||
extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
|
||||
|
||||
extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
|
||||
extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
|
||||
|
||||
/* nfs4renewd.c */
|
||||
extern void nfs4_schedule_state_renewal(struct nfs4_client *);
|
||||
extern void nfs4_renewd_prepare_shutdown(struct nfs_server *);
|
||||
extern void nfs4_kill_renewd(struct nfs4_client *);
|
||||
|
||||
/* nfs4state.c */
|
||||
extern void init_nfsv4_state(struct nfs_server *);
|
||||
extern void destroy_nfsv4_state(struct nfs_server *);
|
||||
extern struct nfs4_client *nfs4_get_client(struct in_addr *);
|
||||
extern void nfs4_put_client(struct nfs4_client *clp);
|
||||
extern int nfs4_init_client(struct nfs4_client *clp);
|
||||
extern struct nfs4_client *nfs4_find_client(struct in_addr *);
|
||||
extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
|
||||
|
||||
extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
|
||||
extern void nfs4_put_state_owner(struct nfs4_state_owner *);
|
||||
extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
|
||||
extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
|
||||
extern void nfs4_put_open_state(struct nfs4_state *);
|
||||
extern void nfs4_close_state(struct nfs4_state *, mode_t);
|
||||
extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
|
||||
extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
|
||||
extern void nfs4_schedule_state_recovery(struct nfs4_client *);
|
||||
extern struct nfs4_lock_state *nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t);
|
||||
extern struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t);
|
||||
extern void nfs4_put_lock_state(struct nfs4_lock_state *state);
|
||||
extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
|
||||
extern void nfs4_notify_setlk(struct nfs4_state *, struct file_lock *, struct nfs4_lock_state *);
|
||||
extern void nfs4_notify_unlck(struct nfs4_state *, struct file_lock *, struct nfs4_lock_state *);
|
||||
extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
|
||||
|
||||
|
||||
|
||||
struct nfs4_mount_data;
|
||||
#else
|
||||
#define init_nfsv4_state(server) do { } while (0)
|
||||
#define destroy_nfsv4_state(server) do { } while (0)
|
||||
#define nfs4_put_state_owner(inode, owner) do { } while (0)
|
||||
#define nfs4_put_open_state(state) do { } while (0)
|
||||
#define nfs4_close_state(a, b) do { } while (0)
|
||||
#define nfs4_renewd_prepare_shutdown(server) do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/*
|
||||
|
|
|
@ -16,6 +16,11 @@ struct nfs_lock_info {
|
|||
struct nlm_lockowner *owner;
|
||||
};
|
||||
|
||||
struct nfs4_lock_state;
|
||||
struct nfs4_lock_info {
|
||||
struct nfs4_lock_state *owner;
|
||||
};
|
||||
|
||||
/*
|
||||
* Lock flag values
|
||||
*/
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
struct nfs_server {
|
||||
struct rpc_clnt * client; /* RPC client handle */
|
||||
struct rpc_clnt * client_sys; /* 2nd handle for FSINFO */
|
||||
struct rpc_clnt * client_acl; /* ACL RPC client handle */
|
||||
struct nfs_rpc_ops * rpc_ops; /* NFS protocol vector */
|
||||
struct backing_dev_info backing_dev_info;
|
||||
int flags; /* various flags */
|
||||
|
|
|
@ -58,6 +58,7 @@ struct nfs_mount_data {
|
|||
#define NFS_MOUNT_KERBEROS 0x0100 /* 3 */
|
||||
#define NFS_MOUNT_NONLM 0x0200 /* 3 */
|
||||
#define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */
|
||||
#define NFS_MOUNT_NOACL 0x0800 /* 4 */
|
||||
#define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */
|
||||
#define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */
|
||||
#define NFS_MOUNT_FLAGMASK 0xFFFF
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
|
||||
#include <asm/atomic.h>
|
||||
|
||||
/*
|
||||
* Valid flags for the radix tree
|
||||
*/
|
||||
#define NFS_PAGE_TAG_DIRTY 0
|
||||
#define NFS_PAGE_TAG_WRITEBACK 1
|
||||
|
||||
/*
|
||||
* Valid flags for a dirty buffer
|
||||
*/
|
||||
|
@ -26,6 +32,7 @@
|
|||
#define PG_NEED_COMMIT 1
|
||||
#define PG_NEED_RESCHED 2
|
||||
|
||||
struct nfs_inode;
|
||||
struct nfs_page {
|
||||
struct list_head wb_list, /* Defines state of page: */
|
||||
*wb_list_head; /* read/write/commit */
|
||||
|
@ -54,14 +61,17 @@ extern void nfs_clear_request(struct nfs_page *req);
|
|||
extern void nfs_release_request(struct nfs_page *req);
|
||||
|
||||
|
||||
extern void nfs_list_add_request(struct nfs_page *, struct list_head *);
|
||||
|
||||
extern int nfs_scan_lock_dirty(struct nfs_inode *nfsi, struct list_head *dst,
|
||||
unsigned long idx_start, unsigned int npages);
|
||||
extern int nfs_scan_list(struct list_head *, struct list_head *,
|
||||
unsigned long, unsigned int);
|
||||
extern int nfs_coalesce_requests(struct list_head *, struct list_head *,
|
||||
unsigned int);
|
||||
extern int nfs_wait_on_request(struct nfs_page *);
|
||||
extern void nfs_unlock_request(struct nfs_page *req);
|
||||
extern int nfs_set_page_writeback_locked(struct nfs_page *req);
|
||||
extern void nfs_clear_page_writeback(struct nfs_page *req);
|
||||
|
||||
|
||||
/*
|
||||
* Lock the page of an asynchronous request without incrementing the wb_count
|
||||
|
@ -86,6 +96,18 @@ nfs_lock_request(struct nfs_page *req)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs_list_add_request - Insert a request into a list
|
||||
* @req: request
|
||||
* @head: head of list into which to insert the request.
|
||||
*/
|
||||
static inline void
|
||||
nfs_list_add_request(struct nfs_page *req, struct list_head *head)
|
||||
{
|
||||
list_add_tail(&req->wb_list, head);
|
||||
req->wb_list_head = head;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nfs_list_remove_request - Remove a request from its wb_list
|
||||
|
@ -96,10 +118,6 @@ nfs_list_remove_request(struct nfs_page *req)
|
|||
{
|
||||
if (list_empty(&req->wb_list))
|
||||
return;
|
||||
if (!NFS_WBACK_BUSY(req)) {
|
||||
printk(KERN_ERR "NFS: unlocked request attempted removed from list!\n");
|
||||
BUG();
|
||||
}
|
||||
list_del_init(&req->wb_list);
|
||||
req->wb_list_head = NULL;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _LINUX_NFS_XDR_H
|
||||
|
||||
#include <linux/sunrpc/xprt.h>
|
||||
#include <linux/nfsacl.h>
|
||||
|
||||
struct nfs4_fsid {
|
||||
__u64 major;
|
||||
|
@ -326,6 +327,20 @@ struct nfs_setattrargs {
|
|||
const u32 * bitmask;
|
||||
};
|
||||
|
||||
struct nfs_setaclargs {
|
||||
struct nfs_fh * fh;
|
||||
size_t acl_len;
|
||||
unsigned int acl_pgbase;
|
||||
struct page ** acl_pages;
|
||||
};
|
||||
|
||||
struct nfs_getaclargs {
|
||||
struct nfs_fh * fh;
|
||||
size_t acl_len;
|
||||
unsigned int acl_pgbase;
|
||||
struct page ** acl_pages;
|
||||
};
|
||||
|
||||
struct nfs_setattrres {
|
||||
struct nfs_fattr * fattr;
|
||||
const struct nfs_server * server;
|
||||
|
@ -354,6 +369,20 @@ struct nfs_readdirargs {
|
|||
struct page ** pages;
|
||||
};
|
||||
|
||||
struct nfs3_getaclargs {
|
||||
struct nfs_fh * fh;
|
||||
int mask;
|
||||
struct page ** pages;
|
||||
};
|
||||
|
||||
struct nfs3_setaclargs {
|
||||
struct inode * inode;
|
||||
int mask;
|
||||
struct posix_acl * acl_access;
|
||||
struct posix_acl * acl_default;
|
||||
struct page ** pages;
|
||||
};
|
||||
|
||||
struct nfs_diropok {
|
||||
struct nfs_fh * fh;
|
||||
struct nfs_fattr * fattr;
|
||||
|
@ -477,6 +506,15 @@ struct nfs3_readdirres {
|
|||
int plus;
|
||||
};
|
||||
|
||||
struct nfs3_getaclres {
|
||||
struct nfs_fattr * fattr;
|
||||
int mask;
|
||||
unsigned int acl_access_count;
|
||||
unsigned int acl_default_count;
|
||||
struct posix_acl * acl_access;
|
||||
struct posix_acl * acl_default;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
|
||||
typedef u64 clientid4;
|
||||
|
@ -667,6 +705,7 @@ struct nfs_rpc_ops {
|
|||
int version; /* Protocol version */
|
||||
struct dentry_operations *dentry_ops;
|
||||
struct inode_operations *dir_inode_ops;
|
||||
struct inode_operations *file_inode_ops;
|
||||
|
||||
int (*getroot) (struct nfs_server *, struct nfs_fh *,
|
||||
struct nfs_fsinfo *);
|
||||
|
@ -713,6 +752,7 @@ struct nfs_rpc_ops {
|
|||
int (*file_open) (struct inode *, struct file *);
|
||||
int (*file_release) (struct inode *, struct file *);
|
||||
int (*lock)(struct file *, int, struct file_lock *);
|
||||
void (*clear_acl_cache)(struct inode *);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -732,4 +772,7 @@ extern struct rpc_version nfs_version2;
|
|||
extern struct rpc_version nfs_version3;
|
||||
extern struct rpc_version nfs_version4;
|
||||
|
||||
extern struct rpc_version nfsacl_version3;
|
||||
extern struct rpc_program nfsacl_program;
|
||||
|
||||
#endif
|
||||
|
|
58
include/linux/nfsacl.h
Normal file
58
include/linux/nfsacl.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* File: linux/nfsacl.h
|
||||
*
|
||||
* (C) 2003 Andreas Gruenbacher <agruen@suse.de>
|
||||
*/
|
||||
#ifndef __LINUX_NFSACL_H
|
||||
#define __LINUX_NFSACL_H
|
||||
|
||||
#define NFS_ACL_PROGRAM 100227
|
||||
|
||||
#define ACLPROC2_GETACL 1
|
||||
#define ACLPROC2_SETACL 2
|
||||
#define ACLPROC2_GETATTR 3
|
||||
#define ACLPROC2_ACCESS 4
|
||||
|
||||
#define ACLPROC3_GETACL 1
|
||||
#define ACLPROC3_SETACL 2
|
||||
|
||||
|
||||
/* Flags for the getacl/setacl mode */
|
||||
#define NFS_ACL 0x0001
|
||||
#define NFS_ACLCNT 0x0002
|
||||
#define NFS_DFACL 0x0004
|
||||
#define NFS_DFACLCNT 0x0008
|
||||
|
||||
/* Flag for Default ACL entries */
|
||||
#define NFS_ACL_DEFAULT 0x1000
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/posix_acl.h>
|
||||
|
||||
/* Maximum number of ACL entries over NFS */
|
||||
#define NFS_ACL_MAX_ENTRIES 1024
|
||||
|
||||
#define NFSACL_MAXWORDS (2*(2+3*NFS_ACL_MAX_ENTRIES))
|
||||
#define NFSACL_MAXPAGES ((2*(8+12*NFS_ACL_MAX_ENTRIES) + PAGE_SIZE-1) \
|
||||
>> PAGE_SHIFT)
|
||||
|
||||
static inline unsigned int
|
||||
nfsacl_size(struct posix_acl *acl_access, struct posix_acl *acl_default)
|
||||
{
|
||||
unsigned int w = 16;
|
||||
w += max(acl_access ? (int)acl_access->a_count : 3, 4) * 12;
|
||||
if (acl_default)
|
||||
w += max((int)acl_default->a_count, 4) * 12;
|
||||
return w;
|
||||
}
|
||||
|
||||
extern unsigned int
|
||||
nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
|
||||
struct posix_acl *acl, int encode_entries, int typeflag);
|
||||
extern unsigned int
|
||||
nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
|
||||
struct posix_acl **pacl);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __LINUX_NFSACL_H */
|
|
@ -15,6 +15,7 @@
|
|||
#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>
|
||||
|
@ -124,6 +125,21 @@ int nfsd_statfs(struct svc_rqst *, struct svc_fh *,
|
|||
int nfsd_notify_change(struct inode *, struct iattr *);
|
||||
int nfsd_permission(struct svc_export *, struct dentry *, int);
|
||||
|
||||
#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
|
||||
|
||||
|
||||
/*
|
||||
* NFSv4 State
|
||||
|
|
|
@ -169,4 +169,8 @@ int nfssvc_encode_entry(struct readdir_cd *, const char *name,
|
|||
|
||||
int nfssvc_release_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
|
||||
|
||||
/* Helper functions for NFSv2 ACL code */
|
||||
u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp);
|
||||
u32 *nfs2svc_decode_fh(u32 *p, struct svc_fh *fhp);
|
||||
|
||||
#endif /* LINUX_NFSD_H */
|
||||
|
|
|
@ -110,6 +110,19 @@ struct nfsd3_commitargs {
|
|||
__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 {
|
||||
__u32 status;
|
||||
struct svc_fh fh;
|
||||
|
@ -209,6 +222,14 @@ struct nfsd3_commitres {
|
|||
struct svc_fh fh;
|
||||
};
|
||||
|
||||
struct nfsd3_getaclres {
|
||||
__u32 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;
|
||||
|
@ -241,6 +262,7 @@ union nfsd3_xdrstore {
|
|||
struct nfsd3_fsinfores fsinfores;
|
||||
struct nfsd3_pathconfres pathconfres;
|
||||
struct nfsd3_commitres commitres;
|
||||
struct nfsd3_getaclres getaclres;
|
||||
};
|
||||
|
||||
#define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore)
|
||||
|
@ -316,6 +338,10 @@ int nfs3svc_encode_entry(struct readdir_cd *, const char *name,
|
|||
int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name,
|
||||
int namlen, loff_t offset, ino_t ino,
|
||||
unsigned int);
|
||||
/* Helper functions for NFSv3 ACL code */
|
||||
u32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p,
|
||||
struct svc_fh *fhp);
|
||||
u32 *nfs3svc_decode_fh(u32 *p, struct svc_fh *fhp);
|
||||
|
||||
|
||||
#endif /* _LINUX_NFSD_XDR3_H */
|
||||
|
|
|
@ -111,6 +111,11 @@ struct rpc_procinfo {
|
|||
struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname,
|
||||
struct rpc_program *info,
|
||||
u32 version, rpc_authflavor_t authflavor);
|
||||
struct rpc_clnt *rpc_new_client(struct rpc_xprt *xprt, char *servname,
|
||||
struct rpc_program *info,
|
||||
u32 version, rpc_authflavor_t authflavor);
|
||||
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
|
||||
struct rpc_program *, int);
|
||||
struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
|
||||
int rpc_shutdown_client(struct rpc_clnt *);
|
||||
int rpc_destroy_client(struct rpc_clnt *);
|
||||
|
@ -129,6 +134,7 @@ void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset);
|
|||
void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
|
||||
void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
|
||||
size_t rpc_max_payload(struct rpc_clnt *);
|
||||
int rpc_ping(struct rpc_clnt *clnt, int flags);
|
||||
|
||||
static __inline__
|
||||
int rpc_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
|
||||
|
|
|
@ -31,7 +31,6 @@ struct rpc_wait_queue;
|
|||
struct rpc_wait {
|
||||
struct list_head list; /* wait queue links */
|
||||
struct list_head links; /* Links to related tasks */
|
||||
wait_queue_head_t waitq; /* sync: sleep on this q */
|
||||
struct rpc_wait_queue * rpc_waitq; /* RPC wait queue we're on */
|
||||
};
|
||||
|
||||
|
|
|
@ -185,6 +185,17 @@ xdr_ressize_check(struct svc_rqst *rqstp, u32 *p)
|
|||
return vec->iov_len <= PAGE_SIZE;
|
||||
}
|
||||
|
||||
static inline struct page *
|
||||
svc_take_res_page(struct svc_rqst *rqstp)
|
||||
{
|
||||
if (rqstp->rq_arghi <= rqstp->rq_argused)
|
||||
return NULL;
|
||||
rqstp->rq_arghi--;
|
||||
rqstp->rq_respages[rqstp->rq_resused] =
|
||||
rqstp->rq_argpages[rqstp->rq_arghi];
|
||||
return rqstp->rq_respages[rqstp->rq_resused++];
|
||||
}
|
||||
|
||||
static inline int svc_take_page(struct svc_rqst *rqstp)
|
||||
{
|
||||
if (rqstp->rq_arghi <= rqstp->rq_argused)
|
||||
|
@ -240,9 +251,10 @@ struct svc_deferred_req {
|
|||
};
|
||||
|
||||
/*
|
||||
* RPC program
|
||||
* List of RPC programs on the same transport endpoint
|
||||
*/
|
||||
struct svc_program {
|
||||
struct svc_program * pg_next; /* other programs (same xprt) */
|
||||
u32 pg_prog; /* program number */
|
||||
unsigned int pg_lovers; /* lowest version */
|
||||
unsigned int pg_hivers; /* lowest version */
|
||||
|
|
|
@ -146,7 +146,8 @@ extern void xdr_shift_buf(struct xdr_buf *, size_t);
|
|||
extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *);
|
||||
extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, int, int);
|
||||
extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, int);
|
||||
extern int read_bytes_from_xdr_buf(struct xdr_buf *buf, int base, void *obj, int len);
|
||||
extern int read_bytes_from_xdr_buf(struct xdr_buf *, int, void *, int);
|
||||
extern int write_bytes_to_xdr_buf(struct xdr_buf *, int, void *, int);
|
||||
|
||||
/*
|
||||
* Helper structure for copying from an sk_buff.
|
||||
|
@ -160,7 +161,7 @@ typedef struct {
|
|||
|
||||
typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
|
||||
|
||||
extern void xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
|
||||
extern ssize_t xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
|
||||
skb_reader_t *, skb_read_actor_t);
|
||||
|
||||
struct socket;
|
||||
|
@ -168,6 +169,22 @@ struct sockaddr;
|
|||
extern int xdr_sendpages(struct socket *, struct sockaddr *, int,
|
||||
struct xdr_buf *, unsigned int, int);
|
||||
|
||||
extern int xdr_encode_word(struct xdr_buf *, int, u32);
|
||||
extern int xdr_decode_word(struct xdr_buf *, int, u32 *);
|
||||
|
||||
struct xdr_array2_desc;
|
||||
typedef int (*xdr_xcode_elem_t)(struct xdr_array2_desc *desc, void *elem);
|
||||
struct xdr_array2_desc {
|
||||
unsigned int elem_size;
|
||||
unsigned int array_len;
|
||||
xdr_xcode_elem_t xcode;
|
||||
};
|
||||
|
||||
extern int xdr_decode_array2(struct xdr_buf *buf, unsigned int base,
|
||||
struct xdr_array2_desc *desc);
|
||||
extern int xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
|
||||
struct xdr_array2_desc *desc);
|
||||
|
||||
/*
|
||||
* Provide some simple tools for XDR buffer overflow-checking etc.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue