NFS client updates for Linux 3.4

New features include:
 - Add NFS client support for containers.
   This should enable most of the necessary functionality, including
   lockd support, and support for rpc.statd, NFSv4 idmapper and
   RPCSEC_GSS upcalls into the correct network namespace from
   which the mount system call was issued.
 - NFSv4 idmapper scalability improvements
   Base the idmapper cache on the keyring interface to allow concurrent
   access to idmapper entries. Start the process of migrating users from
   the single-threaded daemon-based approach to the multi-threaded
   request-key based approach.
 - NFSv4.1 implementation id.
   Allows the NFSv4.1 client and server to mutually identify each other
   for logging and debugging purposes.
 - Support the 'vers=4.1' mount option for mounting NFSv4.1 instead of
   having to use the more counterintuitive 'vers=4,minorversion=1'.
 - SUNRPC tracepoints.
   Start the process of adding tracepoints in order to improve debugging
   of the RPC layer.
 - pNFS object layout support for autologin.
 
 Important bugfixes include:
 - Fix a bug in rpc_wake_up/rpc_wake_up_status that caused them to fail
   to wake up all tasks when applied to priority waitqueues.
 - Ensure that we handle read delegations correctly, when we try to
   truncate a file.
 - A number of fixes for NFSv4 state manager loops (mostly to do with
   delegation recovery).
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJPalZbAAoJEGcL54qWCgDyCi4P+QHcmzQhJO7HWx3Pzjs67bFT
 xMSYaKHGWS4AJKUBVl5OKBxUExfrMHBNbElV3IKUIwBlDx8RVtnwfptKSe146iki
 dn4TrRO5es8nmI4hRDcGMlzJDZq4y0Qg//qiUFmojiNW/Avw0ljfMoVUejJJ09FV
 oeDk4EGtcxkEyH+g48ZjYbyspRnG8qtD3atf70Z3lYE0ELdG/B5Dyzw1RDrA5p73
 xJX3lqy8p/4ROzw/dmNoxdAXOrr3Q4/T58Bvp/lUglPy/EHyPmWzFoH0MU0C/PFu
 5VnAl6QDbNCTcIw9FvJlX/mIyErpNG9eKzUskUc9L9SA+B+J/i4rIap4KATRN3nH
 7QhE5qUacPuJnvxml7MPmlQTuft3fkAQ7NhKIWrbRi1QS9FmJC5NxctIb8loqlFn
 yIXdKeLfMshB+NyuFS9uzStX7SmV3eMgVd+5ZxRjYxm+PKJLw2KXeudArL6M5mHK
 3QeKZpqwaYQ3RfaTNpvAp0doiXHCO5UbWfI0Pe8xQs/QcMCNReffqV2G4IJKFAu6
 WpoN2UDQC9LCBifLw2nS7kku8+ZVXLQU8OC1NVl3TG15xD9cNLXuk3/y5llPGq4O
 odo52uLFpJohbDaHMj5RTKOfchTQCm2iyuVmxZEeAySypMSiAXmW7COSKHs/HxI1
 VBm+EI00Pvmm5+fUjIlp
 =LuHE
 -----END PGP SIGNATURE-----

Merge tag 'nfs-for-3.4-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client updates for Linux 3.4 from Trond Myklebust:
 "New features include:
   - Add NFS client support for containers.

     This should enable most of the necessary functionality, including
     lockd support, and support for rpc.statd, NFSv4 idmapper and
     RPCSEC_GSS upcalls into the correct network namespace from which
     the mount system call was issued.

   - NFSv4 idmapper scalability improvements

     Base the idmapper cache on the keyring interface to allow
     concurrent access to idmapper entries.  Start the process of
     migrating users from the single-threaded daemon-based approach to
     the multi-threaded request-key based approach.

   - NFSv4.1 implementation id.

     Allows the NFSv4.1 client and server to mutually identify each
     other for logging and debugging purposes.

   - Support the 'vers=4.1' mount option for mounting NFSv4.1 instead of
     having to use the more counterintuitive 'vers=4,minorversion=1'.

   - SUNRPC tracepoints.

     Start the process of adding tracepoints in order to improve
     debugging of the RPC layer.

   - pNFS object layout support for autologin.

  Important bugfixes include:

   - Fix a bug in rpc_wake_up/rpc_wake_up_status that caused them to
     fail to wake up all tasks when applied to priority waitqueues.

   - Ensure that we handle read delegations correctly, when we try to
     truncate a file.

   - A number of fixes for NFSv4 state manager loops (mostly to do with
     delegation recovery)."

* tag 'nfs-for-3.4-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (224 commits)
  NFS: fix sb->s_id in nfs debug prints
  xprtrdma: Remove assumption that each segment is <= PAGE_SIZE
  xprtrdma: The transport should not bug-check when a dup reply is received
  pnfs-obj: autologin: Add support for protocol autologin
  NFS: Remove nfs4_setup_sequence from generic rename code
  NFS: Remove nfs4_setup_sequence from generic unlink code
  NFS: Remove nfs4_setup_sequence from generic read code
  NFS: Remove nfs4_setup_sequence from generic write code
  NFS: Fix more NFS debug related build warnings
  SUNRPC/LOCKD: Fix build warnings when CONFIG_SUNRPC_DEBUG is undefined
  nfs: non void functions must return a value
  SUNRPC: Kill compiler warning when RPC_DEBUG is unset
  SUNRPC/NFS: Add Kbuild dependencies for NFS_DEBUG/RPC_DEBUG
  NFS: Use cond_resched_lock() to reduce latencies in the commit scans
  NFSv4: It is not safe to dereference lsp->ls_state in release_lockowner
  NFS: ncommit count is being double decremented
  SUNRPC: We must not use list_for_each_entry_safe() in rpc_wake_up()
  Try using machine credentials for RENEW calls
  NFSv4.1: Fix a few issues in filelayout_commit_pagelist
  NFSv4.1: Clean ups and bugfixes for the pNFS read/writeback/commit code
  ...
This commit is contained in:
Linus Torvalds 2012-03-23 08:53:47 -07:00
commit f63d395d47
127 changed files with 5253 additions and 3023 deletions

View file

@ -277,6 +277,8 @@ static inline key_serial_t key_serial(const struct key *key)
return key ? key->serial : 0;
}
extern void key_set_timeout(struct key *, unsigned);
/**
* key_is_instantiated - Determine if a key has been positively instantiated
* @key: The key to check.

View file

@ -42,6 +42,7 @@ struct nlmclnt_initdata {
unsigned short protocol;
u32 nfs_version;
int noresvport;
struct net *net;
};
/*

View file

@ -67,6 +67,7 @@ struct nlm_host {
struct list_head h_reclaim; /* Locks in RECLAIM state */
struct nsm_handle *h_nsmhandle; /* NSM status handle */
char *h_addrbuf; /* address eyecatcher */
struct net *net; /* host net */
};
/*
@ -188,7 +189,7 @@ struct nlm_block {
/*
* Global variables
*/
extern struct rpc_program nlm_program;
extern const struct rpc_program nlm_program;
extern struct svc_procedure nlmsvc_procedures[];
#ifdef CONFIG_LOCKD_V4
extern struct svc_procedure nlmsvc_procedures4[];
@ -222,7 +223,8 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
const unsigned short protocol,
const u32 version,
const char *hostname,
int noresvport);
int noresvport,
struct net *net);
void nlmclnt_release_host(struct nlm_host *);
struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
const char *hostname,
@ -232,6 +234,7 @@ struct rpc_clnt * nlm_bind_host(struct nlm_host *);
void nlm_rebind_host(struct nlm_host *);
struct nlm_host * nlm_get_host(struct nlm_host *);
void nlm_shutdown_hosts(void);
void nlm_shutdown_hosts_net(struct net *net);
void nlm_host_rebooted(const struct nlm_reboot *);
/*

View file

@ -42,6 +42,6 @@ int nlmclt_encode_lockargs(struct rpc_rqst *, u32 *, struct nlm_args *);
int nlmclt_encode_cancargs(struct rpc_rqst *, u32 *, struct nlm_args *);
int nlmclt_encode_unlockargs(struct rpc_rqst *, u32 *, struct nlm_args *);
*/
extern struct rpc_version nlm_version4;
extern const struct rpc_version nlm_version4;
#endif /* LOCKD_XDR4_H */

View file

@ -29,7 +29,7 @@
#define NFS_MNT_VERSION 1
#define NFS_MNT3_VERSION 3
#define NFS_PIPE_DIRNAME "/nfs"
#define NFS_PIPE_DIRNAME "nfs"
/*
* NFS stats. The good thing with these values is that NFSv3 errors are

View file

@ -183,15 +183,12 @@ struct nfs4_acl {
typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
struct nfs41_stateid {
struct nfs_stateid4 {
__be32 seqid;
char other[NFS4_STATEID_OTHER_SIZE];
} __attribute__ ((packed));
typedef union {
char data[NFS4_STATEID_SIZE];
struct nfs41_stateid stateid;
} nfs4_stateid;
typedef struct nfs_stateid4 nfs4_stateid;
enum nfs_opnum4 {
OP_ACCESS = 3,

View file

@ -38,6 +38,13 @@
#ifdef __KERNEL__
/*
* Enable dprintk() debugging support for nfs client.
*/
#ifdef CONFIG_NFS_DEBUG
# define NFS_DEBUG
#endif
#include <linux/in.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
@ -171,13 +178,9 @@ struct nfs_inode {
*/
__be32 cookieverf[2];
/*
* This is the list of dirty unwritten pages.
*/
struct radix_tree_root nfs_page_tree;
unsigned long npages;
unsigned long ncommit;
struct list_head commit_list;
/* Open contexts for shared mmap writes */
struct list_head open_files;
@ -395,6 +398,29 @@ static inline void nfs_free_fhandle(const struct nfs_fh *fh)
kfree(fh);
}
#ifdef NFS_DEBUG
extern u32 _nfs_display_fhandle_hash(const struct nfs_fh *fh);
static inline u32 nfs_display_fhandle_hash(const struct nfs_fh *fh)
{
return _nfs_display_fhandle_hash(fh);
}
extern void _nfs_display_fhandle(const struct nfs_fh *fh, const char *caption);
#define nfs_display_fhandle(fh, caption) \
do { \
if (unlikely(nfs_debug & NFSDBG_FACILITY)) \
_nfs_display_fhandle(fh, caption); \
} while (0)
#else
static inline u32 nfs_display_fhandle_hash(const struct nfs_fh *fh)
{
return 0;
}
static inline void nfs_display_fhandle(const struct nfs_fh *fh,
const char *caption)
{
}
#endif
/*
* linux/fs/nfs/nfsroot.c
*/
@ -632,19 +658,13 @@ nfs_fileid_to_ino_t(u64 fileid)
#ifdef __KERNEL__
/*
* Enable debugging support for nfs client.
* Requires RPC_DEBUG.
*/
#ifdef RPC_DEBUG
# define NFS_DEBUG
#endif
# undef ifdebug
# ifdef NFS_DEBUG
# define ifdebug(fac) if (unlikely(nfs_debug & NFSDBG_##fac))
# define NFS_IFDEBUG(x) x
# else
# define ifdebug(fac) if (0)
# define NFS_IFDEBUG(x)
# endif
#endif /* __KERNEL */

View file

@ -1,10 +1,6 @@
#ifndef _NFS_FS_I
#define _NFS_FS_I
#include <asm/types.h>
#include <linux/list.h>
#include <linux/nfs.h>
struct nlm_lockowner;
/*

View file

@ -3,6 +3,7 @@
#include <linux/list.h>
#include <linux/backing-dev.h>
#include <linux/idr.h>
#include <linux/wait.h>
#include <linux/nfs_xdr.h>
#include <linux/sunrpc/xprt.h>
@ -17,6 +18,7 @@ struct nfs4_sequence_res;
struct nfs_server;
struct nfs4_minor_version_ops;
struct server_scope;
struct nfs41_impl_id;
/*
* The nfs_client identifies our client state to the server.
@ -85,6 +87,8 @@ struct nfs_client {
#endif
struct server_scope *server_scope; /* from exchange_id */
struct nfs41_impl_id *impl_id; /* from exchange_id */
struct net *net;
};
/*
@ -144,15 +148,18 @@ struct nfs_server {
u32 acl_bitmask; /* V4 bitmask representing the ACEs
that are supported on this
filesystem */
u32 fh_expire_type; /* V4 bitmask representing file
handle volatility type for
this filesystem */
struct pnfs_layoutdriver_type *pnfs_curr_ld; /* Active layout driver */
struct rpc_wait_queue roc_rpcwaitq;
void *pnfs_ld_data; /* per mount point data */
/* the following fields are protected by nfs_client->cl_lock */
struct rb_root state_owners;
struct rb_root openowner_id;
struct rb_root lockowner_id;
#endif
struct ida openowner_id;
struct ida lockowner_id;
struct list_head state_owners_lru;
struct list_head layouts;
struct list_head delegations;
@ -188,21 +195,23 @@ struct nfs_server {
/* maximum number of slots to use */
#define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE
#define NFS4_DEF_SLOT_TABLE_SIZE (16U)
#define NFS4_MAX_SLOT_TABLE (256U)
#define NFS4_NO_SLOT ((u32)-1)
#if defined(CONFIG_NFS_V4)
/* Sessions */
#define SLOT_TABLE_SZ (NFS4_MAX_SLOT_TABLE/(8*sizeof(long)))
#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
struct nfs4_slot_table {
struct nfs4_slot *slots; /* seqid per slot */
unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */
spinlock_t slot_tbl_lock;
struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */
int max_slots; /* # slots in table */
int highest_used_slotid; /* sent to server on each SEQ.
u32 max_slots; /* # slots in table */
u32 highest_used_slotid; /* sent to server on each SEQ.
* op for dynamic resizing */
int target_max_slots; /* Set by CB_RECALL_SLOT as
u32 target_max_slots; /* Set by CB_RECALL_SLOT as
* the new max_slots */
struct completion complete;
};

View file

@ -69,36 +69,22 @@ struct nfs_server;
struct nfs_fattr;
struct nfs4_string;
#ifdef CONFIG_NFS_USE_NEW_IDMAPPER
#ifdef CONFIG_NFS_V4
int nfs_idmap_init(void);
void nfs_idmap_quit(void);
static inline int nfs_idmap_new(struct nfs_client *clp)
{
return 0;
}
static inline void nfs_idmap_delete(struct nfs_client *clp)
{
}
#else /* CONFIG_NFS_USE_NEW_IDMAPPER not set */
#else
static inline int nfs_idmap_init(void)
{
return 0;
}
static inline void nfs_idmap_quit(void)
{
}
{}
#endif
int nfs_idmap_new(struct nfs_client *);
void nfs_idmap_delete(struct nfs_client *);
#endif /* CONFIG_NFS_USE_NEW_IDMAPPER */
void nfs_fattr_init_names(struct nfs_fattr *fattr,
struct nfs4_string *owner_name,
struct nfs4_string *group_name);

View file

@ -21,7 +21,7 @@
#ifndef _LINUX_NFS_IOSTAT
#define _LINUX_NFS_IOSTAT
#define NFS_IOSTAT_VERS "1.0"
#define NFS_IOSTAT_VERS "1.1"
/*
* NFS byte counters

View file

@ -18,12 +18,6 @@
#include <linux/kref.h>
/*
* Valid flags for the radix tree
*/
#define NFS_PAGE_TAG_LOCKED 0
#define NFS_PAGE_TAG_COMMIT 1
/*
* Valid flags for a dirty buffer
*/
@ -33,16 +27,13 @@ enum {
PG_CLEAN,
PG_NEED_COMMIT,
PG_NEED_RESCHED,
PG_PNFS_COMMIT,
PG_PARTIAL_READ_FAILED,
PG_COMMIT_TO_DS,
};
struct nfs_inode;
struct nfs_page {
union {
struct list_head wb_list; /* Defines state of page: */
struct pnfs_layout_segment *wb_commit_lseg; /* Used when PG_PNFS_COMMIT set */
};
struct list_head wb_list; /* Defines state of page: */
struct page *wb_page; /* page to read in/write out */
struct nfs_open_context *wb_context; /* File state context info */
struct nfs_lock_context *wb_lock_context; /* lock context info */
@ -90,8 +81,6 @@ extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx,
extern void nfs_release_request(struct nfs_page *req);
extern int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *dst,
pgoff_t idx_start, unsigned int npages, int tag);
extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
struct inode *inode,
const struct nfs_pageio_ops *pg_ops,
@ -106,8 +95,6 @@ extern bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
struct nfs_page *req);
extern int nfs_wait_on_request(struct nfs_page *);
extern void nfs_unlock_request(struct nfs_page *req);
extern int nfs_set_page_tag_locked(struct nfs_page *req);
extern void nfs_clear_page_tag_locked(struct nfs_page *req);
/*
* Lock the page of an asynchronous request without getting a new reference
@ -118,6 +105,16 @@ nfs_lock_request_dontget(struct nfs_page *req)
return !test_and_set_bit(PG_BUSY, &req->wb_flags);
}
static inline int
nfs_lock_request(struct nfs_page *req)
{
if (test_and_set_bit(PG_BUSY, &req->wb_flags))
return 0;
kref_get(&req->wb_kref);
return 1;
}
/**
* nfs_list_add_request - Insert a request into a list
* @req: request

View file

@ -2,7 +2,6 @@
#define _LINUX_NFS_XDR_H
#include <linux/nfsacl.h>
#include <linux/nfs3.h>
#include <linux/sunrpc/gss_api.h>
/*
@ -89,11 +88,12 @@ struct nfs_fattr {
#define NFS_ATTR_FATTR_PRECTIME (1U << 16)
#define NFS_ATTR_FATTR_CHANGE (1U << 17)
#define NFS_ATTR_FATTR_PRECHANGE (1U << 18)
#define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */
#define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */
#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21)
#define NFS_ATTR_FATTR_OWNER_NAME (1U << 22)
#define NFS_ATTR_FATTR_GROUP_NAME (1U << 23)
#define NFS_ATTR_FATTR_V4_LOCATIONS (1U << 19)
#define NFS_ATTR_FATTR_V4_REFERRAL (1U << 20)
#define NFS_ATTR_FATTR_MOUNTPOINT (1U << 21)
#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 22)
#define NFS_ATTR_FATTR_OWNER_NAME (1U << 23)
#define NFS_ATTR_FATTR_GROUP_NAME (1U << 24)
#define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
| NFS_ATTR_FATTR_MODE \
@ -182,7 +182,7 @@ struct nfs4_slot {
struct nfs4_sequence_args {
struct nfs4_session *sa_session;
u8 sa_slotid;
u32 sa_slotid;
u8 sa_cache_this;
};
@ -977,6 +977,7 @@ struct nfs4_server_caps_res {
u32 acl_bitmask;
u32 has_links;
u32 has_symlinks;
u32 fh_expire_type;
struct nfs4_sequence_res seq_res;
};
@ -1055,14 +1056,6 @@ struct nfstime4 {
};
#ifdef CONFIG_NFS_V4_1
struct nfs_impl_id4 {
u32 domain_len;
char *domain;
u32 name_len;
char *name;
struct nfstime4 date;
};
#define NFS4_EXCHANGE_ID_LEN (48)
struct nfs41_exchange_id_args {
struct nfs_client *client;
@ -1083,10 +1076,17 @@ struct server_scope {
char server_scope[NFS4_OPAQUE_LIMIT];
};
struct nfs41_impl_id {
char domain[NFS4_OPAQUE_LIMIT + 1];
char name[NFS4_OPAQUE_LIMIT + 1];
struct nfstime4 date;
};
struct nfs41_exchange_id_res {
struct nfs_client *client;
u32 flags;
struct server_scope *server_scope;
struct nfs41_impl_id *impl_id;
};
struct nfs41_create_session_args {
@ -1192,6 +1192,27 @@ struct nfs_write_data {
struct page *page_array[NFS_PAGEVEC_SIZE];
};
struct nfs_unlinkdata {
struct hlist_node list;
struct nfs_removeargs args;
struct nfs_removeres res;
struct inode *dir;
struct rpc_cred *cred;
struct nfs_fattr dir_attr;
};
struct nfs_renamedata {
struct nfs_renameargs args;
struct nfs_renameres res;
struct rpc_cred *cred;
struct inode *old_dir;
struct dentry *old_dentry;
struct nfs_fattr old_fattr;
struct inode *new_dir;
struct dentry *new_dentry;
struct nfs_fattr new_fattr;
};
struct nfs_access_entry;
struct nfs_client;
struct rpc_timeout;
@ -1221,10 +1242,12 @@ struct nfs_rpc_ops {
struct iattr *, int, struct nfs_open_context *);
int (*remove) (struct inode *, struct qstr *);
void (*unlink_setup) (struct rpc_message *, struct inode *dir);
void (*unlink_rpc_prepare) (struct rpc_task *, struct nfs_unlinkdata *);
int (*unlink_done) (struct rpc_task *, struct inode *);
int (*rename) (struct inode *, struct qstr *,
struct inode *, struct qstr *);
void (*rename_setup) (struct rpc_message *msg, struct inode *dir);
void (*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *);
int (*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir);
int (*link) (struct inode *, struct inode *, struct qstr *);
int (*symlink) (struct inode *, struct dentry *, struct page *,
@ -1244,8 +1267,10 @@ struct nfs_rpc_ops {
int (*set_capabilities)(struct nfs_server *, struct nfs_fh *);
int (*decode_dirent)(struct xdr_stream *, struct nfs_entry *, int);
void (*read_setup) (struct nfs_read_data *, struct rpc_message *);
void (*read_rpc_prepare)(struct rpc_task *, struct nfs_read_data *);
int (*read_done) (struct rpc_task *, struct nfs_read_data *);
void (*write_setup) (struct nfs_write_data *, struct rpc_message *);
void (*write_rpc_prepare)(struct rpc_task *, struct nfs_write_data *);
int (*write_done) (struct rpc_task *, struct nfs_write_data *);
void (*commit_setup) (struct nfs_write_data *, struct rpc_message *);
int (*commit_done) (struct rpc_task *, struct nfs_write_data *);
@ -1275,11 +1300,11 @@ struct nfs_rpc_ops {
extern const struct nfs_rpc_ops nfs_v2_clientops;
extern const struct nfs_rpc_ops nfs_v3_clientops;
extern const struct nfs_rpc_ops nfs_v4_clientops;
extern struct rpc_version nfs_version2;
extern struct rpc_version nfs_version3;
extern struct rpc_version nfs_version4;
extern const struct rpc_version nfs_version2;
extern const struct rpc_version nfs_version3;
extern const struct rpc_version nfs_version4;
extern struct rpc_version nfsacl_version3;
extern struct rpc_program nfsacl_program;
extern const struct rpc_version nfsacl_version3;
extern const struct rpc_program nfsacl_program;
#endif

View file

@ -99,6 +99,8 @@ struct rpc_authops {
struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int);
struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int);
int (*pipes_create)(struct rpc_auth *);
void (*pipes_destroy)(struct rpc_auth *);
};
struct rpc_credops {

View file

@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt);
void xprt_free_bc_request(struct rpc_rqst *req);
int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs);
void xprt_destroy_backchannel(struct rpc_xprt *, int max_reqs);
void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs);
int bc_send(struct rpc_rqst *req);
/*

View file

@ -117,6 +117,7 @@ struct cache_detail {
struct cache_detail_procfs procfs;
struct cache_detail_pipefs pipefs;
} u;
struct net *net;
};
@ -197,11 +198,14 @@ extern void cache_flush(void);
extern void cache_purge(struct cache_detail *detail);
#define NEVER (0x7FFFFFFF)
extern void __init cache_initialize(void);
extern int cache_register(struct cache_detail *cd);
extern int cache_register_net(struct cache_detail *cd, struct net *net);
extern void cache_unregister(struct cache_detail *cd);
extern void cache_unregister_net(struct cache_detail *cd, struct net *net);
extern struct cache_detail *cache_create_net(struct cache_detail *tmpl, struct net *net);
extern void cache_destroy_net(struct cache_detail *cd, struct net *net);
extern void sunrpc_init_cache_detail(struct cache_detail *cd);
extern void sunrpc_destroy_cache_detail(struct cache_detail *cd);
extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
umode_t, struct cache_detail *);
extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);

View file

@ -35,14 +35,13 @@ struct rpc_clnt {
struct list_head cl_clients; /* Global list of clients */
struct list_head cl_tasks; /* List of tasks */
spinlock_t cl_lock; /* spinlock */
struct rpc_xprt * cl_xprt; /* transport */
struct rpc_xprt __rcu * cl_xprt; /* transport */
struct rpc_procinfo * cl_procinfo; /* procedure info */
u32 cl_prog, /* RPC program number */
cl_vers, /* RPC version number */
cl_maxproc; /* max procedure number */
char * cl_server; /* server machine name */
char * cl_protname; /* protocol name */
const char * cl_protname; /* protocol name */
struct rpc_auth * cl_auth; /* authenticator */
struct rpc_stat * cl_stats; /* per-program statistics */
struct rpc_iostats * cl_metrics; /* per-client statistics */
@ -57,12 +56,11 @@ struct rpc_clnt {
int cl_nodelen; /* nodename length */
char cl_nodename[UNX_MAXNODENAME];
struct path cl_path;
struct dentry * cl_dentry;
struct rpc_clnt * cl_parent; /* Points to parent of clones */
struct rpc_rtt cl_rtt_default;
struct rpc_timeout cl_timeout_default;
struct rpc_program * cl_program;
char cl_inline_name[32];
const struct rpc_program *cl_program;
char *cl_principal; /* target to authenticate to */
};
@ -71,12 +69,12 @@ struct rpc_clnt {
*/
#define RPC_MAXVERSION 4
struct rpc_program {
char * name; /* protocol name */
const char * name; /* protocol name */
u32 number; /* program number */
unsigned int nrvers; /* number of versions */
struct rpc_version ** version; /* version array */
const struct rpc_version ** version; /* version array */
struct rpc_stat * stats; /* statistics */
char * pipe_dir_name; /* path to rpc_pipefs dir */
const char * pipe_dir_name; /* path to rpc_pipefs dir */
};
struct rpc_version {
@ -97,7 +95,7 @@ struct rpc_procinfo {
unsigned int p_count; /* call count */
unsigned int p_timer; /* Which RTT timer to use */
u32 p_statidx; /* Which procedure to account */
char * p_name; /* name of procedure */
const char * p_name; /* name of procedure */
};
#ifdef __KERNEL__
@ -109,8 +107,8 @@ struct rpc_create_args {
size_t addrsize;
struct sockaddr *saddress;
const struct rpc_timeout *timeout;
char *servername;
struct rpc_program *program;
const char *servername;
const struct rpc_program *program;
u32 prognumber; /* overrides program->number */
u32 version;
rpc_authflavor_t authflavor;
@ -129,17 +127,18 @@ struct rpc_create_args {
struct rpc_clnt *rpc_create(struct rpc_create_args *args);
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
struct rpc_program *, u32);
const struct rpc_program *, u32);
void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt);
struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
void rpc_shutdown_client(struct rpc_clnt *);
void rpc_release_client(struct rpc_clnt *);
void rpc_task_release_client(struct rpc_task *);
int rpcb_create_local(void);
void rpcb_put_local(void);
int rpcb_register(u32, u32, int, unsigned short);
int rpcb_v4_register(const u32 program, const u32 version,
int rpcb_create_local(struct net *);
void rpcb_put_local(struct net *);
int rpcb_register(struct net *, u32, u32, int, unsigned short);
int rpcb_v4_register(struct net *net, const u32 program,
const u32 version,
const struct sockaddr *address,
const char *netid);
void rpcb_getport_async(struct rpc_task *);
@ -156,16 +155,19 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred,
int rpc_restart_call_prepare(struct rpc_task *);
int rpc_restart_call(struct rpc_task *);
void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
int rpc_protocol(struct rpc_clnt *);
struct net * rpc_net_ns(struct rpc_clnt *);
size_t rpc_max_payload(struct rpc_clnt *);
void rpc_force_rebind(struct rpc_clnt *);
size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t);
size_t rpc_ntop(const struct sockaddr *, char *, const size_t);
size_t rpc_pton(const char *, const size_t,
size_t rpc_pton(struct net *, const char *, const size_t,
struct sockaddr *, const size_t);
char * rpc_sockaddr2uaddr(const struct sockaddr *, gfp_t);
size_t rpc_uaddr2sockaddr(const char *, const size_t,
size_t rpc_uaddr2sockaddr(struct net *, const char *, const size_t,
struct sockaddr *, const size_t);
static inline unsigned short rpc_get_port(const struct sockaddr *sap)

View file

@ -31,9 +31,12 @@
/*
* Enable RPC debugging/profiling.
*/
#ifdef CONFIG_SYSCTL
#ifdef CONFIG_SUNRPC_DEBUG
#define RPC_DEBUG
#endif
#ifdef CONFIG_TRACEPOINTS
#define RPC_TRACEPOINTS
#endif
/* #define RPC_PROFILE */
/*
@ -47,15 +50,32 @@ extern unsigned int nlm_debug;
#endif
#define dprintk(args...) dfprintk(FACILITY, ## args)
#define dprintk_rcu(args...) dfprintk_rcu(FACILITY, ## args)
#undef ifdebug
#ifdef RPC_DEBUG
# define ifdebug(fac) if (unlikely(rpc_debug & RPCDBG_##fac))
# define dfprintk(fac, args...) do { ifdebug(fac) printk(args); } while(0)
# define dfprintk(fac, args...) \
do { \
ifdebug(fac) \
printk(KERN_DEFAULT args); \
} while (0)
# define dfprintk_rcu(fac, args...) \
do { \
ifdebug(fac) { \
rcu_read_lock(); \
printk(KERN_DEFAULT args); \
rcu_read_unlock(); \
} \
} while (0)
# define RPC_IFDEBUG(x) x
#else
# define ifdebug(fac) if (0)
# define dfprintk(fac, args...) do ; while (0)
# define dfprintk(fac, args...) do {} while (0)
# define dfprintk_rcu(fac, args...) do {} while (0)
# define RPC_IFDEBUG(x)
#endif

View file

@ -74,14 +74,16 @@ struct rpc_clnt;
#ifdef CONFIG_PROC_FS
struct rpc_iostats * rpc_alloc_iostats(struct rpc_clnt *);
void rpc_count_iostats(struct rpc_task *);
void rpc_count_iostats(const struct rpc_task *,
struct rpc_iostats *);
void rpc_print_iostats(struct seq_file *, struct rpc_clnt *);
void rpc_free_iostats(struct rpc_iostats *);
#else /* CONFIG_PROC_FS */
static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; }
static inline void rpc_count_iostats(struct rpc_task *task) {}
static inline void rpc_count_iostats(const struct rpc_task *task,
struct rpc_iostats *stats) {}
static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {}
static inline void rpc_free_iostats(struct rpc_iostats *stats) {}

View file

@ -21,21 +21,26 @@ struct rpc_pipe_ops {
void (*destroy_msg)(struct rpc_pipe_msg *);
};
struct rpc_inode {
struct inode vfs_inode;
void *private;
struct rpc_pipe {
struct list_head pipe;
struct list_head in_upcall;
struct list_head in_downcall;
int pipelen;
int nreaders;
int nwriters;
int nkern_readwriters;
wait_queue_head_t waitq;
#define RPC_PIPE_WAIT_FOR_OPEN 1
int flags;
struct delayed_work queue_timeout;
const struct rpc_pipe_ops *ops;
spinlock_t lock;
struct dentry *dentry;
};
struct rpc_inode {
struct inode vfs_inode;
void *private;
struct rpc_pipe *pipe;
wait_queue_head_t waitq;
};
static inline struct rpc_inode *
@ -44,9 +49,28 @@ RPC_I(struct inode *inode)
return container_of(inode, struct rpc_inode, vfs_inode);
}
enum {
SUNRPC_PIPEFS_NFS_PRIO,
SUNRPC_PIPEFS_RPC_PRIO,
};
extern int rpc_pipefs_notifier_register(struct notifier_block *);
extern void rpc_pipefs_notifier_unregister(struct notifier_block *);
enum {
RPC_PIPEFS_MOUNT,
RPC_PIPEFS_UMOUNT,
};
extern struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
const unsigned char *dir_name);
extern void rpc_pipefs_init_net(struct net *net);
extern struct super_block *rpc_get_sb_net(const struct net *net);
extern void rpc_put_sb_net(const struct net *net);
extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *,
char __user *, size_t);
extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
extern int rpc_queue_upcall(struct rpc_pipe *, struct rpc_pipe_msg *);
struct rpc_clnt;
extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *);
@ -59,11 +83,13 @@ extern struct dentry *rpc_create_cache_dir(struct dentry *,
struct cache_detail *);
extern void rpc_remove_cache_dir(struct dentry *);
extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *,
const struct rpc_pipe_ops *, int flags);
extern int rpc_rmdir(struct dentry *dentry);
struct rpc_pipe *rpc_mkpipe_data(const struct rpc_pipe_ops *ops, int flags);
void rpc_destroy_pipe_data(struct rpc_pipe *pipe);
extern struct dentry *rpc_mkpipe_dentry(struct dentry *, const char *, void *,
struct rpc_pipe *);
extern int rpc_unlink(struct dentry *);
extern struct vfsmount *rpc_get_mount(void);
extern void rpc_put_mount(void);
extern int register_rpc_pipefs(void);
extern void unregister_rpc_pipefs(void);

View file

@ -103,6 +103,7 @@ typedef void (*rpc_action)(struct rpc_task *);
struct rpc_call_ops {
void (*rpc_call_prepare)(struct rpc_task *, void *);
void (*rpc_call_done)(struct rpc_task *, void *);
void (*rpc_count_stats)(struct rpc_task *, void *);
void (*rpc_release)(void *);
};
@ -195,7 +196,7 @@ struct rpc_wait_queue {
unsigned char nr; /* # tasks remaining for cookie */
unsigned short qlen; /* total # tasks waiting in queue */
struct rpc_timer timer_list;
#ifdef RPC_DEBUG
#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
const char * name;
#endif
};
@ -235,6 +236,9 @@ void rpc_wake_up_queued_task(struct rpc_wait_queue *,
struct rpc_task *);
void rpc_wake_up(struct rpc_wait_queue *);
struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *);
struct rpc_task *rpc_wake_up_first(struct rpc_wait_queue *,
bool (*)(struct rpc_task *, void *),
void *);
void rpc_wake_up_status(struct rpc_wait_queue *, int);
int rpc_queue_empty(struct rpc_wait_queue *);
void rpc_delay(struct rpc_task *, unsigned long);
@ -244,7 +248,8 @@ int rpciod_up(void);
void rpciod_down(void);
int __rpc_wait_for_completion_task(struct rpc_task *task, int (*)(void *));
#ifdef RPC_DEBUG
void rpc_show_tasks(void);
struct net;
void rpc_show_tasks(struct net *);
#endif
int rpc_init_mempool(void);
void rpc_destroy_mempool(void);
@ -266,11 +271,22 @@ static inline int rpc_task_has_priority(struct rpc_task *task, unsigned char pri
return (task->tk_priority + RPC_PRIORITY_LOW == prio);
}
#ifdef RPC_DEBUG
static inline const char * rpc_qname(struct rpc_wait_queue *q)
#if defined(RPC_DEBUG) || defined (RPC_TRACEPOINTS)
static inline const char * rpc_qname(const struct rpc_wait_queue *q)
{
return ((q && q->name) ? q->name : "unknown");
}
static inline void rpc_assign_waitqueue_name(struct rpc_wait_queue *q,
const char *name)
{
q->name = name;
}
#else
static inline void rpc_assign_waitqueue_name(struct rpc_wait_queue *q,
const char *name)
{
}
#endif
#endif /* _LINUX_SUNRPC_SCHED_H_ */

View file

@ -12,7 +12,7 @@
#include <linux/proc_fs.h>
struct rpc_stat {
struct rpc_program * program;
const struct rpc_program *program;
unsigned int netcnt,
netudpcnt,
@ -58,24 +58,24 @@ void rpc_modcount(struct inode *, int);
#endif
#ifdef CONFIG_PROC_FS
struct proc_dir_entry * rpc_proc_register(struct rpc_stat *);
void rpc_proc_unregister(const char *);
void rpc_proc_zero(struct rpc_program *);
struct proc_dir_entry * svc_proc_register(struct svc_stat *,
struct proc_dir_entry * rpc_proc_register(struct net *,struct rpc_stat *);
void rpc_proc_unregister(struct net *,const char *);
void rpc_proc_zero(const struct rpc_program *);
struct proc_dir_entry * svc_proc_register(struct net *, struct svc_stat *,
const struct file_operations *);
void svc_proc_unregister(const char *);
void svc_proc_unregister(struct net *, const char *);
void svc_seq_show(struct seq_file *,
const struct svc_stat *);
#else
static inline struct proc_dir_entry *rpc_proc_register(struct rpc_stat *s) { return NULL; }
static inline void rpc_proc_unregister(const char *p) {}
static inline void rpc_proc_zero(struct rpc_program *p) {}
static inline struct proc_dir_entry *rpc_proc_register(struct net *net, struct rpc_stat *s) { return NULL; }
static inline void rpc_proc_unregister(struct net *net, const char *p) {}
static inline void rpc_proc_zero(const struct rpc_program *p) {}
static inline struct proc_dir_entry *svc_proc_register(struct svc_stat *s,
static inline struct proc_dir_entry *svc_proc_register(struct net *net, struct svc_stat *s,
const struct file_operations *f) { return NULL; }
static inline void svc_proc_unregister(const char *p) {}
static inline void svc_proc_unregister(struct net *net, const char *p) {}
static inline void svc_seq_show(struct seq_file *seq,
const struct svc_stat *st) {}

View file

@ -84,7 +84,8 @@ struct svc_serv {
unsigned int sv_nrpools; /* number of thread pools */
struct svc_pool * sv_pools; /* array of thread pools */
void (*sv_shutdown)(struct svc_serv *serv);
void (*sv_shutdown)(struct svc_serv *serv,
struct net *net);
/* Callback to use when last thread
* exits.
*/
@ -413,22 +414,24 @@ struct svc_procedure {
/*
* Function prototypes.
*/
void svc_rpcb_cleanup(struct svc_serv *serv);
int svc_rpcb_setup(struct svc_serv *serv, struct net *net);
void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net);
struct svc_serv *svc_create(struct svc_program *, unsigned int,
void (*shutdown)(struct svc_serv *));
void (*shutdown)(struct svc_serv *, struct net *net));
struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
struct svc_pool *pool, int node);
void svc_exit_thread(struct svc_rqst *);
struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
void (*shutdown)(struct svc_serv *),
void (*shutdown)(struct svc_serv *, struct net *net),
svc_thread_fn, struct module *);
int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
void svc_destroy(struct svc_serv *);
void svc_shutdown_net(struct svc_serv *, struct net *);
int svc_process(struct svc_rqst *);
int bc_svc_process(struct svc_serv *, struct rpc_rqst *,
struct svc_rqst *);
int svc_register(const struct svc_serv *, const int,
int svc_register(const struct svc_serv *, struct net *, const int,
const unsigned short, const unsigned short);
void svc_wake_up(struct svc_serv *);

View file

@ -121,7 +121,8 @@ void svc_close_xprt(struct svc_xprt *xprt);
int svc_port_is_privileged(struct sockaddr *sin);
int svc_print_xprts(char *buf, int maxlen);
struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
const sa_family_t af, const unsigned short port);
struct net *net, const sa_family_t af,
const unsigned short port);
int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen);
static inline void svc_xprt_get(struct svc_xprt *xprt)

View file

@ -135,6 +135,9 @@ extern void svcauth_unix_purge(void);
extern void svcauth_unix_info_release(struct svc_xprt *xpt);
extern int svcauth_unix_set_client(struct svc_rqst *rqstp);
extern int unix_gid_cache_create(struct net *net);
extern void unix_gid_cache_destroy(struct net *net);
static inline unsigned long hash_str(char *name, int bits)
{
unsigned long hash = 0;

View file

@ -18,6 +18,8 @@
int gss_svc_init(void);
void gss_svc_shutdown(void);
int gss_svc_init_net(struct net *net);
void gss_svc_shutdown_net(struct net *net);
int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
u32 svcauth_gss_flavor(struct auth_domain *dom);
char *svc_gss_principal(struct svc_rqst *);

View file

@ -34,7 +34,7 @@ struct svc_sock {
/*
* Function prototypes.
*/
void svc_close_all(struct svc_serv *);
void svc_close_net(struct svc_serv *, struct net *);
int svc_recv(struct svc_rqst *, long);
int svc_send(struct svc_rqst *);
void svc_drop(struct svc_rqst *);

View file

@ -21,8 +21,8 @@
#define RPC_MIN_SLOT_TABLE (2U)
#define RPC_DEF_SLOT_TABLE (16U)
#define RPC_MAX_SLOT_TABLE (128U)
#define RPC_MAX_SLOT_TABLE_LIMIT (65536U)
#define RPC_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE_LIMIT
/*
* This describes a timeout strategy
@ -219,13 +219,17 @@ struct rpc_xprt {
connect_time, /* jiffies waiting for connect */
sends, /* how many complete requests */
recvs, /* how many complete requests */
bad_xids; /* lookup_rqst didn't find XID */
bad_xids, /* lookup_rqst didn't find XID */
max_slots; /* max rpc_slots used */
unsigned long long req_u, /* average requests on the wire */
bklog_u; /* backlog queue utilization */
bklog_u, /* backlog queue utilization */
sending_u, /* send q utilization */
pending_u; /* pend q utilization */
} stat;
struct net *xprt_net;
const char *servername;
const char *address_strings[RPC_DISPLAY_MAX];
};
@ -255,6 +259,7 @@ struct xprt_create {
struct sockaddr * srcaddr; /* optional local address */
struct sockaddr * dstaddr; /* remote peer address */
size_t addrlen;
const char *servername;
struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */
};

View file

@ -12,18 +12,6 @@
int init_socket_xprt(void);
void cleanup_socket_xprt(void);
/*
* RPC slot table sizes for UDP, TCP transports
*/
extern unsigned int xprt_udp_slot_table_entries;
extern unsigned int xprt_tcp_slot_table_entries;
/*
* Parameters for choosing a free port
*/
extern unsigned int xprt_min_resvport;
extern unsigned int xprt_max_resvport;
#define RPC_MIN_RESVPORT (1U)
#define RPC_MAX_RESVPORT (65535U)
#define RPC_DEF_MIN_RESVPORT (665U)