Merge tag 'nfs-for-4.21-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client updates from Anna Schumaker: "Stable bugfixes: - xprtrdma: Yet another double DMA-unmap # v4.20 Features: - Allow some /proc/sys/sunrpc entries without CONFIG_SUNRPC_DEBUG - Per-xprt rdma receive workqueues - Drop support for FMR memory registration - Make port= mount option optional for RDMA mounts Other bugfixes and cleanups: - Remove unused nfs4_xdev_fs_type declaration - Fix comments for behavior that has changed - Remove generic RPC credentials by switching to 'struct cred' - Fix crossing mountpoints with different auth flavors - Various xprtrdma fixes from testing and auditing the close code - Fixes for disconnect issues when using xprtrdma with krb5 - Clean up and improve xprtrdma trace points - Fix NFS v4.2 async copy reboot recovery" * tag 'nfs-for-4.21-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (63 commits) sunrpc: convert to DEFINE_SHOW_ATTRIBUTE sunrpc: Add xprt after nfs4_test_session_trunk() sunrpc: convert unnecessary GFP_ATOMIC to GFP_NOFS sunrpc: handle ENOMEM in rpcb_getport_async NFS: remove unnecessary test for IS_ERR(cred) xprtrdma: Prevent leak of rpcrdma_rep objects NFSv4.2 fix async copy reboot recovery xprtrdma: Don't leak freed MRs xprtrdma: Add documenting comment for rpcrdma_buffer_destroy xprtrdma: Replace outdated comment for rpcrdma_ep_post xprtrdma: Update comments in frwr_op_send SUNRPC: Fix some kernel doc complaints SUNRPC: Simplify defining common RPC trace events NFS: Fix NFSv4 symbolic trace point output xprtrdma: Trace mapping, alloc, and dereg failures xprtrdma: Add trace points for calls to transport switch methods xprtrdma: Relocate the xprtrdma_mr_map trace points xprtrdma: Clean up of xprtrdma chunk trace points xprtrdma: Remove unused fields from rpcrdma_ia xprtrdma: Cull dprintk() call sites ...
This commit is contained in:
@@ -256,7 +256,7 @@ static int nlm_wait_on_grace(wait_queue_head_t *queue)
|
||||
* Generic NLM call
|
||||
*/
|
||||
static int
|
||||
nlmclnt_call(struct rpc_cred *cred, struct nlm_rqst *req, u32 proc)
|
||||
nlmclnt_call(const struct cred *cred, struct nlm_rqst *req, u32 proc)
|
||||
{
|
||||
struct nlm_host *host = req->a_host;
|
||||
struct rpc_clnt *clnt;
|
||||
@@ -401,7 +401,7 @@ int nlm_async_reply(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *t
|
||||
* completion in order to be able to correctly track the lock
|
||||
* state.
|
||||
*/
|
||||
static int nlmclnt_async_call(struct rpc_cred *cred, struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
|
||||
static int nlmclnt_async_call(const struct cred *cred, struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_argp = &req->a_args,
|
||||
@@ -510,7 +510,7 @@ static int do_vfs_lock(struct file_lock *fl)
|
||||
static int
|
||||
nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
|
||||
{
|
||||
struct rpc_cred *cred = nfs_file_cred(fl->fl_file);
|
||||
const struct cred *cred = nfs_file_cred(fl->fl_file);
|
||||
struct nlm_host *host = req->a_host;
|
||||
struct nlm_res *resp = &req->a_res;
|
||||
struct nlm_wait *block = NULL;
|
||||
|
||||
@@ -584,7 +584,7 @@ static int decode_sector_number(__be32 **rp, sector_t *sp)
|
||||
|
||||
static struct nfs4_deviceid_node *
|
||||
bl_find_get_deviceid(struct nfs_server *server,
|
||||
const struct nfs4_deviceid *id, struct rpc_cred *cred,
|
||||
const struct nfs4_deviceid *id, const struct cred *cred,
|
||||
gfp_t gfp_mask)
|
||||
{
|
||||
struct nfs4_deviceid_node *node;
|
||||
|
||||
@@ -151,7 +151,6 @@ EXPORT_SYMBOL_GPL(unregister_nfs_version);
|
||||
struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
|
||||
{
|
||||
struct nfs_client *clp;
|
||||
struct rpc_cred *cred;
|
||||
int err = -ENOMEM;
|
||||
|
||||
if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
|
||||
@@ -182,9 +181,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
|
||||
clp->cl_proto = cl_init->proto;
|
||||
clp->cl_net = get_net(cl_init->net);
|
||||
|
||||
cred = rpc_lookup_machine_cred("*");
|
||||
if (!IS_ERR(cred))
|
||||
clp->cl_machine_cred = cred;
|
||||
clp->cl_principal = "*";
|
||||
nfs_fscache_get_client_cookie(clp);
|
||||
|
||||
return clp;
|
||||
@@ -246,9 +243,6 @@ void nfs_free_client(struct nfs_client *clp)
|
||||
if (!IS_ERR(clp->cl_rpcclient))
|
||||
rpc_shutdown_client(clp->cl_rpcclient);
|
||||
|
||||
if (clp->cl_machine_cred != NULL)
|
||||
put_rpccred(clp->cl_machine_cred);
|
||||
|
||||
put_net(clp->cl_net);
|
||||
put_nfs_version(clp->cl_nfs_mod);
|
||||
kfree(clp->cl_hostname);
|
||||
@@ -527,6 +521,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
|
||||
return PTR_ERR(clnt);
|
||||
}
|
||||
|
||||
clnt->cl_principal = clp->cl_principal;
|
||||
clp->cl_rpcclient = clnt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -26,10 +26,8 @@
|
||||
|
||||
static void nfs_free_delegation(struct nfs_delegation *delegation)
|
||||
{
|
||||
if (delegation->cred) {
|
||||
put_rpccred(delegation->cred);
|
||||
put_cred(delegation->cred);
|
||||
delegation->cred = NULL;
|
||||
}
|
||||
kfree_rcu(delegation, rcu);
|
||||
}
|
||||
|
||||
@@ -178,13 +176,13 @@ again:
|
||||
* @pagemod_limit: write delegation "space_limit"
|
||||
*
|
||||
*/
|
||||
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
|
||||
void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
|
||||
fmode_t type,
|
||||
const nfs4_stateid *stateid,
|
||||
unsigned long pagemod_limit)
|
||||
{
|
||||
struct nfs_delegation *delegation;
|
||||
struct rpc_cred *oldcred = NULL;
|
||||
const struct cred *oldcred = NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
delegation = rcu_dereference(NFS_I(inode)->delegation);
|
||||
@@ -195,12 +193,12 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
|
||||
delegation->type = type;
|
||||
delegation->pagemod_limit = pagemod_limit;
|
||||
oldcred = delegation->cred;
|
||||
delegation->cred = get_rpccred(cred);
|
||||
delegation->cred = get_cred(cred);
|
||||
clear_bit(NFS_DELEGATION_NEED_RECLAIM,
|
||||
&delegation->flags);
|
||||
spin_unlock(&delegation->lock);
|
||||
rcu_read_unlock();
|
||||
put_rpccred(oldcred);
|
||||
put_cred(oldcred);
|
||||
trace_nfs4_reclaim_delegation(inode, type);
|
||||
return;
|
||||
}
|
||||
@@ -341,7 +339,7 @@ nfs_update_inplace_delegation(struct nfs_delegation *delegation,
|
||||
*
|
||||
* Returns zero on success, or a negative errno value.
|
||||
*/
|
||||
int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred,
|
||||
int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
|
||||
fmode_t type,
|
||||
const nfs4_stateid *stateid,
|
||||
unsigned long pagemod_limit)
|
||||
@@ -360,7 +358,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred,
|
||||
delegation->type = type;
|
||||
delegation->pagemod_limit = pagemod_limit;
|
||||
delegation->change_attr = inode_peek_iversion_raw(inode);
|
||||
delegation->cred = get_rpccred(cred);
|
||||
delegation->cred = get_cred(cred);
|
||||
delegation->inode = inode;
|
||||
delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
|
||||
spin_lock_init(&delegation->lock);
|
||||
@@ -1047,7 +1045,7 @@ void nfs_reap_expired_delegations(struct nfs_client *clp)
|
||||
struct nfs_delegation *delegation;
|
||||
struct nfs_server *server;
|
||||
struct inode *inode;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
nfs4_stateid stateid;
|
||||
|
||||
restart:
|
||||
@@ -1069,7 +1067,7 @@ restart:
|
||||
nfs_sb_deactive(server->super);
|
||||
goto restart;
|
||||
}
|
||||
cred = get_rpccred_rcu(delegation->cred);
|
||||
cred = get_cred_rcu(delegation->cred);
|
||||
nfs4_stateid_copy(&stateid, &delegation->stateid);
|
||||
clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
|
||||
rcu_read_unlock();
|
||||
@@ -1078,7 +1076,7 @@ restart:
|
||||
nfs_revoke_delegation(inode, &stateid);
|
||||
nfs_inode_find_state_and_recover(inode, &stateid);
|
||||
}
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
if (nfs4_server_rebooted(clp)) {
|
||||
nfs_inode_mark_test_expired_delegation(server,inode);
|
||||
iput(inode);
|
||||
@@ -1173,7 +1171,7 @@ out:
|
||||
* otherwise "false" is returned.
|
||||
*/
|
||||
bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags,
|
||||
nfs4_stateid *dst, struct rpc_cred **cred)
|
||||
nfs4_stateid *dst, const struct cred **cred)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
struct nfs_delegation *delegation;
|
||||
@@ -1187,7 +1185,7 @@ bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags,
|
||||
nfs4_stateid_copy(dst, &delegation->stateid);
|
||||
nfs_mark_delegation_referenced(delegation);
|
||||
if (cred)
|
||||
*cred = get_rpccred(delegation->cred);
|
||||
*cred = get_cred(delegation->cred);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
struct nfs_delegation {
|
||||
struct list_head super_list;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
struct inode *inode;
|
||||
nfs4_stateid stateid;
|
||||
fmode_t type;
|
||||
@@ -36,9 +36,9 @@ enum {
|
||||
NFS_DELEGATION_TEST_EXPIRED,
|
||||
};
|
||||
|
||||
int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred,
|
||||
int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
|
||||
fmode_t type, const nfs4_stateid *stateid, unsigned long pagemod_limit);
|
||||
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
|
||||
void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
|
||||
fmode_t type, const nfs4_stateid *stateid, unsigned long pagemod_limit);
|
||||
int nfs4_inode_return_delegation(struct inode *inode);
|
||||
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
|
||||
@@ -60,10 +60,10 @@ void nfs_mark_test_expired_all_delegations(struct nfs_client *clp);
|
||||
void nfs_reap_expired_delegations(struct nfs_client *clp);
|
||||
|
||||
/* NFSv4 delegation-related procedures */
|
||||
int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync);
|
||||
int nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, const nfs4_stateid *stateid, int issync);
|
||||
int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid, fmode_t type);
|
||||
int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid);
|
||||
bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags, nfs4_stateid *dst, struct rpc_cred **cred);
|
||||
bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags, nfs4_stateid *dst, const struct cred **cred);
|
||||
bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode);
|
||||
|
||||
void nfs_mark_delegation_referenced(struct nfs_delegation *delegation);
|
||||
|
||||
55
fs/nfs/dir.c
55
fs/nfs/dir.c
@@ -67,7 +67,7 @@ const struct address_space_operations nfs_dir_aops = {
|
||||
.freepage = nfs_readdir_clear_array,
|
||||
};
|
||||
|
||||
static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir, struct rpc_cred *cred)
|
||||
static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir, const struct cred *cred)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(dir);
|
||||
struct nfs_open_dir_context *ctx;
|
||||
@@ -77,7 +77,7 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir
|
||||
ctx->attr_gencount = nfsi->attr_gencount;
|
||||
ctx->dir_cookie = 0;
|
||||
ctx->dup_cookie = 0;
|
||||
ctx->cred = get_rpccred(cred);
|
||||
ctx->cred = get_cred(cred);
|
||||
spin_lock(&dir->i_lock);
|
||||
list_add(&ctx->list, &nfsi->open_files);
|
||||
spin_unlock(&dir->i_lock);
|
||||
@@ -91,7 +91,7 @@ static void put_nfs_open_dir_context(struct inode *dir, struct nfs_open_dir_cont
|
||||
spin_lock(&dir->i_lock);
|
||||
list_del(&ctx->list);
|
||||
spin_unlock(&dir->i_lock);
|
||||
put_rpccred(ctx->cred);
|
||||
put_cred(ctx->cred);
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
@@ -103,23 +103,18 @@ nfs_opendir(struct inode *inode, struct file *filp)
|
||||
{
|
||||
int res = 0;
|
||||
struct nfs_open_dir_context *ctx;
|
||||
struct rpc_cred *cred;
|
||||
|
||||
dfprintk(FILE, "NFS: open dir(%pD2)\n", filp);
|
||||
|
||||
nfs_inc_stats(inode, NFSIOS_VFSOPEN);
|
||||
|
||||
cred = rpc_lookup_cred();
|
||||
if (IS_ERR(cred))
|
||||
return PTR_ERR(cred);
|
||||
ctx = alloc_nfs_open_dir_context(inode, cred);
|
||||
ctx = alloc_nfs_open_dir_context(inode, current_cred());
|
||||
if (IS_ERR(ctx)) {
|
||||
res = PTR_ERR(ctx);
|
||||
goto out;
|
||||
}
|
||||
filp->private_data = ctx;
|
||||
out:
|
||||
put_rpccred(cred);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -334,7 +329,7 @@ int nfs_readdir_xdr_filler(struct page **pages, nfs_readdir_descriptor_t *desc,
|
||||
struct nfs_entry *entry, struct file *file, struct inode *inode)
|
||||
{
|
||||
struct nfs_open_dir_context *ctx = file->private_data;
|
||||
struct rpc_cred *cred = ctx->cred;
|
||||
const struct cred *cred = ctx->cred;
|
||||
unsigned long timestamp, gencount;
|
||||
int error;
|
||||
|
||||
@@ -2139,7 +2134,7 @@ MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access maximum total cache lengt
|
||||
|
||||
static void nfs_access_free_entry(struct nfs_access_entry *entry)
|
||||
{
|
||||
put_rpccred(entry->cred);
|
||||
put_cred(entry->cred);
|
||||
kfree_rcu(entry, rcu_head);
|
||||
smp_mb__before_atomic();
|
||||
atomic_long_dec(&nfs_access_nr_entries);
|
||||
@@ -2265,17 +2260,18 @@ void nfs_access_zap_cache(struct inode *inode)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_access_zap_cache);
|
||||
|
||||
static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred)
|
||||
static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, const struct cred *cred)
|
||||
{
|
||||
struct rb_node *n = NFS_I(inode)->access_cache.rb_node;
|
||||
struct nfs_access_entry *entry;
|
||||
|
||||
while (n != NULL) {
|
||||
entry = rb_entry(n, struct nfs_access_entry, rb_node);
|
||||
struct nfs_access_entry *entry =
|
||||
rb_entry(n, struct nfs_access_entry, rb_node);
|
||||
int cmp = cred_fscmp(cred, entry->cred);
|
||||
|
||||
if (cred < entry->cred)
|
||||
if (cmp < 0)
|
||||
n = n->rb_left;
|
||||
else if (cred > entry->cred)
|
||||
else if (cmp > 0)
|
||||
n = n->rb_right;
|
||||
else
|
||||
return entry;
|
||||
@@ -2283,7 +2279,7 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, st
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res, bool may_block)
|
||||
static int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, bool may_block)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
struct nfs_access_entry *cache;
|
||||
@@ -2326,7 +2322,7 @@ out_zap:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int nfs_access_get_cached_rcu(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res)
|
||||
static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res)
|
||||
{
|
||||
/* Only check the most recently returned cache entry,
|
||||
* but do it without locking.
|
||||
@@ -2363,15 +2359,17 @@ static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *
|
||||
struct rb_node **p = &root_node->rb_node;
|
||||
struct rb_node *parent = NULL;
|
||||
struct nfs_access_entry *entry;
|
||||
int cmp;
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
while (*p != NULL) {
|
||||
parent = *p;
|
||||
entry = rb_entry(parent, struct nfs_access_entry, rb_node);
|
||||
cmp = cred_fscmp(set->cred, entry->cred);
|
||||
|
||||
if (set->cred < entry->cred)
|
||||
if (cmp < 0)
|
||||
p = &parent->rb_left;
|
||||
else if (set->cred > entry->cred)
|
||||
else if (cmp > 0)
|
||||
p = &parent->rb_right;
|
||||
else
|
||||
goto found;
|
||||
@@ -2395,7 +2393,7 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
|
||||
if (cache == NULL)
|
||||
return;
|
||||
RB_CLEAR_NODE(&cache->rb_node);
|
||||
cache->cred = get_rpccred(set->cred);
|
||||
cache->cred = get_cred(set->cred);
|
||||
cache->mask = set->mask;
|
||||
|
||||
/* The above field assignments must be visible
|
||||
@@ -2459,7 +2457,7 @@ void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_access_set_mask);
|
||||
|
||||
static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
|
||||
static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
|
||||
{
|
||||
struct nfs_access_entry cache;
|
||||
bool may_block = (mask & MAY_NOT_BLOCK) == 0;
|
||||
@@ -2523,7 +2521,7 @@ static int nfs_open_permission_mask(int openflags)
|
||||
return mask;
|
||||
}
|
||||
|
||||
int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
|
||||
int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags)
|
||||
{
|
||||
return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
|
||||
}
|
||||
@@ -2548,7 +2546,7 @@ static int nfs_execute_ok(struct inode *inode, int mask)
|
||||
|
||||
int nfs_permission(struct inode *inode, int mask)
|
||||
{
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred = current_cred();
|
||||
int res = 0;
|
||||
|
||||
nfs_inc_stats(inode, NFSIOS_VFSACCESS);
|
||||
@@ -2582,20 +2580,11 @@ force_lookup:
|
||||
|
||||
/* Always try fast lookups first */
|
||||
rcu_read_lock();
|
||||
cred = rpc_lookup_cred_nonblock();
|
||||
if (!IS_ERR(cred))
|
||||
res = nfs_do_access(inode, cred, mask|MAY_NOT_BLOCK);
|
||||
else
|
||||
res = PTR_ERR(cred);
|
||||
rcu_read_unlock();
|
||||
if (res == -ECHILD && !(mask & MAY_NOT_BLOCK)) {
|
||||
/* Fast lookup failed, try the slow way */
|
||||
cred = rpc_lookup_cred();
|
||||
if (!IS_ERR(cred)) {
|
||||
res = nfs_do_access(inode, cred, mask);
|
||||
put_rpccred(cred);
|
||||
} else
|
||||
res = PTR_ERR(cred);
|
||||
}
|
||||
out:
|
||||
if (!res && (mask & MAY_EXEC))
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/nfs_fs.h>
|
||||
#include <linux/nfs_page.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched/mm.h>
|
||||
|
||||
#include <linux/sunrpc/metrics.h>
|
||||
|
||||
@@ -27,9 +28,6 @@
|
||||
#define FF_LAYOUT_POLL_RETRY_MAX (15*HZ)
|
||||
#define FF_LAYOUTRETURN_MAXERR 20
|
||||
|
||||
|
||||
static struct group_info *ff_zero_group;
|
||||
|
||||
static void ff_layout_read_record_layoutstats_done(struct rpc_task *task,
|
||||
struct nfs_pgio_header *hdr);
|
||||
static int ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
|
||||
@@ -226,16 +224,14 @@ static struct nfs4_ff_layout_mirror *ff_layout_alloc_mirror(gfp_t gfp_flags)
|
||||
|
||||
static void ff_layout_free_mirror(struct nfs4_ff_layout_mirror *mirror)
|
||||
{
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
|
||||
ff_layout_remove_mirror(mirror);
|
||||
kfree(mirror->fh_versions);
|
||||
cred = rcu_access_pointer(mirror->ro_cred);
|
||||
if (cred)
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
cred = rcu_access_pointer(mirror->rw_cred);
|
||||
if (cred)
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
nfs4_ff_layout_put_deviceid(mirror->mirror_ds);
|
||||
kfree(mirror);
|
||||
}
|
||||
@@ -413,8 +409,10 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
|
||||
|
||||
for (i = 0; i < fls->mirror_array_cnt; i++) {
|
||||
struct nfs4_ff_layout_mirror *mirror;
|
||||
struct auth_cred acred = { .group_info = ff_zero_group };
|
||||
struct rpc_cred __rcu *cred;
|
||||
struct cred *kcred;
|
||||
const struct cred *cred;
|
||||
kuid_t uid;
|
||||
kgid_t gid;
|
||||
u32 ds_count, fh_count, id;
|
||||
int j;
|
||||
|
||||
@@ -482,21 +480,28 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
|
||||
if (rc)
|
||||
goto out_err_free;
|
||||
|
||||
acred.uid = make_kuid(&init_user_ns, id);
|
||||
uid = make_kuid(&init_user_ns, id);
|
||||
|
||||
/* group */
|
||||
rc = decode_name(&stream, &id);
|
||||
if (rc)
|
||||
goto out_err_free;
|
||||
|
||||
acred.gid = make_kgid(&init_user_ns, id);
|
||||
gid = make_kgid(&init_user_ns, id);
|
||||
|
||||
/* find the cred for it */
|
||||
rcu_assign_pointer(cred, rpc_lookup_generic_cred(&acred, 0, gfp_flags));
|
||||
if (IS_ERR(cred)) {
|
||||
rc = PTR_ERR(cred);
|
||||
goto out_err_free;
|
||||
if (gfp_flags & __GFP_FS)
|
||||
kcred = prepare_kernel_cred(NULL);
|
||||
else {
|
||||
unsigned int nofs_flags = memalloc_nofs_save();
|
||||
kcred = prepare_kernel_cred(NULL);
|
||||
memalloc_nofs_restore(nofs_flags);
|
||||
}
|
||||
rc = -ENOMEM;
|
||||
if (!kcred)
|
||||
goto out_err_free;
|
||||
kcred->fsuid = uid;
|
||||
kcred->fsgid = gid;
|
||||
cred = kcred;
|
||||
|
||||
if (lgr->range.iomode == IOMODE_READ)
|
||||
rcu_assign_pointer(fls->mirror_array[i]->ro_cred, cred);
|
||||
@@ -519,8 +524,8 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
|
||||
|
||||
dprintk("%s: iomode %s uid %u gid %u\n", __func__,
|
||||
lgr->range.iomode == IOMODE_READ ? "READ" : "RW",
|
||||
from_kuid(&init_user_ns, acred.uid),
|
||||
from_kgid(&init_user_ns, acred.gid));
|
||||
from_kuid(&init_user_ns, uid),
|
||||
from_kgid(&init_user_ns, gid));
|
||||
}
|
||||
|
||||
p = xdr_inline_decode(&stream, 4);
|
||||
@@ -1698,7 +1703,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
|
||||
struct pnfs_layout_segment *lseg = hdr->lseg;
|
||||
struct nfs4_pnfs_ds *ds;
|
||||
struct rpc_clnt *ds_clnt;
|
||||
struct rpc_cred *ds_cred;
|
||||
const struct cred *ds_cred;
|
||||
loff_t offset = hdr->args.offset;
|
||||
u32 idx = hdr->pgio_mirror_idx;
|
||||
int vers;
|
||||
@@ -1749,7 +1754,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
|
||||
vers == 3 ? &ff_layout_read_call_ops_v3 :
|
||||
&ff_layout_read_call_ops_v4,
|
||||
0, RPC_TASK_SOFTCONN);
|
||||
put_rpccred(ds_cred);
|
||||
put_cred(ds_cred);
|
||||
return PNFS_ATTEMPTED;
|
||||
|
||||
out_failed:
|
||||
@@ -1765,7 +1770,7 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
|
||||
struct pnfs_layout_segment *lseg = hdr->lseg;
|
||||
struct nfs4_pnfs_ds *ds;
|
||||
struct rpc_clnt *ds_clnt;
|
||||
struct rpc_cred *ds_cred;
|
||||
const struct cred *ds_cred;
|
||||
loff_t offset = hdr->args.offset;
|
||||
int vers;
|
||||
struct nfs_fh *fh;
|
||||
@@ -1814,7 +1819,7 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
|
||||
vers == 3 ? &ff_layout_write_call_ops_v3 :
|
||||
&ff_layout_write_call_ops_v4,
|
||||
sync, RPC_TASK_SOFTCONN);
|
||||
put_rpccred(ds_cred);
|
||||
put_cred(ds_cred);
|
||||
return PNFS_ATTEMPTED;
|
||||
|
||||
out_failed:
|
||||
@@ -1844,7 +1849,7 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
|
||||
struct pnfs_layout_segment *lseg = data->lseg;
|
||||
struct nfs4_pnfs_ds *ds;
|
||||
struct rpc_clnt *ds_clnt;
|
||||
struct rpc_cred *ds_cred;
|
||||
const struct cred *ds_cred;
|
||||
u32 idx;
|
||||
int vers, ret;
|
||||
struct nfs_fh *fh;
|
||||
@@ -1884,7 +1889,7 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
|
||||
vers == 3 ? &ff_layout_commit_call_ops_v3 :
|
||||
&ff_layout_commit_call_ops_v4,
|
||||
how, RPC_TASK_SOFTCONN);
|
||||
put_rpccred(ds_cred);
|
||||
put_cred(ds_cred);
|
||||
return ret;
|
||||
out_err:
|
||||
pnfs_generic_prepare_to_resend_writes(data);
|
||||
@@ -2383,11 +2388,6 @@ static int __init nfs4flexfilelayout_init(void)
|
||||
{
|
||||
printk(KERN_INFO "%s: NFSv4 Flexfile Layout Driver Registering...\n",
|
||||
__func__);
|
||||
if (!ff_zero_group) {
|
||||
ff_zero_group = groups_alloc(0);
|
||||
if (!ff_zero_group)
|
||||
return -ENOMEM;
|
||||
}
|
||||
return pnfs_register_layoutdriver(&flexfilelayout_type);
|
||||
}
|
||||
|
||||
@@ -2396,10 +2396,6 @@ static void __exit nfs4flexfilelayout_exit(void)
|
||||
printk(KERN_INFO "%s: NFSv4 Flexfile Layout Driver Unregistering...\n",
|
||||
__func__);
|
||||
pnfs_unregister_layoutdriver(&flexfilelayout_type);
|
||||
if (ff_zero_group) {
|
||||
put_group_info(ff_zero_group);
|
||||
ff_zero_group = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MODULE_ALIAS("nfs-layouttype4-4");
|
||||
|
||||
@@ -81,8 +81,8 @@ struct nfs4_ff_layout_mirror {
|
||||
u32 fh_versions_cnt;
|
||||
struct nfs_fh *fh_versions;
|
||||
nfs4_stateid stateid;
|
||||
struct rpc_cred __rcu *ro_cred;
|
||||
struct rpc_cred __rcu *rw_cred;
|
||||
const struct cred __rcu *ro_cred;
|
||||
const struct cred __rcu *rw_cred;
|
||||
refcount_t ref;
|
||||
spinlock_t lock;
|
||||
unsigned long flags;
|
||||
@@ -229,8 +229,8 @@ nfs4_ff_find_or_create_ds_client(struct pnfs_layout_segment *lseg,
|
||||
u32 ds_idx,
|
||||
struct nfs_client *ds_clp,
|
||||
struct inode *inode);
|
||||
struct rpc_cred *ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg,
|
||||
u32 ds_idx, struct rpc_cred *mdscred);
|
||||
const struct cred *ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg,
|
||||
u32 ds_idx, const struct cred *mdscred);
|
||||
bool ff_layout_avoid_mds_available_ds(struct pnfs_layout_segment *lseg);
|
||||
bool ff_layout_avoid_read_on_rw(struct pnfs_layout_segment *lseg);
|
||||
|
||||
|
||||
@@ -330,10 +330,10 @@ int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rpc_cred *
|
||||
static const struct cred *
|
||||
ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode)
|
||||
{
|
||||
struct rpc_cred *cred, __rcu **pcred;
|
||||
const struct cred *cred, __rcu **pcred;
|
||||
|
||||
if (iomode == IOMODE_READ)
|
||||
pcred = &mirror->ro_cred;
|
||||
@@ -346,7 +346,7 @@ ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode)
|
||||
if (!cred)
|
||||
break;
|
||||
|
||||
cred = get_rpccred_rcu(cred);
|
||||
cred = get_cred_rcu(cred);
|
||||
} while(!cred);
|
||||
rcu_read_unlock();
|
||||
return cred;
|
||||
@@ -465,19 +465,19 @@ out:
|
||||
return ds;
|
||||
}
|
||||
|
||||
struct rpc_cred *
|
||||
const struct cred *
|
||||
ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg, u32 ds_idx,
|
||||
struct rpc_cred *mdscred)
|
||||
const struct cred *mdscred)
|
||||
{
|
||||
struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
|
||||
if (mirror && !mirror->mirror_ds->ds_versions[0].tightly_coupled) {
|
||||
cred = ff_layout_get_mirror_cred(mirror, lseg->pls_range.iomode);
|
||||
if (!cred)
|
||||
cred = get_rpccred(mdscred);
|
||||
cred = get_cred(mdscred);
|
||||
} else {
|
||||
cred = get_rpccred(mdscred);
|
||||
cred = get_cred(mdscred);
|
||||
}
|
||||
return cred;
|
||||
}
|
||||
|
||||
@@ -950,18 +950,17 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,
|
||||
struct file *filp)
|
||||
{
|
||||
struct nfs_open_context *ctx;
|
||||
struct rpc_cred *cred = rpc_lookup_cred();
|
||||
if (IS_ERR(cred))
|
||||
return ERR_CAST(cred);
|
||||
const struct cred *cred = get_current_cred();
|
||||
|
||||
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx) {
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
nfs_sb_active(dentry->d_sb);
|
||||
ctx->dentry = dget(dentry);
|
||||
ctx->cred = cred;
|
||||
ctx->ll_cred = NULL;
|
||||
ctx->state = NULL;
|
||||
ctx->mode = f_mode;
|
||||
ctx->flags = 0;
|
||||
@@ -997,10 +996,10 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
|
||||
}
|
||||
if (inode != NULL)
|
||||
NFS_PROTO(inode)->close_context(ctx, is_sync);
|
||||
if (ctx->cred != NULL)
|
||||
put_rpccred(ctx->cred);
|
||||
put_cred(ctx->cred);
|
||||
dput(ctx->dentry);
|
||||
nfs_sb_deactive(sb);
|
||||
put_rpccred(ctx->ll_cred);
|
||||
kfree(ctx->mdsthreshold);
|
||||
kfree_rcu(ctx, rcu_head);
|
||||
}
|
||||
@@ -1042,7 +1041,7 @@ EXPORT_SYMBOL_GPL(nfs_file_set_open_context);
|
||||
/*
|
||||
* Given an inode, search for an open context with the desired characteristics
|
||||
*/
|
||||
struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode)
|
||||
struct nfs_open_context *nfs_find_open_context(struct inode *inode, const struct cred *cred, fmode_t mode)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
struct nfs_open_context *pos, *ctx = NULL;
|
||||
|
||||
@@ -254,7 +254,7 @@ struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *);
|
||||
void nfs_pgio_header_free(struct nfs_pgio_header *);
|
||||
int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
|
||||
int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
|
||||
struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops,
|
||||
const struct cred *cred, const struct nfs_rpc_ops *rpc_ops,
|
||||
const struct rpc_call_ops *call_ops, int how, int flags);
|
||||
void nfs_free_request(struct nfs_page *req);
|
||||
struct nfs_pgio_mirror *
|
||||
@@ -269,7 +269,7 @@ static inline bool nfs_pgio_has_mirroring(struct nfs_pageio_descriptor *desc)
|
||||
static inline bool nfs_match_open_context(const struct nfs_open_context *ctx1,
|
||||
const struct nfs_open_context *ctx2)
|
||||
{
|
||||
return ctx1->cred == ctx2->cred && ctx1->state == ctx2->state;
|
||||
return cred_fscmp(ctx1->cred, ctx2->cred) == 0 && ctx1->state == ctx2->state;
|
||||
}
|
||||
|
||||
/* nfs2xdr.c */
|
||||
@@ -395,7 +395,6 @@ extern const struct super_operations nfs_sops;
|
||||
extern struct file_system_type nfs_fs_type;
|
||||
extern struct file_system_type nfs_xdev_fs_type;
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
extern struct file_system_type nfs4_xdev_fs_type;
|
||||
extern struct file_system_type nfs4_referral_fs_type;
|
||||
#endif
|
||||
bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t);
|
||||
@@ -565,13 +564,13 @@ extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
|
||||
const struct nfs_client_initdata *);
|
||||
extern int nfs40_walk_client_list(struct nfs_client *clp,
|
||||
struct nfs_client **result,
|
||||
struct rpc_cred *cred);
|
||||
const struct cred *cred);
|
||||
extern int nfs41_walk_client_list(struct nfs_client *clp,
|
||||
struct nfs_client **result,
|
||||
struct rpc_cred *cred);
|
||||
extern int nfs4_test_session_trunk(struct rpc_clnt *,
|
||||
struct rpc_xprt *,
|
||||
void *);
|
||||
const struct cred *cred);
|
||||
extern void nfs4_test_session_trunk(struct rpc_clnt *clnt,
|
||||
struct rpc_xprt *xprt,
|
||||
void *data);
|
||||
|
||||
static inline struct inode *nfs_igrab_and_active(struct inode *inode)
|
||||
{
|
||||
|
||||
@@ -607,7 +607,7 @@ out:
|
||||
* readdirplus.
|
||||
*/
|
||||
static int
|
||||
nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
|
||||
nfs3_proc_readdir(struct dentry *dentry, const struct cred *cred,
|
||||
u64 cookie, struct page **pages, unsigned int count, bool plus)
|
||||
{
|
||||
struct inode *dir = d_inode(dentry);
|
||||
@@ -628,7 +628,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
|
||||
.rpc_proc = &nfs3_procedures[NFS3PROC_READDIR],
|
||||
.rpc_argp = &arg,
|
||||
.rpc_resp = &res,
|
||||
.rpc_cred = cred
|
||||
.rpc_cred = cred,
|
||||
};
|
||||
int status = -ENOMEM;
|
||||
|
||||
|
||||
@@ -62,10 +62,11 @@ struct nfs4_minor_version_ops {
|
||||
void (*free_lock_state)(struct nfs_server *,
|
||||
struct nfs4_lock_state *);
|
||||
int (*test_and_free_expired)(struct nfs_server *,
|
||||
nfs4_stateid *, struct rpc_cred *);
|
||||
nfs4_stateid *, const struct cred *);
|
||||
struct nfs_seqid *
|
||||
(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t);
|
||||
int (*session_trunk)(struct rpc_clnt *, struct rpc_xprt *, void *);
|
||||
void (*session_trunk)(struct rpc_clnt *clnt,
|
||||
struct rpc_xprt *xprt, void *data);
|
||||
const struct rpc_call_ops *call_sync_ops;
|
||||
const struct nfs4_state_recovery_ops *reboot_recovery_ops;
|
||||
const struct nfs4_state_recovery_ops *nograce_recovery_ops;
|
||||
@@ -107,7 +108,7 @@ struct nfs4_state_owner {
|
||||
unsigned long so_expires;
|
||||
struct rb_node so_server_node;
|
||||
|
||||
struct rpc_cred *so_cred; /* Associated cred */
|
||||
const struct cred *so_cred; /* Associated cred */
|
||||
|
||||
spinlock_t so_lock;
|
||||
atomic_t so_count;
|
||||
@@ -212,10 +213,10 @@ struct nfs4_state_recovery_ops {
|
||||
int state_flag_bit;
|
||||
int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
|
||||
int (*recover_lock)(struct nfs4_state *, struct file_lock *);
|
||||
int (*establish_clid)(struct nfs_client *, struct rpc_cred *);
|
||||
int (*reclaim_complete)(struct nfs_client *, struct rpc_cred *);
|
||||
int (*establish_clid)(struct nfs_client *, const struct cred *);
|
||||
int (*reclaim_complete)(struct nfs_client *, const struct cred *);
|
||||
int (*detect_trunking)(struct nfs_client *, struct nfs_client **,
|
||||
struct rpc_cred *);
|
||||
const struct cred *);
|
||||
};
|
||||
|
||||
struct nfs4_opendata {
|
||||
@@ -245,19 +246,19 @@ struct nfs4_opendata {
|
||||
|
||||
struct nfs4_add_xprt_data {
|
||||
struct nfs_client *clp;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
};
|
||||
|
||||
struct nfs4_state_maintenance_ops {
|
||||
int (*sched_state_renewal)(struct nfs_client *, struct rpc_cred *, unsigned);
|
||||
struct rpc_cred * (*get_state_renewal_cred_locked)(struct nfs_client *);
|
||||
int (*renew_lease)(struct nfs_client *, struct rpc_cred *);
|
||||
int (*sched_state_renewal)(struct nfs_client *, const struct cred *, unsigned);
|
||||
const struct cred * (*get_state_renewal_cred)(struct nfs_client *);
|
||||
int (*renew_lease)(struct nfs_client *, const struct cred *);
|
||||
};
|
||||
|
||||
struct nfs4_mig_recovery_ops {
|
||||
int (*get_locations)(struct inode *, struct nfs4_fs_locations *,
|
||||
struct page *, struct rpc_cred *);
|
||||
int (*fsid_present)(struct inode *, struct rpc_cred *);
|
||||
struct page *, const struct cred *);
|
||||
int (*fsid_present)(struct inode *, const struct cred *);
|
||||
};
|
||||
|
||||
extern const struct dentry_operations nfs4_dentry_operations;
|
||||
@@ -286,21 +287,21 @@ extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *,
|
||||
struct rpc_message *, struct nfs4_sequence_args *,
|
||||
struct nfs4_sequence_res *, int);
|
||||
extern void nfs4_init_sequence(struct nfs4_sequence_args *, struct nfs4_sequence_res *, int, int);
|
||||
extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
|
||||
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
|
||||
extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, const struct cred *, struct nfs4_setclientid_res *);
|
||||
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, const struct cred *);
|
||||
extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *, bool);
|
||||
extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, struct rpc_cred *cred);
|
||||
extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
|
||||
extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, const struct cred *cred);
|
||||
extern int nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred);
|
||||
extern int nfs4_destroy_clientid(struct nfs_client *clp);
|
||||
extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
|
||||
extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
|
||||
extern int nfs4_init_clientid(struct nfs_client *, const struct cred *);
|
||||
extern int nfs41_init_clientid(struct nfs_client *, const struct cred *);
|
||||
extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait);
|
||||
extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
|
||||
extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *,
|
||||
struct nfs4_fs_locations *, struct page *);
|
||||
extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *,
|
||||
struct page *page, struct rpc_cred *);
|
||||
extern int nfs4_proc_fsid_present(struct inode *, struct rpc_cred *);
|
||||
struct page *page, const struct cred *);
|
||||
extern int nfs4_proc_fsid_present(struct inode *, const struct cred *);
|
||||
extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, const struct qstr *,
|
||||
struct nfs_fh *, struct nfs_fattr *);
|
||||
extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
|
||||
@@ -312,8 +313,8 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
|
||||
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
extern int nfs41_sequence_done(struct rpc_task *, struct nfs4_sequence_res *);
|
||||
extern int nfs4_proc_create_session(struct nfs_client *, struct rpc_cred *);
|
||||
extern int nfs4_proc_destroy_session(struct nfs4_session *, struct rpc_cred *);
|
||||
extern int nfs4_proc_create_session(struct nfs_client *, const struct cred *);
|
||||
extern int nfs4_proc_destroy_session(struct nfs4_session *, const struct cred *);
|
||||
extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
|
||||
struct nfs_fsinfo *fsinfo);
|
||||
extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data,
|
||||
@@ -338,7 +339,6 @@ static inline bool
|
||||
_nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
|
||||
struct rpc_clnt **clntp, struct rpc_message *msg)
|
||||
{
|
||||
struct rpc_cred *newcred = NULL;
|
||||
rpc_authflavor_t flavor;
|
||||
|
||||
if (sp4_mode == NFS_SP4_MACH_CRED_CLEANUP ||
|
||||
@@ -353,13 +353,7 @@ _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
|
||||
return false;
|
||||
}
|
||||
if (test_bit(sp4_mode, &clp->cl_sp4_flags)) {
|
||||
spin_lock(&clp->cl_lock);
|
||||
if (clp->cl_machine_cred != NULL)
|
||||
/* don't call get_rpccred on the machine cred -
|
||||
* a reference will be held for life of clp */
|
||||
newcred = clp->cl_machine_cred;
|
||||
spin_unlock(&clp->cl_lock);
|
||||
msg->rpc_cred = newcred;
|
||||
msg->rpc_cred = rpc_machine_cred();
|
||||
|
||||
flavor = clp->cl_rpcclient->cl_auth->au_flavor;
|
||||
WARN_ON_ONCE(flavor != RPC_AUTH_GSS_KRB5I &&
|
||||
@@ -450,16 +444,16 @@ extern void nfs4_set_lease_period(struct nfs_client *clp,
|
||||
|
||||
|
||||
/* nfs4state.c */
|
||||
struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp);
|
||||
struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
|
||||
struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp);
|
||||
const struct cred *nfs4_get_clid_cred(struct nfs_client *clp);
|
||||
const struct cred *nfs4_get_machine_cred(struct nfs_client *clp);
|
||||
const struct cred *nfs4_get_renew_cred(struct nfs_client *clp);
|
||||
int nfs4_discover_server_trunking(struct nfs_client *clp,
|
||||
struct nfs_client **);
|
||||
int nfs40_discover_server_trunking(struct nfs_client *clp,
|
||||
struct nfs_client **, struct rpc_cred *);
|
||||
struct nfs_client **, const struct cred *);
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
int nfs41_discover_server_trunking(struct nfs_client *clp,
|
||||
struct nfs_client **, struct rpc_cred *);
|
||||
struct nfs_client **, const struct cred *);
|
||||
extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
|
||||
extern void nfs41_notify_server(struct nfs_client *);
|
||||
#else
|
||||
@@ -468,7 +462,7 @@ static inline void nfs4_schedule_session_recovery(struct nfs4_session *session,
|
||||
}
|
||||
#endif /* CONFIG_NFS_V4_1 */
|
||||
|
||||
extern struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *, gfp_t);
|
||||
extern struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *, const struct cred *, gfp_t);
|
||||
extern void nfs4_put_state_owner(struct nfs4_state_owner *);
|
||||
extern void nfs4_purge_state_owners(struct nfs_server *);
|
||||
extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
|
||||
@@ -494,7 +488,7 @@ extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
|
||||
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
|
||||
extern int nfs4_select_rw_stateid(struct nfs4_state *, fmode_t,
|
||||
const struct nfs_lock_context *, nfs4_stateid *,
|
||||
struct rpc_cred **);
|
||||
const struct cred **);
|
||||
extern bool nfs4_refresh_open_stateid(nfs4_stateid *dst,
|
||||
struct nfs4_state *state);
|
||||
extern bool nfs4_copy_open_stateid(nfs4_stateid *dst,
|
||||
|
||||
@@ -545,7 +545,7 @@ static int nfs4_match_client(struct nfs_client *pos, struct nfs_client *new,
|
||||
*/
|
||||
int nfs40_walk_client_list(struct nfs_client *new,
|
||||
struct nfs_client **result,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
|
||||
struct nfs_client *pos, *prev = NULL;
|
||||
@@ -711,7 +711,7 @@ out_err:
|
||||
*/
|
||||
int nfs41_walk_client_list(struct nfs_client *new,
|
||||
struct nfs_client **result,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
|
||||
struct nfs_client *pos, *prev = NULL;
|
||||
|
||||
@@ -93,19 +93,19 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf
|
||||
static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
|
||||
static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label, struct inode *inode);
|
||||
static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode);
|
||||
static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
|
||||
static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
|
||||
struct nfs_fattr *fattr, struct iattr *sattr,
|
||||
struct nfs_open_context *ctx, struct nfs4_label *ilabel,
|
||||
struct nfs4_label *olabel);
|
||||
#ifdef CONFIG_NFS_V4_1
|
||||
static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
|
||||
struct rpc_cred *cred,
|
||||
const struct cred *cred,
|
||||
struct nfs4_slot *slot,
|
||||
bool is_privileged);
|
||||
static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *,
|
||||
struct rpc_cred *);
|
||||
const struct cred *);
|
||||
static int nfs41_free_stateid(struct nfs_server *, const nfs4_stateid *,
|
||||
struct rpc_cred *, bool);
|
||||
const struct cred *, bool);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
|
||||
@@ -361,7 +361,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
|
||||
|
||||
static void nfs4_test_and_free_stateid(struct nfs_server *server,
|
||||
nfs4_stateid *stateid,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
const struct nfs4_minor_version_ops *ops = server->nfs_client->cl_mvops;
|
||||
|
||||
@@ -370,7 +370,7 @@ static void nfs4_test_and_free_stateid(struct nfs_server *server,
|
||||
|
||||
static void __nfs4_free_revoked_stateid(struct nfs_server *server,
|
||||
nfs4_stateid *stateid,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
stateid->type = NFS4_REVOKED_STATEID_TYPE;
|
||||
nfs4_test_and_free_stateid(server, stateid, cred);
|
||||
@@ -378,7 +378,7 @@ static void __nfs4_free_revoked_stateid(struct nfs_server *server,
|
||||
|
||||
static void nfs4_free_revoked_stateid(struct nfs_server *server,
|
||||
const nfs4_stateid *stateid,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
nfs4_stateid tmp;
|
||||
|
||||
@@ -908,7 +908,7 @@ static const struct rpc_call_ops nfs41_call_sync_ops = {
|
||||
|
||||
static void
|
||||
nfs4_sequence_process_interrupted(struct nfs_client *client,
|
||||
struct nfs4_slot *slot, struct rpc_cred *cred)
|
||||
struct nfs4_slot *slot, const struct cred *cred)
|
||||
{
|
||||
struct rpc_task *task;
|
||||
|
||||
@@ -939,7 +939,7 @@ EXPORT_SYMBOL_GPL(nfs4_sequence_done);
|
||||
|
||||
static void
|
||||
nfs4_sequence_process_interrupted(struct nfs_client *client,
|
||||
struct nfs4_slot *slot, struct rpc_cred *cred)
|
||||
struct nfs4_slot *slot, const struct cred *cred)
|
||||
{
|
||||
WARN_ON_ONCE(1);
|
||||
slot->interrupted = 0;
|
||||
@@ -2484,7 +2484,7 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
|
||||
* Note that in the non-execute case, we want to turn off permission
|
||||
* checking if we just created a new file (POSIX open() semantics).
|
||||
*/
|
||||
static int nfs4_opendata_access(struct rpc_cred *cred,
|
||||
static int nfs4_opendata_access(const struct cred *cred,
|
||||
struct nfs4_opendata *opendata,
|
||||
struct nfs4_state *state, fmode_t fmode,
|
||||
int openflags)
|
||||
@@ -2651,7 +2651,7 @@ static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
|
||||
|
||||
static int nfs40_test_and_free_expired_stateid(struct nfs_server *server,
|
||||
nfs4_stateid *stateid,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
return -NFS4ERR_BAD_STATEID;
|
||||
}
|
||||
@@ -2659,7 +2659,7 @@ static int nfs40_test_and_free_expired_stateid(struct nfs_server *server,
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
static int nfs41_test_and_free_expired_stateid(struct nfs_server *server,
|
||||
nfs4_stateid *stateid,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -2693,7 +2693,7 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state)
|
||||
struct nfs_server *server = NFS_SERVER(state->inode);
|
||||
nfs4_stateid stateid;
|
||||
struct nfs_delegation *delegation;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred = NULL;
|
||||
int status;
|
||||
|
||||
/* Get the delegation credential for use by test/free_stateid */
|
||||
@@ -2718,14 +2718,16 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state)
|
||||
return;
|
||||
}
|
||||
|
||||
cred = get_rpccred(delegation->cred);
|
||||
if (delegation->cred)
|
||||
cred = get_cred(delegation->cred);
|
||||
rcu_read_unlock();
|
||||
status = nfs41_test_and_free_expired_stateid(server, &stateid, cred);
|
||||
trace_nfs4_test_delegation_stateid(state, NULL, status);
|
||||
if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID)
|
||||
nfs_finish_clear_delegation_stateid(state, &stateid);
|
||||
|
||||
put_rpccred(cred);
|
||||
if (delegation->cred)
|
||||
put_cred(cred);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2748,7 +2750,7 @@ static int nfs41_check_expired_locks(struct nfs4_state *state)
|
||||
spin_lock(&state->state_lock);
|
||||
list_for_each_entry(lsp, &state->lock_states, ls_locks) {
|
||||
if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
|
||||
struct rpc_cred *cred = lsp->ls_state->owner->so_cred;
|
||||
const struct cred *cred = lsp->ls_state->owner->so_cred;
|
||||
|
||||
refcount_inc(&lsp->ls_count);
|
||||
spin_unlock(&state->state_lock);
|
||||
@@ -2792,7 +2794,7 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(state->inode);
|
||||
nfs4_stateid *stateid = &state->open_stateid;
|
||||
struct rpc_cred *cred = state->owner->so_cred;
|
||||
const struct cred *cred = state->owner->so_cred;
|
||||
int status;
|
||||
|
||||
if (test_bit(NFS_OPEN_STATE, &state->flags) == 0) {
|
||||
@@ -2950,7 +2952,7 @@ static int _nfs4_do_open(struct inode *dir,
|
||||
struct nfs_server *server = NFS_SERVER(dir);
|
||||
struct nfs4_opendata *opendata;
|
||||
struct dentry *dentry = ctx->dentry;
|
||||
struct rpc_cred *cred = ctx->cred;
|
||||
const struct cred *cred = ctx->cred;
|
||||
struct nfs4_threshold **ctx_th = &ctx->mdsthreshold;
|
||||
fmode_t fmode = ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC);
|
||||
enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
|
||||
@@ -3120,7 +3122,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
|
||||
static int _nfs4_do_setattr(struct inode *inode,
|
||||
struct nfs_setattrargs *arg,
|
||||
struct nfs_setattrres *res,
|
||||
struct rpc_cred *cred,
|
||||
const struct cred *cred,
|
||||
struct nfs_open_context *ctx)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
@@ -3130,7 +3132,7 @@ static int _nfs4_do_setattr(struct inode *inode,
|
||||
.rpc_resp = res,
|
||||
.rpc_cred = cred,
|
||||
};
|
||||
struct rpc_cred *delegation_cred = NULL;
|
||||
const struct cred *delegation_cred = NULL;
|
||||
unsigned long timestamp = jiffies;
|
||||
bool truncate;
|
||||
int status;
|
||||
@@ -3165,14 +3167,14 @@ zero_stateid:
|
||||
|
||||
status = nfs4_call_sync(server->client, server, &msg, &arg->seq_args, &res->seq_res, 1);
|
||||
|
||||
put_rpccred(delegation_cred);
|
||||
put_cred(delegation_cred);
|
||||
if (status == 0 && ctx != NULL)
|
||||
renew_lease(server, timestamp);
|
||||
trace_nfs4_setattr(inode, &arg->stateid, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
|
||||
static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
|
||||
struct nfs_fattr *fattr, struct iattr *sattr,
|
||||
struct nfs_open_context *ctx, struct nfs4_label *ilabel,
|
||||
struct nfs4_label *olabel)
|
||||
@@ -3973,7 +3975,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
|
||||
struct iattr *sattr)
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct rpc_cred *cred = NULL;
|
||||
const struct cred *cred = NULL;
|
||||
struct nfs_open_context *ctx = NULL;
|
||||
struct nfs4_label *label = NULL;
|
||||
int status;
|
||||
@@ -4202,7 +4204,6 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
|
||||
return -ENOMEM;
|
||||
args.bitmask = server->cache_consistency_bitmask;
|
||||
}
|
||||
|
||||
status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
|
||||
if (!status) {
|
||||
nfs_access_set_mask(entry, res.access);
|
||||
@@ -4691,7 +4692,7 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
|
||||
static int _nfs4_proc_readdir(struct dentry *dentry, const struct cred *cred,
|
||||
u64 cookie, struct page **pages, unsigned int count, bool plus)
|
||||
{
|
||||
struct inode *dir = d_inode(dentry);
|
||||
@@ -4729,7 +4730,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
|
||||
return status;
|
||||
}
|
||||
|
||||
static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
|
||||
static int nfs4_proc_readdir(struct dentry *dentry, const struct cred *cred,
|
||||
u64 cookie, struct page **pages, unsigned int count, bool plus)
|
||||
{
|
||||
struct nfs4_exception exception = { };
|
||||
@@ -5257,7 +5258,7 @@ static const struct rpc_call_ops nfs4_renew_ops = {
|
||||
.rpc_release = nfs4_renew_release,
|
||||
};
|
||||
|
||||
static int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred, unsigned renew_flags)
|
||||
static int nfs4_proc_async_renew(struct nfs_client *clp, const struct cred *cred, unsigned renew_flags)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
|
||||
@@ -5281,7 +5282,7 @@ static int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred,
|
||||
&nfs4_renew_ops, data);
|
||||
}
|
||||
|
||||
static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
static int nfs4_proc_renew(struct nfs_client *clp, const struct cred *cred)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
|
||||
@@ -5696,7 +5697,6 @@ nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
|
||||
{
|
||||
struct nfs4_label ilabel, *olabel = NULL;
|
||||
struct nfs_fattr fattr;
|
||||
struct rpc_cred *cred;
|
||||
int status;
|
||||
|
||||
if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
|
||||
@@ -5709,10 +5709,6 @@ nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
|
||||
ilabel.label = (char *)buf;
|
||||
ilabel.len = buflen;
|
||||
|
||||
cred = rpc_lookup_cred();
|
||||
if (IS_ERR(cred))
|
||||
return PTR_ERR(cred);
|
||||
|
||||
olabel = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
|
||||
if (IS_ERR(olabel)) {
|
||||
status = -PTR_ERR(olabel);
|
||||
@@ -5725,7 +5721,6 @@ nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
|
||||
|
||||
nfs4_label_free(olabel);
|
||||
out:
|
||||
put_rpccred(cred);
|
||||
return status;
|
||||
}
|
||||
#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
|
||||
@@ -5894,13 +5889,13 @@ static const struct rpc_call_ops nfs4_setclientid_ops = {
|
||||
* @clp: state data structure
|
||||
* @program: RPC program for NFSv4 callback service
|
||||
* @port: IP port number for NFS4 callback service
|
||||
* @cred: RPC credential to use for this call
|
||||
* @cred: credential to use for this call
|
||||
* @res: where to place the result
|
||||
*
|
||||
* Returns zero, a negative errno, or a negative NFS4ERR status code.
|
||||
*/
|
||||
int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
|
||||
unsigned short port, struct rpc_cred *cred,
|
||||
unsigned short port, const struct cred *cred,
|
||||
struct nfs4_setclientid_res *res)
|
||||
{
|
||||
nfs4_verifier sc_verifier;
|
||||
@@ -5969,13 +5964,13 @@ out:
|
||||
* nfs4_proc_setclientid_confirm - Confirm client ID
|
||||
* @clp: state data structure
|
||||
* @res: result of a previous SETCLIENTID
|
||||
* @cred: RPC credential to use for this call
|
||||
* @cred: credential to use for this call
|
||||
*
|
||||
* Returns zero, a negative errno, or a negative NFS4ERR status code.
|
||||
*/
|
||||
int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
|
||||
struct nfs4_setclientid_res *arg,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
|
||||
@@ -6138,7 +6133,7 @@ static const struct rpc_call_ops nfs4_delegreturn_ops = {
|
||||
.rpc_release = nfs4_delegreturn_release,
|
||||
};
|
||||
|
||||
static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
|
||||
static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, const nfs4_stateid *stateid, int issync)
|
||||
{
|
||||
struct nfs4_delegreturndata *data;
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
@@ -6205,7 +6200,7 @@ out:
|
||||
return status;
|
||||
}
|
||||
|
||||
int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
|
||||
int nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, const nfs4_stateid *stateid, int issync)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct nfs4_exception exception = { };
|
||||
@@ -7268,7 +7263,7 @@ int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
|
||||
*/
|
||||
static int _nfs40_proc_get_locations(struct inode *inode,
|
||||
struct nfs4_fs_locations *locations,
|
||||
struct page *page, struct rpc_cred *cred)
|
||||
struct page *page, const struct cred *cred)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct rpc_clnt *clnt = server->client;
|
||||
@@ -7325,7 +7320,7 @@ static int _nfs40_proc_get_locations(struct inode *inode,
|
||||
*/
|
||||
static int _nfs41_proc_get_locations(struct inode *inode,
|
||||
struct nfs4_fs_locations *locations,
|
||||
struct page *page, struct rpc_cred *cred)
|
||||
struct page *page, const struct cred *cred)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct rpc_clnt *clnt = server->client;
|
||||
@@ -7384,7 +7379,7 @@ static int _nfs41_proc_get_locations(struct inode *inode,
|
||||
*/
|
||||
int nfs4_proc_get_locations(struct inode *inode,
|
||||
struct nfs4_fs_locations *locations,
|
||||
struct page *page, struct rpc_cred *cred)
|
||||
struct page *page, const struct cred *cred)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
@@ -7415,7 +7410,7 @@ int nfs4_proc_get_locations(struct inode *inode,
|
||||
* is appended to this compound to identify the client ID which is
|
||||
* performing recovery.
|
||||
*/
|
||||
static int _nfs40_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
|
||||
static int _nfs40_proc_fsid_present(struct inode *inode, const struct cred *cred)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
|
||||
@@ -7461,7 +7456,7 @@ static int _nfs40_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
|
||||
* this operation is identified in the SEQUENCE operation in this
|
||||
* compound.
|
||||
*/
|
||||
static int _nfs41_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
|
||||
static int _nfs41_proc_fsid_present(struct inode *inode, const struct cred *cred)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct rpc_clnt *clnt = server->client;
|
||||
@@ -7508,7 +7503,7 @@ static int _nfs41_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
|
||||
* NFS4ERR code if some error occurred on the server, or a
|
||||
* negative errno if a local failure occurred.
|
||||
*/
|
||||
int nfs4_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
|
||||
int nfs4_proc_fsid_present(struct inode *inode, const struct cred *cred)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
@@ -7555,7 +7550,7 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
|
||||
.rpc_resp = &res,
|
||||
};
|
||||
struct rpc_clnt *clnt = NFS_SERVER(dir)->client;
|
||||
struct rpc_cred *cred = NULL;
|
||||
const struct cred *cred = NULL;
|
||||
|
||||
if (use_integrity) {
|
||||
clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient;
|
||||
@@ -7572,8 +7567,7 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
|
||||
&res.seq_res, 0);
|
||||
dprintk("NFS reply secinfo: %d\n", status);
|
||||
|
||||
if (cred)
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -7654,7 +7648,7 @@ static
|
||||
int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt,
|
||||
struct rpc_xprt *xprt,
|
||||
struct nfs_client *clp,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
int status;
|
||||
struct nfs41_bind_conn_to_session_args args = {
|
||||
@@ -7716,7 +7710,7 @@ int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt,
|
||||
|
||||
struct rpc_bind_conn_calldata {
|
||||
struct nfs_client *clp;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -7729,7 +7723,7 @@ nfs4_proc_bind_conn_to_session_callback(struct rpc_clnt *clnt,
|
||||
return nfs4_proc_bind_one_conn_to_session(clnt, xprt, p->clp, p->cred);
|
||||
}
|
||||
|
||||
int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, const struct cred *cred)
|
||||
{
|
||||
struct rpc_bind_conn_calldata data = {
|
||||
.clp = clp,
|
||||
@@ -7895,7 +7889,7 @@ static const struct rpc_call_ops nfs4_exchange_id_call_ops = {
|
||||
* Wrapper for EXCHANGE_ID operation.
|
||||
*/
|
||||
static struct rpc_task *
|
||||
nfs4_run_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
||||
nfs4_run_exchange_id(struct nfs_client *clp, const struct cred *cred,
|
||||
u32 sp4_how, struct rpc_xprt *xprt)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
@@ -7991,7 +7985,7 @@ out:
|
||||
*
|
||||
* Wrapper for EXCHANGE_ID operation.
|
||||
*/
|
||||
static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
||||
static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred,
|
||||
u32 sp4_how)
|
||||
{
|
||||
struct rpc_task *task;
|
||||
@@ -8058,7 +8052,7 @@ out:
|
||||
*
|
||||
* Will attempt to negotiate SP4_MACH_CRED if krb5i / krb5p auth is used.
|
||||
*/
|
||||
int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
int nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred)
|
||||
{
|
||||
rpc_authflavor_t authflavor = clp->cl_rpcclient->cl_auth->au_flavor;
|
||||
int status;
|
||||
@@ -8090,7 +8084,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
* @xprt: the rpc_xprt to test
|
||||
* @data: call data for _nfs4_proc_exchange_id.
|
||||
*/
|
||||
int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
|
||||
void nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
|
||||
void *data)
|
||||
{
|
||||
struct nfs4_add_xprt_data *adata = (struct nfs4_add_xprt_data *)data;
|
||||
@@ -8107,20 +8101,22 @@ int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
|
||||
/* Test connection for session trunking. Async exchange_id call */
|
||||
task = nfs4_run_exchange_id(adata->clp, adata->cred, sp4_how, xprt);
|
||||
if (IS_ERR(task))
|
||||
return PTR_ERR(task);
|
||||
return;
|
||||
|
||||
status = task->tk_status;
|
||||
if (status == 0)
|
||||
status = nfs4_detect_session_trunking(adata->clp,
|
||||
task->tk_msg.rpc_resp, xprt);
|
||||
|
||||
if (status == 0)
|
||||
rpc_clnt_xprt_switch_add_xprt(clnt, xprt);
|
||||
|
||||
rpc_put_task(task);
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs4_test_session_trunk);
|
||||
|
||||
static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_CLIENTID],
|
||||
@@ -8138,7 +8134,7 @@ static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
|
||||
}
|
||||
|
||||
static int nfs4_proc_destroy_clientid(struct nfs_client *clp,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
unsigned int loop;
|
||||
int ret;
|
||||
@@ -8159,7 +8155,7 @@ static int nfs4_proc_destroy_clientid(struct nfs_client *clp,
|
||||
|
||||
int nfs4_destroy_clientid(struct nfs_client *clp)
|
||||
{
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
int ret = 0;
|
||||
|
||||
if (clp->cl_mvops->minor_version < 1)
|
||||
@@ -8170,8 +8166,7 @@ int nfs4_destroy_clientid(struct nfs_client *clp)
|
||||
goto out;
|
||||
cred = nfs4_get_clid_cred(clp);
|
||||
ret = nfs4_proc_destroy_clientid(clp, cred);
|
||||
if (cred)
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
switch (ret) {
|
||||
case 0:
|
||||
case -NFS4ERR_STALE_CLIENTID:
|
||||
@@ -8387,7 +8382,7 @@ static void nfs4_update_session(struct nfs4_session *session,
|
||||
}
|
||||
|
||||
static int _nfs4_proc_create_session(struct nfs_client *clp,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs4_session *session = clp->cl_session;
|
||||
struct nfs41_create_session_args args = {
|
||||
@@ -8439,7 +8434,7 @@ out:
|
||||
* It is the responsibility of the caller to verify the session is
|
||||
* expired before calling this routine.
|
||||
*/
|
||||
int nfs4_proc_create_session(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
int nfs4_proc_create_session(struct nfs_client *clp, const struct cred *cred)
|
||||
{
|
||||
int status;
|
||||
unsigned *ptr;
|
||||
@@ -8470,7 +8465,7 @@ out:
|
||||
* The caller must serialize access to this routine.
|
||||
*/
|
||||
int nfs4_proc_destroy_session(struct nfs4_session *session,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_SESSION],
|
||||
@@ -8572,7 +8567,7 @@ static const struct rpc_call_ops nfs41_sequence_ops = {
|
||||
};
|
||||
|
||||
static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
|
||||
struct rpc_cred *cred,
|
||||
const struct cred *cred,
|
||||
struct nfs4_slot *slot,
|
||||
bool is_privileged)
|
||||
{
|
||||
@@ -8615,7 +8610,7 @@ out_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cred, unsigned renew_flags)
|
||||
static int nfs41_proc_async_sequence(struct nfs_client *clp, const struct cred *cred, unsigned renew_flags)
|
||||
{
|
||||
struct rpc_task *task;
|
||||
int ret = 0;
|
||||
@@ -8631,7 +8626,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
static int nfs4_proc_sequence(struct nfs_client *clp, const struct cred *cred)
|
||||
{
|
||||
struct rpc_task *task;
|
||||
int ret;
|
||||
@@ -8727,7 +8722,7 @@ static const struct rpc_call_ops nfs4_reclaim_complete_call_ops = {
|
||||
* Issue a global reclaim complete.
|
||||
*/
|
||||
static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs4_reclaim_complete_data *calldata;
|
||||
struct rpc_task *task;
|
||||
@@ -9080,7 +9075,7 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync)
|
||||
static int
|
||||
_nfs4_proc_getdeviceinfo(struct nfs_server *server,
|
||||
struct pnfs_device *pdev,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs4_getdeviceinfo_args args = {
|
||||
.pdev = pdev,
|
||||
@@ -9112,7 +9107,7 @@ _nfs4_proc_getdeviceinfo(struct nfs_server *server,
|
||||
|
||||
int nfs4_proc_getdeviceinfo(struct nfs_server *server,
|
||||
struct pnfs_device *pdev,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs4_exception exception = { };
|
||||
int err;
|
||||
@@ -9169,7 +9164,7 @@ static void nfs4_layoutcommit_release(void *calldata)
|
||||
pnfs_cleanup_layoutcommit(data);
|
||||
nfs_post_op_update_inode_force_wcc(data->args.inode,
|
||||
data->res.fattr);
|
||||
put_rpccred(data->cred);
|
||||
put_cred(data->cred);
|
||||
nfs_iput_and_deactive(data->inode);
|
||||
kfree(data);
|
||||
}
|
||||
@@ -9245,7 +9240,7 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
.rpc_resp = &res,
|
||||
};
|
||||
struct rpc_clnt *clnt = server->client;
|
||||
struct rpc_cred *cred = NULL;
|
||||
const struct cred *cred = NULL;
|
||||
int status;
|
||||
|
||||
if (use_integrity) {
|
||||
@@ -9259,8 +9254,7 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
&res.seq_res, 0);
|
||||
dprintk("<-- %s status=%d\n", __func__, status);
|
||||
|
||||
if (cred)
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -9373,7 +9367,7 @@ out:
|
||||
|
||||
static int _nfs41_test_stateid(struct nfs_server *server,
|
||||
nfs4_stateid *stateid,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
int status;
|
||||
struct nfs41_test_stateid_args args = {
|
||||
@@ -9434,7 +9428,7 @@ static void nfs4_handle_delay_or_session_error(struct nfs_server *server,
|
||||
*/
|
||||
static int nfs41_test_stateid(struct nfs_server *server,
|
||||
nfs4_stateid *stateid,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs4_exception exception = { };
|
||||
int err;
|
||||
@@ -9496,7 +9490,7 @@ static const struct rpc_call_ops nfs41_free_stateid_ops = {
|
||||
*/
|
||||
static int nfs41_free_stateid(struct nfs_server *server,
|
||||
const nfs4_stateid *stateid,
|
||||
struct rpc_cred *cred,
|
||||
const struct cred *cred,
|
||||
bool privileged)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
@@ -9537,7 +9531,7 @@ static int nfs41_free_stateid(struct nfs_server *server,
|
||||
static void
|
||||
nfs41_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
|
||||
{
|
||||
struct rpc_cred *cred = lsp->ls_state->owner->so_cred;
|
||||
const struct cred *cred = lsp->ls_state->owner->so_cred;
|
||||
|
||||
nfs41_free_stateid(server, &lsp->ls_stateid, cred, false);
|
||||
nfs4_free_lock_state(server, lsp);
|
||||
@@ -9608,14 +9602,14 @@ static const struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
|
||||
|
||||
static const struct nfs4_state_maintenance_ops nfs40_state_renewal_ops = {
|
||||
.sched_state_renewal = nfs4_proc_async_renew,
|
||||
.get_state_renewal_cred_locked = nfs4_get_renew_cred_locked,
|
||||
.get_state_renewal_cred = nfs4_get_renew_cred,
|
||||
.renew_lease = nfs4_proc_renew,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
static const struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = {
|
||||
.sched_state_renewal = nfs41_proc_async_sequence,
|
||||
.get_state_renewal_cred_locked = nfs4_get_machine_cred_locked,
|
||||
.get_state_renewal_cred = nfs4_get_machine_cred,
|
||||
.renew_lease = nfs4_proc_sequence,
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -57,7 +57,7 @@ nfs4_renew_state(struct work_struct *work)
|
||||
const struct nfs4_state_maintenance_ops *ops;
|
||||
struct nfs_client *clp =
|
||||
container_of(work, struct nfs_client, cl_renewd.work);
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
long lease;
|
||||
unsigned long last, now;
|
||||
unsigned renew_flags = 0;
|
||||
@@ -68,7 +68,6 @@ nfs4_renew_state(struct work_struct *work)
|
||||
if (test_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state))
|
||||
goto out;
|
||||
|
||||
spin_lock(&clp->cl_lock);
|
||||
lease = clp->cl_lease_time;
|
||||
last = clp->cl_last_renewal;
|
||||
now = jiffies;
|
||||
@@ -79,8 +78,7 @@ nfs4_renew_state(struct work_struct *work)
|
||||
renew_flags |= NFS4_RENEW_DELEGATION_CB;
|
||||
|
||||
if (renew_flags != 0) {
|
||||
cred = ops->get_state_renewal_cred_locked(clp);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
cred = ops->get_state_renewal_cred(clp);
|
||||
if (cred == NULL) {
|
||||
if (!(renew_flags & NFS4_RENEW_DELEGATION_CB)) {
|
||||
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
|
||||
@@ -92,7 +90,7 @@ nfs4_renew_state(struct work_struct *work)
|
||||
|
||||
/* Queue an asynchronous RENEW. */
|
||||
ret = ops->sched_state_renewal(clp, cred, renew_flags);
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
switch (ret) {
|
||||
default:
|
||||
goto out_exp;
|
||||
@@ -104,7 +102,6 @@ nfs4_renew_state(struct work_struct *work)
|
||||
} else {
|
||||
dprintk("%s: failed to call renewd. Reason: lease not expired \n",
|
||||
__func__);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
}
|
||||
nfs4_schedule_state_renewal(clp);
|
||||
out_exp:
|
||||
|
||||
@@ -573,12 +573,11 @@ static void nfs4_destroy_session_slot_tables(struct nfs4_session *session)
|
||||
void nfs4_destroy_session(struct nfs4_session *session)
|
||||
{
|
||||
struct rpc_xprt *xprt;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
|
||||
cred = nfs4_get_clid_cred(session->clp);
|
||||
nfs4_proc_destroy_session(session, cred);
|
||||
if (cred)
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
|
||||
rcu_read_lock();
|
||||
xprt = rcu_dereference(session->clp->cl_rpcclient->cl_xprt);
|
||||
|
||||
@@ -87,7 +87,7 @@ const nfs4_stateid current_stateid = {
|
||||
|
||||
static DEFINE_MUTEX(nfs_clid_init_mutex);
|
||||
|
||||
int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
int nfs4_init_clientid(struct nfs_client *clp, const struct cred *cred)
|
||||
{
|
||||
struct nfs4_setclientid_res clid = {
|
||||
.clientid = clp->cl_clientid,
|
||||
@@ -134,7 +134,7 @@ out:
|
||||
*/
|
||||
int nfs40_discover_server_trunking(struct nfs_client *clp,
|
||||
struct nfs_client **result,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs4_setclientid_res clid = {
|
||||
.clientid = clp->cl_clientid,
|
||||
@@ -164,32 +164,23 @@ out:
|
||||
return status;
|
||||
}
|
||||
|
||||
struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
|
||||
const struct cred *nfs4_get_machine_cred(struct nfs_client *clp)
|
||||
{
|
||||
struct rpc_cred *cred = NULL;
|
||||
|
||||
if (clp->cl_machine_cred != NULL)
|
||||
cred = get_rpccred(clp->cl_machine_cred);
|
||||
return cred;
|
||||
return get_cred(rpc_machine_cred());
|
||||
}
|
||||
|
||||
static void nfs4_root_machine_cred(struct nfs_client *clp)
|
||||
{
|
||||
struct rpc_cred *cred, *new;
|
||||
|
||||
new = rpc_lookup_machine_cred(NULL);
|
||||
spin_lock(&clp->cl_lock);
|
||||
cred = clp->cl_machine_cred;
|
||||
clp->cl_machine_cred = new;
|
||||
spin_unlock(&clp->cl_lock);
|
||||
if (cred != NULL)
|
||||
put_rpccred(cred);
|
||||
/* Force root creds instead of machine */
|
||||
clp->cl_principal = NULL;
|
||||
clp->cl_rpcclient->cl_principal = NULL;
|
||||
}
|
||||
|
||||
static struct rpc_cred *
|
||||
static const struct cred *
|
||||
nfs4_get_renew_cred_server_locked(struct nfs_server *server)
|
||||
{
|
||||
struct rpc_cred *cred = NULL;
|
||||
const struct cred *cred = NULL;
|
||||
struct nfs4_state_owner *sp;
|
||||
struct rb_node *pos;
|
||||
|
||||
@@ -199,29 +190,30 @@ nfs4_get_renew_cred_server_locked(struct nfs_server *server)
|
||||
sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
|
||||
if (list_empty(&sp->so_states))
|
||||
continue;
|
||||
cred = get_rpccred(sp->so_cred);
|
||||
cred = get_cred(sp->so_cred);
|
||||
break;
|
||||
}
|
||||
return cred;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs4_get_renew_cred_locked - Acquire credential for a renew operation
|
||||
* nfs4_get_renew_cred - Acquire credential for a renew operation
|
||||
* @clp: client state handle
|
||||
*
|
||||
* Returns an rpc_cred with reference count bumped, or NULL.
|
||||
* Caller must hold clp->cl_lock.
|
||||
*/
|
||||
struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
|
||||
const struct cred *nfs4_get_renew_cred(struct nfs_client *clp)
|
||||
{
|
||||
struct rpc_cred *cred = NULL;
|
||||
const struct cred *cred = NULL;
|
||||
struct nfs_server *server;
|
||||
|
||||
/* Use machine credentials if available */
|
||||
cred = nfs4_get_machine_cred_locked(clp);
|
||||
cred = nfs4_get_machine_cred(clp);
|
||||
if (cred != NULL)
|
||||
goto out;
|
||||
|
||||
spin_lock(&clp->cl_lock);
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
|
||||
cred = nfs4_get_renew_cred_server_locked(server);
|
||||
@@ -229,6 +221,7 @@ struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
|
||||
break;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
spin_unlock(&clp->cl_lock);
|
||||
|
||||
out:
|
||||
return cred;
|
||||
@@ -319,7 +312,7 @@ static void nfs41_finish_session_reset(struct nfs_client *clp)
|
||||
nfs41_setup_state_renewal(clp);
|
||||
}
|
||||
|
||||
int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
int nfs41_init_clientid(struct nfs_client *clp, const struct cred *cred)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -354,7 +347,7 @@ out:
|
||||
*/
|
||||
int nfs41_discover_server_trunking(struct nfs_client *clp,
|
||||
struct nfs_client **result,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -392,32 +385,32 @@ int nfs41_discover_server_trunking(struct nfs_client *clp,
|
||||
* nfs4_get_clid_cred - Acquire credential for a setclientid operation
|
||||
* @clp: client state handle
|
||||
*
|
||||
* Returns an rpc_cred with reference count bumped, or NULL.
|
||||
* Returns a cred with reference count bumped, or NULL.
|
||||
*/
|
||||
struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp)
|
||||
const struct cred *nfs4_get_clid_cred(struct nfs_client *clp)
|
||||
{
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
|
||||
spin_lock(&clp->cl_lock);
|
||||
cred = nfs4_get_machine_cred_locked(clp);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
cred = nfs4_get_machine_cred(clp);
|
||||
return cred;
|
||||
}
|
||||
|
||||
static struct nfs4_state_owner *
|
||||
nfs4_find_state_owner_locked(struct nfs_server *server, struct rpc_cred *cred)
|
||||
nfs4_find_state_owner_locked(struct nfs_server *server, const struct cred *cred)
|
||||
{
|
||||
struct rb_node **p = &server->state_owners.rb_node,
|
||||
*parent = NULL;
|
||||
struct nfs4_state_owner *sp;
|
||||
int cmp;
|
||||
|
||||
while (*p != NULL) {
|
||||
parent = *p;
|
||||
sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
|
||||
cmp = cred_fscmp(cred, sp->so_cred);
|
||||
|
||||
if (cred < sp->so_cred)
|
||||
if (cmp < 0)
|
||||
p = &parent->rb_left;
|
||||
else if (cred > sp->so_cred)
|
||||
else if (cmp > 0)
|
||||
p = &parent->rb_right;
|
||||
else {
|
||||
if (!list_empty(&sp->so_lru))
|
||||
@@ -436,14 +429,16 @@ nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
|
||||
struct rb_node **p = &server->state_owners.rb_node,
|
||||
*parent = NULL;
|
||||
struct nfs4_state_owner *sp;
|
||||
int cmp;
|
||||
|
||||
while (*p != NULL) {
|
||||
parent = *p;
|
||||
sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
|
||||
cmp = cred_fscmp(new->so_cred, sp->so_cred);
|
||||
|
||||
if (new->so_cred < sp->so_cred)
|
||||
if (cmp < 0)
|
||||
p = &parent->rb_left;
|
||||
else if (new->so_cred > sp->so_cred)
|
||||
else if (cmp > 0)
|
||||
p = &parent->rb_right;
|
||||
else {
|
||||
if (!list_empty(&sp->so_lru))
|
||||
@@ -490,7 +485,7 @@ nfs4_destroy_seqid_counter(struct nfs_seqid_counter *sc)
|
||||
*/
|
||||
static struct nfs4_state_owner *
|
||||
nfs4_alloc_state_owner(struct nfs_server *server,
|
||||
struct rpc_cred *cred,
|
||||
const struct cred *cred,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct nfs4_state_owner *sp;
|
||||
@@ -505,7 +500,7 @@ nfs4_alloc_state_owner(struct nfs_server *server,
|
||||
return NULL;
|
||||
}
|
||||
sp->so_server = server;
|
||||
sp->so_cred = get_rpccred(cred);
|
||||
sp->so_cred = get_cred(cred);
|
||||
spin_lock_init(&sp->so_lock);
|
||||
INIT_LIST_HEAD(&sp->so_states);
|
||||
nfs4_init_seqid_counter(&sp->so_seqid);
|
||||
@@ -534,7 +529,7 @@ nfs4_reset_state_owner(struct nfs4_state_owner *sp)
|
||||
static void nfs4_free_state_owner(struct nfs4_state_owner *sp)
|
||||
{
|
||||
nfs4_destroy_seqid_counter(&sp->so_seqid);
|
||||
put_rpccred(sp->so_cred);
|
||||
put_cred(sp->so_cred);
|
||||
ida_simple_remove(&sp->so_server->openowner_id, sp->so_seqid.owner_id);
|
||||
kfree(sp);
|
||||
}
|
||||
@@ -572,7 +567,7 @@ static void nfs4_gc_state_owners(struct nfs_server *server)
|
||||
* Returns a pointer to an instantiated nfs4_state_owner struct, or NULL.
|
||||
*/
|
||||
struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
|
||||
struct rpc_cred *cred,
|
||||
const struct cred *cred,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
@@ -1041,7 +1036,7 @@ bool nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
|
||||
*/
|
||||
int nfs4_select_rw_stateid(struct nfs4_state *state,
|
||||
fmode_t fmode, const struct nfs_lock_context *l_ctx,
|
||||
nfs4_stateid *dst, struct rpc_cred **cred)
|
||||
nfs4_stateid *dst, const struct cred **cred)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -1560,7 +1555,7 @@ static void nfs42_complete_copies(struct nfs4_state_owner *sp, struct nfs4_state
|
||||
|
||||
spin_lock(&sp->so_server->nfs_client->cl_lock);
|
||||
list_for_each_entry(copy, &sp->so_server->ss_copies, copies) {
|
||||
if (nfs4_stateid_match_other(&state->stateid, ©->parent_state->stateid))
|
||||
if (!nfs4_stateid_match_other(&state->stateid, ©->parent_state->stateid))
|
||||
continue;
|
||||
copy->flags = 1;
|
||||
complete(©->completion);
|
||||
@@ -1741,7 +1736,7 @@ static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
|
||||
|
||||
static int nfs4_reclaim_complete(struct nfs_client *clp,
|
||||
const struct nfs4_state_recovery_ops *ops,
|
||||
struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
/* Notify the server we're done reclaiming our state */
|
||||
if (ops->reclaim_complete)
|
||||
@@ -1792,7 +1787,7 @@ static int nfs4_state_clear_reclaim_reboot(struct nfs_client *clp)
|
||||
static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
|
||||
{
|
||||
const struct nfs4_state_recovery_ops *ops;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
int err;
|
||||
|
||||
if (!nfs4_state_clear_reclaim_reboot(clp))
|
||||
@@ -1800,7 +1795,7 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
|
||||
ops = clp->cl_mvops->reboot_recovery_ops;
|
||||
cred = nfs4_get_clid_cred(clp);
|
||||
err = nfs4_reclaim_complete(clp, ops, cred);
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
if (err == -NFS4ERR_CONN_NOT_BOUND_TO_SESSION)
|
||||
set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
|
||||
}
|
||||
@@ -1896,7 +1891,7 @@ restart:
|
||||
|
||||
static int nfs4_check_lease(struct nfs_client *clp)
|
||||
{
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
const struct nfs4_state_maintenance_ops *ops =
|
||||
clp->cl_mvops->state_renewal_ops;
|
||||
int status;
|
||||
@@ -1904,9 +1899,7 @@ static int nfs4_check_lease(struct nfs_client *clp)
|
||||
/* Is the client already known to have an expired lease? */
|
||||
if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
|
||||
return 0;
|
||||
spin_lock(&clp->cl_lock);
|
||||
cred = ops->get_state_renewal_cred_locked(clp);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
cred = ops->get_state_renewal_cred(clp);
|
||||
if (cred == NULL) {
|
||||
cred = nfs4_get_clid_cred(clp);
|
||||
status = -ENOKEY;
|
||||
@@ -1914,7 +1907,7 @@ static int nfs4_check_lease(struct nfs_client *clp)
|
||||
goto out;
|
||||
}
|
||||
status = ops->renew_lease(clp, cred);
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
if (status == -ETIMEDOUT) {
|
||||
set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
|
||||
return 0;
|
||||
@@ -1974,7 +1967,7 @@ static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
|
||||
|
||||
static int nfs4_establish_lease(struct nfs_client *clp)
|
||||
{
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
const struct nfs4_state_recovery_ops *ops =
|
||||
clp->cl_mvops->reboot_recovery_ops;
|
||||
int status;
|
||||
@@ -1986,7 +1979,7 @@ static int nfs4_establish_lease(struct nfs_client *clp)
|
||||
if (cred == NULL)
|
||||
return -ENOENT;
|
||||
status = ops->establish_clid(clp, cred);
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
if (status != 0)
|
||||
return status;
|
||||
pnfs_destroy_all_layouts(clp);
|
||||
@@ -2033,7 +2026,7 @@ static int nfs4_purge_lease(struct nfs_client *clp)
|
||||
*
|
||||
* Returns zero or a negative NFS4ERR status code.
|
||||
*/
|
||||
static int nfs4_try_migration(struct nfs_server *server, struct rpc_cred *cred)
|
||||
static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred)
|
||||
{
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
struct nfs4_fs_locations *locations = NULL;
|
||||
@@ -2103,14 +2096,12 @@ static int nfs4_handle_migration(struct nfs_client *clp)
|
||||
const struct nfs4_state_maintenance_ops *ops =
|
||||
clp->cl_mvops->state_renewal_ops;
|
||||
struct nfs_server *server;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
|
||||
dprintk("%s: migration reported on \"%s\"\n", __func__,
|
||||
clp->cl_hostname);
|
||||
|
||||
spin_lock(&clp->cl_lock);
|
||||
cred = ops->get_state_renewal_cred_locked(clp);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
cred = ops->get_state_renewal_cred(clp);
|
||||
if (cred == NULL)
|
||||
return -NFS4ERR_NOENT;
|
||||
|
||||
@@ -2131,13 +2122,13 @@ restart:
|
||||
rcu_read_unlock();
|
||||
status = nfs4_try_migration(server, cred);
|
||||
if (status < 0) {
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
return status;
|
||||
}
|
||||
goto restart;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2151,14 +2142,12 @@ static int nfs4_handle_lease_moved(struct nfs_client *clp)
|
||||
const struct nfs4_state_maintenance_ops *ops =
|
||||
clp->cl_mvops->state_renewal_ops;
|
||||
struct nfs_server *server;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
|
||||
dprintk("%s: lease moved reported on \"%s\"\n", __func__,
|
||||
clp->cl_hostname);
|
||||
|
||||
spin_lock(&clp->cl_lock);
|
||||
cred = ops->get_state_renewal_cred_locked(clp);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
cred = ops->get_state_renewal_cred(clp);
|
||||
if (cred == NULL)
|
||||
return -NFS4ERR_NOENT;
|
||||
|
||||
@@ -2186,7 +2175,7 @@ restart:
|
||||
rcu_read_unlock();
|
||||
|
||||
out:
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2209,7 +2198,7 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
|
||||
const struct nfs4_state_recovery_ops *ops =
|
||||
clp->cl_mvops->reboot_recovery_ops;
|
||||
struct rpc_clnt *clnt;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
int i, status;
|
||||
|
||||
dprintk("NFS: %s: testing '%s'\n", __func__, clp->cl_hostname);
|
||||
@@ -2225,7 +2214,7 @@ again:
|
||||
goto out_unlock;
|
||||
|
||||
status = ops->detect_trunking(clp, result, cred);
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
switch (status) {
|
||||
case 0:
|
||||
case -EINTR:
|
||||
@@ -2416,7 +2405,7 @@ out_recovery:
|
||||
|
||||
static int nfs4_reset_session(struct nfs_client *clp)
|
||||
{
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
int status;
|
||||
|
||||
if (!nfs4_has_session(clp))
|
||||
@@ -2454,14 +2443,13 @@ static int nfs4_reset_session(struct nfs_client *clp)
|
||||
dprintk("%s: session reset was successful for server %s!\n",
|
||||
__func__, clp->cl_hostname);
|
||||
out:
|
||||
if (cred)
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int nfs4_bind_conn_to_session(struct nfs_client *clp)
|
||||
{
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
int ret;
|
||||
|
||||
if (!nfs4_has_session(clp))
|
||||
@@ -2471,8 +2459,7 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp)
|
||||
return ret;
|
||||
cred = nfs4_get_clid_cred(clp);
|
||||
ret = nfs4_proc_bind_conn_to_session(clp, cred);
|
||||
if (cred)
|
||||
put_rpccred(cred);
|
||||
put_cred(cred);
|
||||
clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
|
||||
switch (ret) {
|
||||
case 0:
|
||||
|
||||
@@ -10,157 +10,302 @@
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
TRACE_DEFINE_ENUM(EPERM);
|
||||
TRACE_DEFINE_ENUM(ENOENT);
|
||||
TRACE_DEFINE_ENUM(EIO);
|
||||
TRACE_DEFINE_ENUM(ENXIO);
|
||||
TRACE_DEFINE_ENUM(EACCES);
|
||||
TRACE_DEFINE_ENUM(EEXIST);
|
||||
TRACE_DEFINE_ENUM(EXDEV);
|
||||
TRACE_DEFINE_ENUM(ENOTDIR);
|
||||
TRACE_DEFINE_ENUM(EISDIR);
|
||||
TRACE_DEFINE_ENUM(EFBIG);
|
||||
TRACE_DEFINE_ENUM(ENOSPC);
|
||||
TRACE_DEFINE_ENUM(EROFS);
|
||||
TRACE_DEFINE_ENUM(EMLINK);
|
||||
TRACE_DEFINE_ENUM(ENAMETOOLONG);
|
||||
TRACE_DEFINE_ENUM(ENOTEMPTY);
|
||||
TRACE_DEFINE_ENUM(EDQUOT);
|
||||
TRACE_DEFINE_ENUM(ESTALE);
|
||||
TRACE_DEFINE_ENUM(EBADHANDLE);
|
||||
TRACE_DEFINE_ENUM(EBADCOOKIE);
|
||||
TRACE_DEFINE_ENUM(ENOTSUPP);
|
||||
TRACE_DEFINE_ENUM(ETOOSMALL);
|
||||
TRACE_DEFINE_ENUM(EREMOTEIO);
|
||||
TRACE_DEFINE_ENUM(EBADTYPE);
|
||||
TRACE_DEFINE_ENUM(EAGAIN);
|
||||
TRACE_DEFINE_ENUM(ELOOP);
|
||||
TRACE_DEFINE_ENUM(EOPNOTSUPP);
|
||||
TRACE_DEFINE_ENUM(EDEADLK);
|
||||
TRACE_DEFINE_ENUM(ENOMEM);
|
||||
TRACE_DEFINE_ENUM(EKEYEXPIRED);
|
||||
TRACE_DEFINE_ENUM(ETIMEDOUT);
|
||||
TRACE_DEFINE_ENUM(ERESTARTSYS);
|
||||
TRACE_DEFINE_ENUM(ECONNREFUSED);
|
||||
TRACE_DEFINE_ENUM(ECONNRESET);
|
||||
TRACE_DEFINE_ENUM(ENETUNREACH);
|
||||
TRACE_DEFINE_ENUM(EHOSTUNREACH);
|
||||
TRACE_DEFINE_ENUM(EHOSTDOWN);
|
||||
TRACE_DEFINE_ENUM(EPIPE);
|
||||
TRACE_DEFINE_ENUM(EPFNOSUPPORT);
|
||||
TRACE_DEFINE_ENUM(EPROTONOSUPPORT);
|
||||
|
||||
TRACE_DEFINE_ENUM(NFS4_OK);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_ACCESS);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADNAME);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BADXDR);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_DELAY);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_DENIED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_DQUOT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_EXIST);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_FBIG);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_GRACE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_INVAL);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_IO);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_ISDIR);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_LOCKED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_MLINK);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_MOVED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NOENT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NOSPC);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_NXIO);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_PERM);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_ROFS);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_SAME);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_STALE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE);
|
||||
TRACE_DEFINE_ENUM(NFS4ERR_XDEV);
|
||||
|
||||
#define show_nfsv4_errors(error) \
|
||||
__print_symbolic(error, \
|
||||
__print_symbolic(-(error), \
|
||||
{ NFS4_OK, "OK" }, \
|
||||
/* Mapped by nfs4_stat_to_errno() */ \
|
||||
{ -EPERM, "EPERM" }, \
|
||||
{ -ENOENT, "ENOENT" }, \
|
||||
{ -EIO, "EIO" }, \
|
||||
{ -ENXIO, "ENXIO" }, \
|
||||
{ -EACCES, "EACCES" }, \
|
||||
{ -EEXIST, "EEXIST" }, \
|
||||
{ -EXDEV, "EXDEV" }, \
|
||||
{ -ENOTDIR, "ENOTDIR" }, \
|
||||
{ -EISDIR, "EISDIR" }, \
|
||||
{ -EFBIG, "EFBIG" }, \
|
||||
{ -ENOSPC, "ENOSPC" }, \
|
||||
{ -EROFS, "EROFS" }, \
|
||||
{ -EMLINK, "EMLINK" }, \
|
||||
{ -ENAMETOOLONG, "ENAMETOOLONG" }, \
|
||||
{ -ENOTEMPTY, "ENOTEMPTY" }, \
|
||||
{ -EDQUOT, "EDQUOT" }, \
|
||||
{ -ESTALE, "ESTALE" }, \
|
||||
{ -EBADHANDLE, "EBADHANDLE" }, \
|
||||
{ -EBADCOOKIE, "EBADCOOKIE" }, \
|
||||
{ -ENOTSUPP, "ENOTSUPP" }, \
|
||||
{ -ETOOSMALL, "ETOOSMALL" }, \
|
||||
{ -EREMOTEIO, "EREMOTEIO" }, \
|
||||
{ -EBADTYPE, "EBADTYPE" }, \
|
||||
{ -EAGAIN, "EAGAIN" }, \
|
||||
{ -ELOOP, "ELOOP" }, \
|
||||
{ -EOPNOTSUPP, "EOPNOTSUPP" }, \
|
||||
{ -EDEADLK, "EDEADLK" }, \
|
||||
{ EPERM, "EPERM" }, \
|
||||
{ ENOENT, "ENOENT" }, \
|
||||
{ EIO, "EIO" }, \
|
||||
{ ENXIO, "ENXIO" }, \
|
||||
{ EACCES, "EACCES" }, \
|
||||
{ EEXIST, "EEXIST" }, \
|
||||
{ EXDEV, "EXDEV" }, \
|
||||
{ ENOTDIR, "ENOTDIR" }, \
|
||||
{ EISDIR, "EISDIR" }, \
|
||||
{ EFBIG, "EFBIG" }, \
|
||||
{ ENOSPC, "ENOSPC" }, \
|
||||
{ EROFS, "EROFS" }, \
|
||||
{ EMLINK, "EMLINK" }, \
|
||||
{ ENAMETOOLONG, "ENAMETOOLONG" }, \
|
||||
{ ENOTEMPTY, "ENOTEMPTY" }, \
|
||||
{ EDQUOT, "EDQUOT" }, \
|
||||
{ ESTALE, "ESTALE" }, \
|
||||
{ EBADHANDLE, "EBADHANDLE" }, \
|
||||
{ EBADCOOKIE, "EBADCOOKIE" }, \
|
||||
{ ENOTSUPP, "ENOTSUPP" }, \
|
||||
{ ETOOSMALL, "ETOOSMALL" }, \
|
||||
{ EREMOTEIO, "EREMOTEIO" }, \
|
||||
{ EBADTYPE, "EBADTYPE" }, \
|
||||
{ EAGAIN, "EAGAIN" }, \
|
||||
{ ELOOP, "ELOOP" }, \
|
||||
{ EOPNOTSUPP, "EOPNOTSUPP" }, \
|
||||
{ EDEADLK, "EDEADLK" }, \
|
||||
/* RPC errors */ \
|
||||
{ -ENOMEM, "ENOMEM" }, \
|
||||
{ -EKEYEXPIRED, "EKEYEXPIRED" }, \
|
||||
{ -ETIMEDOUT, "ETIMEDOUT" }, \
|
||||
{ -ERESTARTSYS, "ERESTARTSYS" }, \
|
||||
{ -ECONNREFUSED, "ECONNREFUSED" }, \
|
||||
{ -ECONNRESET, "ECONNRESET" }, \
|
||||
{ -ENETUNREACH, "ENETUNREACH" }, \
|
||||
{ -EHOSTUNREACH, "EHOSTUNREACH" }, \
|
||||
{ -EHOSTDOWN, "EHOSTDOWN" }, \
|
||||
{ -EPIPE, "EPIPE" }, \
|
||||
{ -EPFNOSUPPORT, "EPFNOSUPPORT" }, \
|
||||
{ -EPROTONOSUPPORT, "EPROTONOSUPPORT" }, \
|
||||
{ ENOMEM, "ENOMEM" }, \
|
||||
{ EKEYEXPIRED, "EKEYEXPIRED" }, \
|
||||
{ ETIMEDOUT, "ETIMEDOUT" }, \
|
||||
{ ERESTARTSYS, "ERESTARTSYS" }, \
|
||||
{ ECONNREFUSED, "ECONNREFUSED" }, \
|
||||
{ ECONNRESET, "ECONNRESET" }, \
|
||||
{ ENETUNREACH, "ENETUNREACH" }, \
|
||||
{ EHOSTUNREACH, "EHOSTUNREACH" }, \
|
||||
{ EHOSTDOWN, "EHOSTDOWN" }, \
|
||||
{ EPIPE, "EPIPE" }, \
|
||||
{ EPFNOSUPPORT, "EPFNOSUPPORT" }, \
|
||||
{ EPROTONOSUPPORT, "EPROTONOSUPPORT" }, \
|
||||
/* NFSv4 native errors */ \
|
||||
{ -NFS4ERR_ACCESS, "ACCESS" }, \
|
||||
{ -NFS4ERR_ATTRNOTSUPP, "ATTRNOTSUPP" }, \
|
||||
{ -NFS4ERR_ADMIN_REVOKED, "ADMIN_REVOKED" }, \
|
||||
{ -NFS4ERR_BACK_CHAN_BUSY, "BACK_CHAN_BUSY" }, \
|
||||
{ -NFS4ERR_BADCHAR, "BADCHAR" }, \
|
||||
{ -NFS4ERR_BADHANDLE, "BADHANDLE" }, \
|
||||
{ -NFS4ERR_BADIOMODE, "BADIOMODE" }, \
|
||||
{ -NFS4ERR_BADLAYOUT, "BADLAYOUT" }, \
|
||||
{ -NFS4ERR_BADLABEL, "BADLABEL" }, \
|
||||
{ -NFS4ERR_BADNAME, "BADNAME" }, \
|
||||
{ -NFS4ERR_BADOWNER, "BADOWNER" }, \
|
||||
{ -NFS4ERR_BADSESSION, "BADSESSION" }, \
|
||||
{ -NFS4ERR_BADSLOT, "BADSLOT" }, \
|
||||
{ -NFS4ERR_BADTYPE, "BADTYPE" }, \
|
||||
{ -NFS4ERR_BADXDR, "BADXDR" }, \
|
||||
{ -NFS4ERR_BAD_COOKIE, "BAD_COOKIE" }, \
|
||||
{ -NFS4ERR_BAD_HIGH_SLOT, "BAD_HIGH_SLOT" }, \
|
||||
{ -NFS4ERR_BAD_RANGE, "BAD_RANGE" }, \
|
||||
{ -NFS4ERR_BAD_SEQID, "BAD_SEQID" }, \
|
||||
{ -NFS4ERR_BAD_SESSION_DIGEST, "BAD_SESSION_DIGEST" }, \
|
||||
{ -NFS4ERR_BAD_STATEID, "BAD_STATEID" }, \
|
||||
{ -NFS4ERR_CB_PATH_DOWN, "CB_PATH_DOWN" }, \
|
||||
{ -NFS4ERR_CLID_INUSE, "CLID_INUSE" }, \
|
||||
{ -NFS4ERR_CLIENTID_BUSY, "CLIENTID_BUSY" }, \
|
||||
{ -NFS4ERR_COMPLETE_ALREADY, "COMPLETE_ALREADY" }, \
|
||||
{ -NFS4ERR_CONN_NOT_BOUND_TO_SESSION, \
|
||||
{ NFS4ERR_ACCESS, "ACCESS" }, \
|
||||
{ NFS4ERR_ATTRNOTSUPP, "ATTRNOTSUPP" }, \
|
||||
{ NFS4ERR_ADMIN_REVOKED, "ADMIN_REVOKED" }, \
|
||||
{ NFS4ERR_BACK_CHAN_BUSY, "BACK_CHAN_BUSY" }, \
|
||||
{ NFS4ERR_BADCHAR, "BADCHAR" }, \
|
||||
{ NFS4ERR_BADHANDLE, "BADHANDLE" }, \
|
||||
{ NFS4ERR_BADIOMODE, "BADIOMODE" }, \
|
||||
{ NFS4ERR_BADLAYOUT, "BADLAYOUT" }, \
|
||||
{ NFS4ERR_BADLABEL, "BADLABEL" }, \
|
||||
{ NFS4ERR_BADNAME, "BADNAME" }, \
|
||||
{ NFS4ERR_BADOWNER, "BADOWNER" }, \
|
||||
{ NFS4ERR_BADSESSION, "BADSESSION" }, \
|
||||
{ NFS4ERR_BADSLOT, "BADSLOT" }, \
|
||||
{ NFS4ERR_BADTYPE, "BADTYPE" }, \
|
||||
{ NFS4ERR_BADXDR, "BADXDR" }, \
|
||||
{ NFS4ERR_BAD_COOKIE, "BAD_COOKIE" }, \
|
||||
{ NFS4ERR_BAD_HIGH_SLOT, "BAD_HIGH_SLOT" }, \
|
||||
{ NFS4ERR_BAD_RANGE, "BAD_RANGE" }, \
|
||||
{ NFS4ERR_BAD_SEQID, "BAD_SEQID" }, \
|
||||
{ NFS4ERR_BAD_SESSION_DIGEST, "BAD_SESSION_DIGEST" }, \
|
||||
{ NFS4ERR_BAD_STATEID, "BAD_STATEID" }, \
|
||||
{ NFS4ERR_CB_PATH_DOWN, "CB_PATH_DOWN" }, \
|
||||
{ NFS4ERR_CLID_INUSE, "CLID_INUSE" }, \
|
||||
{ NFS4ERR_CLIENTID_BUSY, "CLIENTID_BUSY" }, \
|
||||
{ NFS4ERR_COMPLETE_ALREADY, "COMPLETE_ALREADY" }, \
|
||||
{ NFS4ERR_CONN_NOT_BOUND_TO_SESSION, \
|
||||
"CONN_NOT_BOUND_TO_SESSION" }, \
|
||||
{ -NFS4ERR_DEADLOCK, "DEADLOCK" }, \
|
||||
{ -NFS4ERR_DEADSESSION, "DEAD_SESSION" }, \
|
||||
{ -NFS4ERR_DELAY, "DELAY" }, \
|
||||
{ -NFS4ERR_DELEG_ALREADY_WANTED, \
|
||||
{ NFS4ERR_DEADLOCK, "DEADLOCK" }, \
|
||||
{ NFS4ERR_DEADSESSION, "DEAD_SESSION" }, \
|
||||
{ NFS4ERR_DELAY, "DELAY" }, \
|
||||
{ NFS4ERR_DELEG_ALREADY_WANTED, \
|
||||
"DELEG_ALREADY_WANTED" }, \
|
||||
{ -NFS4ERR_DELEG_REVOKED, "DELEG_REVOKED" }, \
|
||||
{ -NFS4ERR_DENIED, "DENIED" }, \
|
||||
{ -NFS4ERR_DIRDELEG_UNAVAIL, "DIRDELEG_UNAVAIL" }, \
|
||||
{ -NFS4ERR_DQUOT, "DQUOT" }, \
|
||||
{ -NFS4ERR_ENCR_ALG_UNSUPP, "ENCR_ALG_UNSUPP" }, \
|
||||
{ -NFS4ERR_EXIST, "EXIST" }, \
|
||||
{ -NFS4ERR_EXPIRED, "EXPIRED" }, \
|
||||
{ -NFS4ERR_FBIG, "FBIG" }, \
|
||||
{ -NFS4ERR_FHEXPIRED, "FHEXPIRED" }, \
|
||||
{ -NFS4ERR_FILE_OPEN, "FILE_OPEN" }, \
|
||||
{ -NFS4ERR_GRACE, "GRACE" }, \
|
||||
{ -NFS4ERR_HASH_ALG_UNSUPP, "HASH_ALG_UNSUPP" }, \
|
||||
{ -NFS4ERR_INVAL, "INVAL" }, \
|
||||
{ -NFS4ERR_IO, "IO" }, \
|
||||
{ -NFS4ERR_ISDIR, "ISDIR" }, \
|
||||
{ -NFS4ERR_LAYOUTTRYLATER, "LAYOUTTRYLATER" }, \
|
||||
{ -NFS4ERR_LAYOUTUNAVAILABLE, "LAYOUTUNAVAILABLE" }, \
|
||||
{ -NFS4ERR_LEASE_MOVED, "LEASE_MOVED" }, \
|
||||
{ -NFS4ERR_LOCKED, "LOCKED" }, \
|
||||
{ -NFS4ERR_LOCKS_HELD, "LOCKS_HELD" }, \
|
||||
{ -NFS4ERR_LOCK_RANGE, "LOCK_RANGE" }, \
|
||||
{ -NFS4ERR_MINOR_VERS_MISMATCH, "MINOR_VERS_MISMATCH" }, \
|
||||
{ -NFS4ERR_MLINK, "MLINK" }, \
|
||||
{ -NFS4ERR_MOVED, "MOVED" }, \
|
||||
{ -NFS4ERR_NAMETOOLONG, "NAMETOOLONG" }, \
|
||||
{ -NFS4ERR_NOENT, "NOENT" }, \
|
||||
{ -NFS4ERR_NOFILEHANDLE, "NOFILEHANDLE" }, \
|
||||
{ -NFS4ERR_NOMATCHING_LAYOUT, "NOMATCHING_LAYOUT" }, \
|
||||
{ -NFS4ERR_NOSPC, "NOSPC" }, \
|
||||
{ -NFS4ERR_NOTDIR, "NOTDIR" }, \
|
||||
{ -NFS4ERR_NOTEMPTY, "NOTEMPTY" }, \
|
||||
{ -NFS4ERR_NOTSUPP, "NOTSUPP" }, \
|
||||
{ -NFS4ERR_NOT_ONLY_OP, "NOT_ONLY_OP" }, \
|
||||
{ -NFS4ERR_NOT_SAME, "NOT_SAME" }, \
|
||||
{ -NFS4ERR_NO_GRACE, "NO_GRACE" }, \
|
||||
{ -NFS4ERR_NXIO, "NXIO" }, \
|
||||
{ -NFS4ERR_OLD_STATEID, "OLD_STATEID" }, \
|
||||
{ -NFS4ERR_OPENMODE, "OPENMODE" }, \
|
||||
{ -NFS4ERR_OP_ILLEGAL, "OP_ILLEGAL" }, \
|
||||
{ -NFS4ERR_OP_NOT_IN_SESSION, "OP_NOT_IN_SESSION" }, \
|
||||
{ -NFS4ERR_PERM, "PERM" }, \
|
||||
{ -NFS4ERR_PNFS_IO_HOLE, "PNFS_IO_HOLE" }, \
|
||||
{ -NFS4ERR_PNFS_NO_LAYOUT, "PNFS_NO_LAYOUT" }, \
|
||||
{ -NFS4ERR_RECALLCONFLICT, "RECALLCONFLICT" }, \
|
||||
{ -NFS4ERR_RECLAIM_BAD, "RECLAIM_BAD" }, \
|
||||
{ -NFS4ERR_RECLAIM_CONFLICT, "RECLAIM_CONFLICT" }, \
|
||||
{ -NFS4ERR_REJECT_DELEG, "REJECT_DELEG" }, \
|
||||
{ -NFS4ERR_REP_TOO_BIG, "REP_TOO_BIG" }, \
|
||||
{ -NFS4ERR_REP_TOO_BIG_TO_CACHE, \
|
||||
{ NFS4ERR_DELEG_REVOKED, "DELEG_REVOKED" }, \
|
||||
{ NFS4ERR_DENIED, "DENIED" }, \
|
||||
{ NFS4ERR_DIRDELEG_UNAVAIL, "DIRDELEG_UNAVAIL" }, \
|
||||
{ NFS4ERR_DQUOT, "DQUOT" }, \
|
||||
{ NFS4ERR_ENCR_ALG_UNSUPP, "ENCR_ALG_UNSUPP" }, \
|
||||
{ NFS4ERR_EXIST, "EXIST" }, \
|
||||
{ NFS4ERR_EXPIRED, "EXPIRED" }, \
|
||||
{ NFS4ERR_FBIG, "FBIG" }, \
|
||||
{ NFS4ERR_FHEXPIRED, "FHEXPIRED" }, \
|
||||
{ NFS4ERR_FILE_OPEN, "FILE_OPEN" }, \
|
||||
{ NFS4ERR_GRACE, "GRACE" }, \
|
||||
{ NFS4ERR_HASH_ALG_UNSUPP, "HASH_ALG_UNSUPP" }, \
|
||||
{ NFS4ERR_INVAL, "INVAL" }, \
|
||||
{ NFS4ERR_IO, "IO" }, \
|
||||
{ NFS4ERR_ISDIR, "ISDIR" }, \
|
||||
{ NFS4ERR_LAYOUTTRYLATER, "LAYOUTTRYLATER" }, \
|
||||
{ NFS4ERR_LAYOUTUNAVAILABLE, "LAYOUTUNAVAILABLE" }, \
|
||||
{ NFS4ERR_LEASE_MOVED, "LEASE_MOVED" }, \
|
||||
{ NFS4ERR_LOCKED, "LOCKED" }, \
|
||||
{ NFS4ERR_LOCKS_HELD, "LOCKS_HELD" }, \
|
||||
{ NFS4ERR_LOCK_RANGE, "LOCK_RANGE" }, \
|
||||
{ NFS4ERR_MINOR_VERS_MISMATCH, "MINOR_VERS_MISMATCH" }, \
|
||||
{ NFS4ERR_MLINK, "MLINK" }, \
|
||||
{ NFS4ERR_MOVED, "MOVED" }, \
|
||||
{ NFS4ERR_NAMETOOLONG, "NAMETOOLONG" }, \
|
||||
{ NFS4ERR_NOENT, "NOENT" }, \
|
||||
{ NFS4ERR_NOFILEHANDLE, "NOFILEHANDLE" }, \
|
||||
{ NFS4ERR_NOMATCHING_LAYOUT, "NOMATCHING_LAYOUT" }, \
|
||||
{ NFS4ERR_NOSPC, "NOSPC" }, \
|
||||
{ NFS4ERR_NOTDIR, "NOTDIR" }, \
|
||||
{ NFS4ERR_NOTEMPTY, "NOTEMPTY" }, \
|
||||
{ NFS4ERR_NOTSUPP, "NOTSUPP" }, \
|
||||
{ NFS4ERR_NOT_ONLY_OP, "NOT_ONLY_OP" }, \
|
||||
{ NFS4ERR_NOT_SAME, "NOT_SAME" }, \
|
||||
{ NFS4ERR_NO_GRACE, "NO_GRACE" }, \
|
||||
{ NFS4ERR_NXIO, "NXIO" }, \
|
||||
{ NFS4ERR_OLD_STATEID, "OLD_STATEID" }, \
|
||||
{ NFS4ERR_OPENMODE, "OPENMODE" }, \
|
||||
{ NFS4ERR_OP_ILLEGAL, "OP_ILLEGAL" }, \
|
||||
{ NFS4ERR_OP_NOT_IN_SESSION, "OP_NOT_IN_SESSION" }, \
|
||||
{ NFS4ERR_PERM, "PERM" }, \
|
||||
{ NFS4ERR_PNFS_IO_HOLE, "PNFS_IO_HOLE" }, \
|
||||
{ NFS4ERR_PNFS_NO_LAYOUT, "PNFS_NO_LAYOUT" }, \
|
||||
{ NFS4ERR_RECALLCONFLICT, "RECALLCONFLICT" }, \
|
||||
{ NFS4ERR_RECLAIM_BAD, "RECLAIM_BAD" }, \
|
||||
{ NFS4ERR_RECLAIM_CONFLICT, "RECLAIM_CONFLICT" }, \
|
||||
{ NFS4ERR_REJECT_DELEG, "REJECT_DELEG" }, \
|
||||
{ NFS4ERR_REP_TOO_BIG, "REP_TOO_BIG" }, \
|
||||
{ NFS4ERR_REP_TOO_BIG_TO_CACHE, \
|
||||
"REP_TOO_BIG_TO_CACHE" }, \
|
||||
{ -NFS4ERR_REQ_TOO_BIG, "REQ_TOO_BIG" }, \
|
||||
{ -NFS4ERR_RESOURCE, "RESOURCE" }, \
|
||||
{ -NFS4ERR_RESTOREFH, "RESTOREFH" }, \
|
||||
{ -NFS4ERR_RETRY_UNCACHED_REP, "RETRY_UNCACHED_REP" }, \
|
||||
{ -NFS4ERR_RETURNCONFLICT, "RETURNCONFLICT" }, \
|
||||
{ -NFS4ERR_ROFS, "ROFS" }, \
|
||||
{ -NFS4ERR_SAME, "SAME" }, \
|
||||
{ -NFS4ERR_SHARE_DENIED, "SHARE_DENIED" }, \
|
||||
{ -NFS4ERR_SEQUENCE_POS, "SEQUENCE_POS" }, \
|
||||
{ -NFS4ERR_SEQ_FALSE_RETRY, "SEQ_FALSE_RETRY" }, \
|
||||
{ -NFS4ERR_SEQ_MISORDERED, "SEQ_MISORDERED" }, \
|
||||
{ -NFS4ERR_SERVERFAULT, "SERVERFAULT" }, \
|
||||
{ -NFS4ERR_STALE, "STALE" }, \
|
||||
{ -NFS4ERR_STALE_CLIENTID, "STALE_CLIENTID" }, \
|
||||
{ -NFS4ERR_STALE_STATEID, "STALE_STATEID" }, \
|
||||
{ -NFS4ERR_SYMLINK, "SYMLINK" }, \
|
||||
{ -NFS4ERR_TOOSMALL, "TOOSMALL" }, \
|
||||
{ -NFS4ERR_TOO_MANY_OPS, "TOO_MANY_OPS" }, \
|
||||
{ -NFS4ERR_UNKNOWN_LAYOUTTYPE, "UNKNOWN_LAYOUTTYPE" }, \
|
||||
{ -NFS4ERR_UNSAFE_COMPOUND, "UNSAFE_COMPOUND" }, \
|
||||
{ -NFS4ERR_WRONGSEC, "WRONGSEC" }, \
|
||||
{ -NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \
|
||||
{ -NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \
|
||||
{ -NFS4ERR_XDEV, "XDEV" })
|
||||
{ NFS4ERR_REQ_TOO_BIG, "REQ_TOO_BIG" }, \
|
||||
{ NFS4ERR_RESOURCE, "RESOURCE" }, \
|
||||
{ NFS4ERR_RESTOREFH, "RESTOREFH" }, \
|
||||
{ NFS4ERR_RETRY_UNCACHED_REP, "RETRY_UNCACHED_REP" }, \
|
||||
{ NFS4ERR_RETURNCONFLICT, "RETURNCONFLICT" }, \
|
||||
{ NFS4ERR_ROFS, "ROFS" }, \
|
||||
{ NFS4ERR_SAME, "SAME" }, \
|
||||
{ NFS4ERR_SHARE_DENIED, "SHARE_DENIED" }, \
|
||||
{ NFS4ERR_SEQUENCE_POS, "SEQUENCE_POS" }, \
|
||||
{ NFS4ERR_SEQ_FALSE_RETRY, "SEQ_FALSE_RETRY" }, \
|
||||
{ NFS4ERR_SEQ_MISORDERED, "SEQ_MISORDERED" }, \
|
||||
{ NFS4ERR_SERVERFAULT, "SERVERFAULT" }, \
|
||||
{ NFS4ERR_STALE, "STALE" }, \
|
||||
{ NFS4ERR_STALE_CLIENTID, "STALE_CLIENTID" }, \
|
||||
{ NFS4ERR_STALE_STATEID, "STALE_STATEID" }, \
|
||||
{ NFS4ERR_SYMLINK, "SYMLINK" }, \
|
||||
{ NFS4ERR_TOOSMALL, "TOOSMALL" }, \
|
||||
{ NFS4ERR_TOO_MANY_OPS, "TOO_MANY_OPS" }, \
|
||||
{ NFS4ERR_UNKNOWN_LAYOUTTYPE, "UNKNOWN_LAYOUTTYPE" }, \
|
||||
{ NFS4ERR_UNSAFE_COMPOUND, "UNSAFE_COMPOUND" }, \
|
||||
{ NFS4ERR_WRONGSEC, "WRONGSEC" }, \
|
||||
{ NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \
|
||||
{ NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \
|
||||
{ NFS4ERR_XDEV, "XDEV" })
|
||||
|
||||
#define show_open_flags(flags) \
|
||||
__print_flags(flags, "|", \
|
||||
@@ -558,6 +703,13 @@ TRACE_EVENT(nfs4_close,
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_DEFINE_ENUM(F_GETLK);
|
||||
TRACE_DEFINE_ENUM(F_SETLK);
|
||||
TRACE_DEFINE_ENUM(F_SETLKW);
|
||||
TRACE_DEFINE_ENUM(F_RDLCK);
|
||||
TRACE_DEFINE_ENUM(F_WRLCK);
|
||||
TRACE_DEFINE_ENUM(F_UNLCK);
|
||||
|
||||
#define show_lock_cmd(type) \
|
||||
__print_symbolic((int)type, \
|
||||
{ F_GETLK, "GETLK" }, \
|
||||
@@ -1451,6 +1603,10 @@ DEFINE_NFS4_COMMIT_EVENT(nfs4_commit);
|
||||
#ifdef CONFIG_NFS_V4_1
|
||||
DEFINE_NFS4_COMMIT_EVENT(nfs4_pnfs_commit_ds);
|
||||
|
||||
TRACE_DEFINE_ENUM(IOMODE_READ);
|
||||
TRACE_DEFINE_ENUM(IOMODE_RW);
|
||||
TRACE_DEFINE_ENUM(IOMODE_ANY);
|
||||
|
||||
#define show_pnfs_iomode(iomode) \
|
||||
__print_symbolic(iomode, \
|
||||
{ IOMODE_READ, "READ" }, \
|
||||
@@ -1528,6 +1684,20 @@ DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutcommit);
|
||||
DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutreturn);
|
||||
DEFINE_NFS4_INODE_EVENT(nfs4_layoutreturn_on_close);
|
||||
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_UNKNOWN);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_NO_PNFS);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_RD_ZEROLEN);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_MDSTHRESH);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_NOMEM);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_BULK_RECALL);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_IO_TEST_FAIL);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_FOUND_CACHED);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_RETURN);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_BLOCKED);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_INVALID_OPEN);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_RETRY);
|
||||
TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET);
|
||||
|
||||
#define show_pnfs_update_layout_reason(reason) \
|
||||
__print_symbolic(reason, \
|
||||
{ PNFS_UPDATE_LAYOUT_UNKNOWN, "unknown" }, \
|
||||
|
||||
@@ -461,7 +461,7 @@ EXPORT_SYMBOL_GPL(nfs_wait_on_request);
|
||||
* @prev: previous request in desc, or NULL
|
||||
* @req: this request
|
||||
*
|
||||
* Returns zero if @req can be coalesced into @desc, otherwise it returns
|
||||
* Returns zero if @req cannot be coalesced into @desc, otherwise it returns
|
||||
* the size of the request.
|
||||
*/
|
||||
size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
|
||||
@@ -587,7 +587,7 @@ static void nfs_pgio_prepare(struct rpc_task *task, void *calldata)
|
||||
}
|
||||
|
||||
int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
|
||||
struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops,
|
||||
const struct cred *cred, const struct nfs_rpc_ops *rpc_ops,
|
||||
const struct rpc_call_ops *call_ops, int how, int flags)
|
||||
{
|
||||
struct rpc_task *task;
|
||||
|
||||
@@ -275,7 +275,7 @@ pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo)
|
||||
list_del_init(&lo->plh_layouts);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
}
|
||||
put_rpccred(lo->plh_lc_cred);
|
||||
put_cred(lo->plh_lc_cred);
|
||||
return ld->free_layout_hdr(lo);
|
||||
}
|
||||
|
||||
@@ -1038,7 +1038,7 @@ pnfs_alloc_init_layoutget_args(struct inode *ino,
|
||||
lgp->args.ctx = get_nfs_open_context(ctx);
|
||||
nfs4_stateid_copy(&lgp->args.stateid, stateid);
|
||||
lgp->gfp_flags = gfp_flags;
|
||||
lgp->cred = get_rpccred(ctx->cred);
|
||||
lgp->cred = get_cred(ctx->cred);
|
||||
return lgp;
|
||||
}
|
||||
|
||||
@@ -1049,7 +1049,7 @@ void pnfs_layoutget_free(struct nfs4_layoutget *lgp)
|
||||
nfs4_free_pages(lgp->args.layout.pages, max_pages);
|
||||
if (lgp->args.inode)
|
||||
pnfs_put_layout_hdr(NFS_I(lgp->args.inode)->layout);
|
||||
put_rpccred(lgp->cred);
|
||||
put_cred(lgp->cred);
|
||||
put_nfs_open_context(lgp->args.ctx);
|
||||
kfree(lgp);
|
||||
}
|
||||
@@ -1324,7 +1324,7 @@ pnfs_commit_and_return_layout(struct inode *inode)
|
||||
bool pnfs_roc(struct inode *ino,
|
||||
struct nfs4_layoutreturn_args *args,
|
||||
struct nfs4_layoutreturn_res *res,
|
||||
const struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(ino);
|
||||
struct nfs_open_context *ctx;
|
||||
@@ -1583,7 +1583,7 @@ alloc_init_layout_hdr(struct inode *ino,
|
||||
INIT_LIST_HEAD(&lo->plh_return_segs);
|
||||
INIT_LIST_HEAD(&lo->plh_bulk_destroy);
|
||||
lo->plh_inode = ino;
|
||||
lo->plh_lc_cred = get_rpccred(ctx->cred);
|
||||
lo->plh_lc_cred = get_cred(ctx->cred);
|
||||
lo->plh_flags |= 1 << NFS_LAYOUT_INVALID_STID;
|
||||
return lo;
|
||||
}
|
||||
@@ -2928,7 +2928,7 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
|
||||
spin_unlock(&inode->i_lock);
|
||||
|
||||
data->args.inode = inode;
|
||||
data->cred = get_rpccred(nfsi->layout->plh_lc_cred);
|
||||
data->cred = get_cred(nfsi->layout->plh_lc_cred);
|
||||
nfs_fattr_init(&data->fattr);
|
||||
data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
|
||||
data->res.fattr = &data->fattr;
|
||||
@@ -2941,7 +2941,7 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
|
||||
if (ld->prepare_layoutcommit) {
|
||||
status = ld->prepare_layoutcommit(&data->args);
|
||||
if (status) {
|
||||
put_rpccred(data->cred);
|
||||
put_cred(data->cred);
|
||||
spin_lock(&inode->i_lock);
|
||||
set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags);
|
||||
if (end_pos > nfsi->layout->plh_lwb)
|
||||
|
||||
@@ -200,7 +200,7 @@ struct pnfs_layout_hdr {
|
||||
u32 plh_return_seq;
|
||||
enum pnfs_iomode plh_return_iomode;
|
||||
loff_t plh_lwb; /* last write byte for layoutcommit */
|
||||
struct rpc_cred *plh_lc_cred; /* layoutcommit cred */
|
||||
const struct cred *plh_lc_cred; /* layoutcommit cred */
|
||||
struct inode *plh_inode;
|
||||
};
|
||||
|
||||
@@ -230,7 +230,7 @@ extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);
|
||||
extern size_t max_response_pages(struct nfs_server *server);
|
||||
extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
|
||||
struct pnfs_device *dev,
|
||||
struct rpc_cred *cred);
|
||||
const struct cred *cred);
|
||||
extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout);
|
||||
extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync);
|
||||
|
||||
@@ -280,7 +280,7 @@ int pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
|
||||
bool pnfs_roc(struct inode *ino,
|
||||
struct nfs4_layoutreturn_args *args,
|
||||
struct nfs4_layoutreturn_res *res,
|
||||
const struct rpc_cred *cred);
|
||||
const struct cred *cred);
|
||||
void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
|
||||
struct nfs4_layoutreturn_res *res,
|
||||
int ret);
|
||||
@@ -343,7 +343,7 @@ struct nfs4_deviceid_node {
|
||||
|
||||
struct nfs4_deviceid_node *
|
||||
nfs4_find_get_deviceid(struct nfs_server *server,
|
||||
const struct nfs4_deviceid *id, struct rpc_cred *cred,
|
||||
const struct nfs4_deviceid *id, const struct cred *cred,
|
||||
gfp_t gfp_mask);
|
||||
void nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
|
||||
void nfs4_init_deviceid_node(struct nfs4_deviceid_node *, struct nfs_server *,
|
||||
@@ -694,7 +694,7 @@ static inline bool
|
||||
pnfs_roc(struct inode *ino,
|
||||
struct nfs4_layoutreturn_args *args,
|
||||
struct nfs4_layoutreturn_res *res,
|
||||
const struct rpc_cred *cred)
|
||||
const struct cred *cred)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ _lookup_deviceid(const struct pnfs_layoutdriver_type *ld,
|
||||
static struct nfs4_deviceid_node *
|
||||
nfs4_get_device_info(struct nfs_server *server,
|
||||
const struct nfs4_deviceid *dev_id,
|
||||
struct rpc_cred *cred, gfp_t gfp_flags)
|
||||
const struct cred *cred, gfp_t gfp_flags)
|
||||
{
|
||||
struct nfs4_deviceid_node *d = NULL;
|
||||
struct pnfs_device *pdev = NULL;
|
||||
@@ -184,7 +184,7 @@ __nfs4_find_get_deviceid(struct nfs_server *server,
|
||||
|
||||
struct nfs4_deviceid_node *
|
||||
nfs4_find_get_deviceid(struct nfs_server *server,
|
||||
const struct nfs4_deviceid *id, struct rpc_cred *cred,
|
||||
const struct nfs4_deviceid *id, const struct cred *cred,
|
||||
gfp_t gfp_mask)
|
||||
{
|
||||
long hash = nfs4_deviceid_hash(id);
|
||||
|
||||
@@ -686,7 +686,7 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
|
||||
rpc_clnt_setup_test_and_add_xprt,
|
||||
&rpcdata);
|
||||
if (xprtdata.cred)
|
||||
put_rpccred(xprtdata.cred);
|
||||
put_cred(xprtdata.cred);
|
||||
} else {
|
||||
clp = nfs4_set_ds_client(mds_srv,
|
||||
(struct sockaddr *)&da->da_addr,
|
||||
|
||||
@@ -490,7 +490,7 @@ nfs_proc_rmdir(struct inode *dir, const struct qstr *name)
|
||||
* from nfs_readdir by calling the decode_entry function directly.
|
||||
*/
|
||||
static int
|
||||
nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
|
||||
nfs_proc_readdir(struct dentry *dentry, const struct cred *cred,
|
||||
u64 cookie, struct page **pages, unsigned int count, bool plus)
|
||||
{
|
||||
struct inode *dir = d_inode(dentry);
|
||||
|
||||
@@ -2168,6 +2168,9 @@ static int nfs_validate_text_mount_data(void *options,
|
||||
|
||||
if (args->version == 4) {
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
|
||||
port = NFS_RDMA_PORT;
|
||||
else
|
||||
port = NFS_PORT;
|
||||
max_namelen = NFS4_MAXNAMLEN;
|
||||
max_pathlen = NFS4_MAXPATHLEN;
|
||||
@@ -2178,8 +2181,11 @@ static int nfs_validate_text_mount_data(void *options,
|
||||
#else
|
||||
goto out_v4_not_compiled;
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
} else
|
||||
} else {
|
||||
nfs_set_mount_transport_protocol(args);
|
||||
if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
|
||||
port = NFS_RDMA_PORT;
|
||||
}
|
||||
|
||||
nfs_set_port(sap, &args->nfs_server.port, port);
|
||||
|
||||
@@ -2409,8 +2415,7 @@ static int nfs_compare_mount_options(const struct super_block *s, const struct n
|
||||
goto Ebusy;
|
||||
if (a->acdirmax != b->acdirmax)
|
||||
goto Ebusy;
|
||||
if (b->auth_info.flavor_len > 0 &&
|
||||
clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
|
||||
if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
|
||||
goto Ebusy;
|
||||
return 1;
|
||||
Ebusy:
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
static void
|
||||
nfs_free_unlinkdata(struct nfs_unlinkdata *data)
|
||||
{
|
||||
put_rpccred(data->cred);
|
||||
put_cred(data->cred);
|
||||
kfree(data->args.name.name);
|
||||
kfree(data);
|
||||
}
|
||||
@@ -177,11 +177,7 @@ nfs_async_unlink(struct dentry *dentry, const struct qstr *name)
|
||||
goto out_free;
|
||||
data->args.name.len = name->len;
|
||||
|
||||
data->cred = rpc_lookup_cred();
|
||||
if (IS_ERR(data->cred)) {
|
||||
status = PTR_ERR(data->cred);
|
||||
goto out_free_name;
|
||||
}
|
||||
data->cred = get_current_cred();
|
||||
data->res.dir_attr = &data->dir_attr;
|
||||
init_waitqueue_head(&data->wq);
|
||||
|
||||
@@ -202,8 +198,7 @@ nfs_async_unlink(struct dentry *dentry, const struct qstr *name)
|
||||
return 0;
|
||||
out_unlock:
|
||||
spin_unlock(&dentry->d_lock);
|
||||
put_rpccred(data->cred);
|
||||
out_free_name:
|
||||
put_cred(data->cred);
|
||||
kfree(data->args.name.name);
|
||||
out_free:
|
||||
kfree(data);
|
||||
@@ -307,7 +302,7 @@ static void nfs_async_rename_release(void *calldata)
|
||||
iput(data->old_dir);
|
||||
iput(data->new_dir);
|
||||
nfs_sb_deactive(sb);
|
||||
put_rpccred(data->cred);
|
||||
put_cred(data->cred);
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
@@ -352,12 +347,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
task_setup_data.callback_data = data;
|
||||
|
||||
data->cred = rpc_lookup_cred();
|
||||
if (IS_ERR(data->cred)) {
|
||||
struct rpc_task *task = ERR_CAST(data->cred);
|
||||
kfree(data);
|
||||
return task;
|
||||
}
|
||||
data->cred = get_current_cred();
|
||||
|
||||
msg.rpc_argp = &data->args;
|
||||
msg.rpc_resp = &data->res;
|
||||
|
||||
@@ -1233,9 +1233,12 @@ int
|
||||
nfs_key_timeout_notify(struct file *filp, struct inode *inode)
|
||||
{
|
||||
struct nfs_open_context *ctx = nfs_file_open_context(filp);
|
||||
struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth;
|
||||
|
||||
return rpcauth_key_timeout_notify(auth, ctx->cred);
|
||||
if (nfs_ctx_key_to_expire(ctx, inode) &&
|
||||
!ctx->ll_cred)
|
||||
/* Already expired! */
|
||||
return -EACCES;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1244,8 +1247,23 @@ nfs_key_timeout_notify(struct file *filp, struct inode *inode)
|
||||
bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx, struct inode *inode)
|
||||
{
|
||||
struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth;
|
||||
struct rpc_cred *cred = ctx->ll_cred;
|
||||
struct auth_cred acred = {
|
||||
.cred = ctx->cred,
|
||||
};
|
||||
|
||||
return rpcauth_cred_key_to_expire(auth, ctx->cred);
|
||||
if (cred && !cred->cr_ops->crmatch(&acred, cred, 0)) {
|
||||
put_rpccred(cred);
|
||||
ctx->ll_cred = NULL;
|
||||
cred = NULL;
|
||||
}
|
||||
if (!cred)
|
||||
cred = auth->au_ops->lookup_cred(auth, &acred, 0);
|
||||
if (!cred || IS_ERR(cred))
|
||||
return true;
|
||||
ctx->ll_cred = cred;
|
||||
return !!(cred->cr_ops->crkey_timeout &&
|
||||
cred->cr_ops->crkey_timeout(cred));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -844,24 +844,23 @@ static int max_cb_time(struct net *net)
|
||||
return max(nn->nfsd4_lease/10, (time_t)1) * HZ;
|
||||
}
|
||||
|
||||
static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
|
||||
static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
|
||||
{
|
||||
if (clp->cl_minorversion == 0) {
|
||||
char *principal = clp->cl_cred.cr_targ_princ ?
|
||||
client->cl_principal = clp->cl_cred.cr_targ_princ ?
|
||||
clp->cl_cred.cr_targ_princ : "nfs";
|
||||
struct rpc_cred *cred;
|
||||
|
||||
cred = rpc_lookup_machine_cred(principal);
|
||||
if (!IS_ERR(cred))
|
||||
get_rpccred(cred);
|
||||
return cred;
|
||||
return get_cred(rpc_machine_cred());
|
||||
} else {
|
||||
struct rpc_auth *auth = client->cl_auth;
|
||||
struct auth_cred acred = {};
|
||||
struct cred *kcred;
|
||||
|
||||
acred.uid = ses->se_cb_sec.uid;
|
||||
acred.gid = ses->se_cb_sec.gid;
|
||||
return auth->au_ops->lookup_cred(client->cl_auth, &acred, 0);
|
||||
kcred = prepare_kernel_cred(NULL);
|
||||
if (!kcred)
|
||||
return NULL;
|
||||
|
||||
kcred->uid = ses->se_cb_sec.uid;
|
||||
kcred->gid = ses->se_cb_sec.gid;
|
||||
return kcred;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -884,7 +883,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
|
||||
.flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
|
||||
};
|
||||
struct rpc_clnt *client;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
|
||||
if (clp->cl_minorversion == 0) {
|
||||
if (!clp->cl_cred.cr_principal &&
|
||||
@@ -1214,7 +1213,7 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
|
||||
if (clp->cl_cb_client) {
|
||||
rpc_shutdown_client(clp->cl_cb_client);
|
||||
clp->cl_cb_client = NULL;
|
||||
put_rpccred(clp->cl_cb_cred);
|
||||
put_cred(clp->cl_cb_cred);
|
||||
clp->cl_cb_cred = NULL;
|
||||
}
|
||||
if (clp->cl_cb_conn.cb_xprt) {
|
||||
|
||||
@@ -327,7 +327,7 @@ struct nfs4_client {
|
||||
#define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \
|
||||
1 << NFSD4_CLIENT_CB_KILL)
|
||||
unsigned long cl_flags;
|
||||
struct rpc_cred *cl_cb_cred;
|
||||
const struct cred *cl_cb_cred;
|
||||
struct rpc_clnt *cl_cb_client;
|
||||
u32 cl_cb_ident;
|
||||
#define NFSD4_CB_UP 0
|
||||
|
||||
@@ -169,6 +169,7 @@ extern int change_create_files_as(struct cred *, struct inode *);
|
||||
extern int set_security_override(struct cred *, u32);
|
||||
extern int set_security_override_from_ctx(struct cred *, const char *);
|
||||
extern int set_create_files_as(struct cred *, struct inode *);
|
||||
extern int cred_fscmp(const struct cred *, const struct cred *);
|
||||
extern void __init cred_init(void);
|
||||
|
||||
/*
|
||||
@@ -236,7 +237,7 @@ static inline struct cred *get_new_cred(struct cred *cred)
|
||||
* @cred: The credentials to reference
|
||||
*
|
||||
* Get a reference on the specified set of credentials. The caller must
|
||||
* release the reference.
|
||||
* release the reference. If %NULL is passed, it is returned with no action.
|
||||
*
|
||||
* This is used to deal with a committed set of credentials. Although the
|
||||
* pointer is const, this will temporarily discard the const and increment the
|
||||
@@ -247,16 +248,29 @@ static inline struct cred *get_new_cred(struct cred *cred)
|
||||
static inline const struct cred *get_cred(const struct cred *cred)
|
||||
{
|
||||
struct cred *nonconst_cred = (struct cred *) cred;
|
||||
if (!cred)
|
||||
return cred;
|
||||
validate_creds(cred);
|
||||
return get_new_cred(nonconst_cred);
|
||||
}
|
||||
|
||||
static inline const struct cred *get_cred_rcu(const struct cred *cred)
|
||||
{
|
||||
struct cred *nonconst_cred = (struct cred *) cred;
|
||||
if (!cred)
|
||||
return NULL;
|
||||
if (!atomic_inc_not_zero(&nonconst_cred->usage))
|
||||
return NULL;
|
||||
validate_creds(cred);
|
||||
return cred;
|
||||
}
|
||||
|
||||
/**
|
||||
* put_cred - Release a reference to a set of credentials
|
||||
* @cred: The credentials to release
|
||||
*
|
||||
* Release a reference to a set of credentials, deleting them when the last ref
|
||||
* is released.
|
||||
* is released. If %NULL is passed, nothing is done.
|
||||
*
|
||||
* This takes a const pointer to a set of credentials because the credentials
|
||||
* on task_struct are attached by const pointers to prevent accidental
|
||||
@@ -266,9 +280,11 @@ static inline void put_cred(const struct cred *_cred)
|
||||
{
|
||||
struct cred *cred = (struct cred *) _cred;
|
||||
|
||||
if (cred) {
|
||||
validate_creds(cred);
|
||||
if (atomic_dec_and_test(&(cred)->usage))
|
||||
__put_cred(cred);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
struct nfs_access_entry {
|
||||
struct rb_node rb_node;
|
||||
struct list_head lru;
|
||||
struct rpc_cred * cred;
|
||||
const struct cred * cred;
|
||||
__u32 mask;
|
||||
struct rcu_head rcu_head;
|
||||
};
|
||||
@@ -70,7 +70,8 @@ struct nfs_open_context {
|
||||
struct nfs_lock_context lock_context;
|
||||
fl_owner_t flock_owner;
|
||||
struct dentry *dentry;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
struct rpc_cred *ll_cred; /* low-level cred - use to check for expiry */
|
||||
struct nfs4_state *state;
|
||||
fmode_t mode;
|
||||
|
||||
@@ -88,7 +89,7 @@ struct nfs_open_context {
|
||||
|
||||
struct nfs_open_dir_context {
|
||||
struct list_head list;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
unsigned long attr_gencount;
|
||||
__u64 dir_cookie;
|
||||
__u64 dup_cookie;
|
||||
@@ -390,7 +391,7 @@ extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
|
||||
struct nfs4_label *label);
|
||||
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);
|
||||
extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode);
|
||||
extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, const struct cred *cred, fmode_t mode);
|
||||
extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode, struct file *filp);
|
||||
extern void nfs_inode_attach_open_context(struct nfs_open_context *ctx);
|
||||
extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx);
|
||||
@@ -461,7 +462,7 @@ static inline struct nfs_open_context *nfs_file_open_context(struct file *filp)
|
||||
return filp->private_data;
|
||||
}
|
||||
|
||||
static inline struct rpc_cred *nfs_file_cred(struct file *file)
|
||||
static inline const struct cred *nfs_file_cred(struct file *file)
|
||||
{
|
||||
if (file != NULL) {
|
||||
struct nfs_open_context *ctx =
|
||||
@@ -490,7 +491,7 @@ extern const struct dentry_operations nfs_dentry_operations;
|
||||
extern void nfs_force_lookup_revalidate(struct inode *dir);
|
||||
extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh,
|
||||
struct nfs_fattr *fattr, struct nfs4_label *label);
|
||||
extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags);
|
||||
extern int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags);
|
||||
extern void nfs_access_zap_cache(struct inode *inode);
|
||||
|
||||
/*
|
||||
|
||||
@@ -58,7 +58,7 @@ struct nfs_client {
|
||||
struct nfs_subversion * cl_nfs_mod; /* pointer to nfs version module */
|
||||
|
||||
u32 cl_minorversion;/* NFSv4 minorversion */
|
||||
struct rpc_cred *cl_machine_cred;
|
||||
const char * cl_principal; /* used for machine cred */
|
||||
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
struct list_head cl_ds_clients; /* auth flavor data servers */
|
||||
|
||||
@@ -270,7 +270,7 @@ struct nfs4_layoutget_res {
|
||||
struct nfs4_layoutget {
|
||||
struct nfs4_layoutget_args args;
|
||||
struct nfs4_layoutget_res res;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
gfp_t gfp_flags;
|
||||
};
|
||||
|
||||
@@ -309,7 +309,7 @@ struct nfs4_layoutcommit_data {
|
||||
struct rpc_task task;
|
||||
struct nfs_fattr fattr;
|
||||
struct list_head lseg_list;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
struct inode *inode;
|
||||
struct nfs4_layoutcommit_args args;
|
||||
struct nfs4_layoutcommit_res res;
|
||||
@@ -334,7 +334,7 @@ struct nfs4_layoutreturn_res {
|
||||
struct nfs4_layoutreturn {
|
||||
struct nfs4_layoutreturn_args args;
|
||||
struct nfs4_layoutreturn_res res;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
struct nfs_client *clp;
|
||||
struct inode *inode;
|
||||
int rpc_status;
|
||||
@@ -1469,7 +1469,7 @@ enum {
|
||||
struct nfs_io_completion;
|
||||
struct nfs_pgio_header {
|
||||
struct inode *inode;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
struct list_head pages;
|
||||
struct nfs_page *req;
|
||||
struct nfs_writeverf verf; /* Used for writes */
|
||||
@@ -1529,7 +1529,7 @@ struct nfs_commit_info {
|
||||
struct nfs_commit_data {
|
||||
struct rpc_task task;
|
||||
struct inode *inode;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
struct nfs_fattr fattr;
|
||||
struct nfs_writeverf verf;
|
||||
struct list_head pages; /* Coalesced requests we wish to flush */
|
||||
@@ -1560,7 +1560,7 @@ struct nfs_unlinkdata {
|
||||
struct nfs_removeres res;
|
||||
struct dentry *dentry;
|
||||
wait_queue_head_t wq;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
struct nfs_fattr dir_attr;
|
||||
long timeout;
|
||||
};
|
||||
@@ -1568,7 +1568,7 @@ struct nfs_unlinkdata {
|
||||
struct nfs_renamedata {
|
||||
struct nfs_renameargs args;
|
||||
struct nfs_renameres res;
|
||||
struct rpc_cred *cred;
|
||||
const struct cred *cred;
|
||||
struct inode *old_dir;
|
||||
struct dentry *old_dentry;
|
||||
struct nfs_fattr old_fattr;
|
||||
@@ -1634,7 +1634,7 @@ struct nfs_rpc_ops {
|
||||
unsigned int, struct iattr *);
|
||||
int (*mkdir) (struct inode *, struct dentry *, struct iattr *);
|
||||
int (*rmdir) (struct inode *, const struct qstr *);
|
||||
int (*readdir) (struct dentry *, struct rpc_cred *,
|
||||
int (*readdir) (struct dentry *, const struct cred *,
|
||||
u64, struct page **, unsigned int, bool);
|
||||
int (*mknod) (struct inode *, struct dentry *, struct iattr *,
|
||||
dev_t);
|
||||
|
||||
@@ -37,21 +37,9 @@
|
||||
|
||||
struct rpcsec_gss_info;
|
||||
|
||||
/* auth_cred ac_flags bits */
|
||||
enum {
|
||||
RPC_CRED_KEY_EXPIRE_SOON = 1, /* underlying cred key will expire soon */
|
||||
RPC_CRED_NOTIFY_TIMEOUT = 2, /* nofity generic cred when underlying
|
||||
key will expire soon */
|
||||
};
|
||||
|
||||
/* Work around the lack of a VFS credential */
|
||||
struct auth_cred {
|
||||
kuid_t uid;
|
||||
kgid_t gid;
|
||||
struct group_info *group_info;
|
||||
const char *principal;
|
||||
unsigned long ac_flags;
|
||||
unsigned char machine_cred : 1;
|
||||
const struct cred *cred;
|
||||
const char *principal; /* If present, this is a machine credential */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -68,8 +56,7 @@ struct rpc_cred {
|
||||
unsigned long cr_expire; /* when to gc */
|
||||
unsigned long cr_flags; /* various flags */
|
||||
refcount_t cr_count; /* ref count */
|
||||
|
||||
kuid_t cr_uid;
|
||||
const struct cred *cr_cred;
|
||||
|
||||
/* per-flavor data */
|
||||
};
|
||||
@@ -78,8 +65,7 @@ struct rpc_cred {
|
||||
#define RPCAUTH_CRED_HASHED 2
|
||||
#define RPCAUTH_CRED_NEGATIVE 3
|
||||
|
||||
/* rpc_auth au_flags */
|
||||
#define RPCAUTH_AUTH_NO_CRKEY_TIMEOUT 0x0001 /* underlying cred has no key timeout */
|
||||
const struct cred *rpc_machine_cred(void);
|
||||
|
||||
/*
|
||||
* Client authentication handle
|
||||
@@ -116,7 +102,6 @@ struct rpc_auth_create_args {
|
||||
|
||||
/* Flags for rpcauth_lookupcred() */
|
||||
#define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */
|
||||
#define RPCAUTH_LOOKUP_RCU 0x02 /* lock-less lookup */
|
||||
|
||||
/*
|
||||
* Client authentication ops
|
||||
@@ -146,7 +131,6 @@ struct rpc_credops {
|
||||
void (*crdestroy)(struct rpc_cred *);
|
||||
|
||||
int (*crmatch)(struct auth_cred *, struct rpc_cred *, int);
|
||||
struct rpc_cred * (*crbind)(struct rpc_task *, struct rpc_cred *, int);
|
||||
__be32 * (*crmarshal)(struct rpc_task *, __be32 *);
|
||||
int (*crrefresh)(struct rpc_task *);
|
||||
__be32 * (*crvalidate)(struct rpc_task *, __be32 *);
|
||||
@@ -155,7 +139,6 @@ struct rpc_credops {
|
||||
int (*crunwrap_resp)(struct rpc_task *, kxdrdproc_t,
|
||||
void *, __be32 *, void *);
|
||||
int (*crkey_timeout)(struct rpc_cred *);
|
||||
bool (*crkey_to_expire)(struct rpc_cred *);
|
||||
char * (*crstringify_acceptor)(struct rpc_cred *);
|
||||
bool (*crneed_reencode)(struct rpc_task *);
|
||||
};
|
||||
@@ -164,16 +147,10 @@ extern const struct rpc_authops authunix_ops;
|
||||
extern const struct rpc_authops authnull_ops;
|
||||
|
||||
int __init rpc_init_authunix(void);
|
||||
int __init rpc_init_generic_auth(void);
|
||||
int __init rpcauth_init_module(void);
|
||||
void rpcauth_remove_module(void);
|
||||
void rpc_destroy_generic_auth(void);
|
||||
void rpc_destroy_authunix(void);
|
||||
|
||||
struct rpc_cred * rpc_lookup_cred(void);
|
||||
struct rpc_cred * rpc_lookup_cred_nonblock(void);
|
||||
struct rpc_cred * rpc_lookup_generic_cred(struct auth_cred *, int, gfp_t);
|
||||
struct rpc_cred * rpc_lookup_machine_cred(const char *service_name);
|
||||
int rpcauth_register(const struct rpc_authops *);
|
||||
int rpcauth_unregister(const struct rpc_authops *);
|
||||
struct rpc_auth * rpcauth_create(const struct rpc_auth_create_args *,
|
||||
@@ -187,7 +164,6 @@ int rpcauth_list_flavors(rpc_authflavor_t *, int);
|
||||
struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int, gfp_t);
|
||||
void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
|
||||
struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int);
|
||||
struct rpc_cred * rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred *, int);
|
||||
void put_rpccred(struct rpc_cred *);
|
||||
__be32 * rpcauth_marshcred(struct rpc_task *, __be32 *);
|
||||
__be32 * rpcauth_checkverf(struct rpc_task *, __be32 *);
|
||||
@@ -200,9 +176,6 @@ int rpcauth_uptodatecred(struct rpc_task *);
|
||||
int rpcauth_init_credcache(struct rpc_auth *);
|
||||
void rpcauth_destroy_credcache(struct rpc_auth *);
|
||||
void rpcauth_clear_credcache(struct rpc_cred_cache *);
|
||||
int rpcauth_key_timeout_notify(struct rpc_auth *,
|
||||
struct rpc_cred *);
|
||||
bool rpcauth_cred_key_to_expire(struct rpc_auth *, struct rpc_cred *);
|
||||
char * rpcauth_stringify_acceptor(struct rpc_cred *);
|
||||
|
||||
static inline
|
||||
@@ -213,21 +186,5 @@ struct rpc_cred *get_rpccred(struct rpc_cred *cred)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_rpccred_rcu - get a reference to a cred using rcu-protected pointer
|
||||
* @cred: cred of which to take a reference
|
||||
*
|
||||
* In some cases, we may have a pointer to a credential to which we
|
||||
* want to take a reference, but don't already have one. Because these
|
||||
* objects are freed using RCU, we can access the cr_count while its
|
||||
* on its way to destruction and only take a reference if it's not already
|
||||
* zero.
|
||||
*/
|
||||
static inline struct rpc_cred *
|
||||
get_rpccred_rcu(struct rpc_cred *cred)
|
||||
{
|
||||
return get_rpccred(cred);
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _LINUX_SUNRPC_AUTH_H */
|
||||
|
||||
@@ -66,6 +66,7 @@ struct rpc_clnt {
|
||||
struct rpc_rtt cl_rtt_default;
|
||||
struct rpc_timeout cl_timeout_default;
|
||||
const struct rpc_program *cl_program;
|
||||
const char * cl_principal; /* use for machine cred */
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
struct dentry *cl_debugfs; /* debugfs directory */
|
||||
#endif
|
||||
@@ -127,8 +128,8 @@ struct rpc_create_args {
|
||||
};
|
||||
|
||||
struct rpc_add_xprt_test {
|
||||
int (*add_xprt_test)(struct rpc_clnt *,
|
||||
struct rpc_xprt *,
|
||||
void (*add_xprt_test)(struct rpc_clnt *clnt,
|
||||
struct rpc_xprt *xprt,
|
||||
void *calldata);
|
||||
void *data;
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ struct rpc_message {
|
||||
const struct rpc_procinfo *rpc_proc; /* Procedure information */
|
||||
void * rpc_argp; /* Arguments */
|
||||
void * rpc_resp; /* Result */
|
||||
struct rpc_cred * rpc_cred; /* Credentials */
|
||||
const struct cred * rpc_cred; /* Credentials */
|
||||
};
|
||||
|
||||
struct rpc_call_ops;
|
||||
@@ -71,6 +71,7 @@ struct rpc_task {
|
||||
|
||||
struct rpc_clnt * tk_client; /* RPC client */
|
||||
struct rpc_xprt * tk_xprt; /* Transport */
|
||||
struct rpc_cred * tk_op_cred; /* cred being operated on */
|
||||
|
||||
struct rpc_rqst * tk_rqstp; /* RPC request */
|
||||
|
||||
@@ -105,6 +106,7 @@ struct rpc_task_setup {
|
||||
struct rpc_task *task;
|
||||
struct rpc_clnt *rpc_client;
|
||||
struct rpc_xprt *rpc_xprt;
|
||||
struct rpc_cred *rpc_op_cred; /* credential being operated on */
|
||||
const struct rpc_message *rpc_message;
|
||||
const struct rpc_call_ops *callback_ops;
|
||||
void *callback_data;
|
||||
@@ -118,6 +120,7 @@ struct rpc_task_setup {
|
||||
*/
|
||||
#define RPC_TASK_ASYNC 0x0001 /* is an async task */
|
||||
#define RPC_TASK_SWAPPER 0x0002 /* is swapping in/out */
|
||||
#define RPC_TASK_NULLCREDS 0x0010 /* Use AUTH_NULL credential */
|
||||
#define RPC_CALL_MAJORSEEN 0x0020 /* major timeout seen */
|
||||
#define RPC_TASK_ROOTCREDS 0x0040 /* force root creds */
|
||||
#define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */
|
||||
@@ -131,7 +134,6 @@ struct rpc_task_setup {
|
||||
|
||||
#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
|
||||
#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
|
||||
#define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS)
|
||||
#define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED)
|
||||
#define RPC_IS_SOFT(t) ((t)->tk_flags & (RPC_TASK_SOFT|RPC_TASK_TIMEOUT))
|
||||
#define RPC_IS_SOFTCONN(t) ((t)->tk_flags & RPC_TASK_SOFTCONN)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#if !defined(_TRACE_RPCRDMA_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_RPCRDMA_H
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/tracepoint.h>
|
||||
#include <trace/events/rdma.h>
|
||||
|
||||
@@ -97,7 +98,6 @@ DECLARE_EVENT_CLASS(xprtrdma_rdch_event,
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, task_id)
|
||||
__field(unsigned int, client_id)
|
||||
__field(const void *, mr)
|
||||
__field(unsigned int, pos)
|
||||
__field(int, nents)
|
||||
__field(u32, handle)
|
||||
@@ -109,7 +109,6 @@ DECLARE_EVENT_CLASS(xprtrdma_rdch_event,
|
||||
TP_fast_assign(
|
||||
__entry->task_id = task->tk_pid;
|
||||
__entry->client_id = task->tk_client->cl_clid;
|
||||
__entry->mr = mr;
|
||||
__entry->pos = pos;
|
||||
__entry->nents = mr->mr_nents;
|
||||
__entry->handle = mr->mr_handle;
|
||||
@@ -118,8 +117,8 @@ DECLARE_EVENT_CLASS(xprtrdma_rdch_event,
|
||||
__entry->nsegs = nsegs;
|
||||
),
|
||||
|
||||
TP_printk("task:%u@%u mr=%p pos=%u %u@0x%016llx:0x%08x (%s)",
|
||||
__entry->task_id, __entry->client_id, __entry->mr,
|
||||
TP_printk("task:%u@%u pos=%u %u@0x%016llx:0x%08x (%s)",
|
||||
__entry->task_id, __entry->client_id,
|
||||
__entry->pos, __entry->length,
|
||||
(unsigned long long)__entry->offset, __entry->handle,
|
||||
__entry->nents < __entry->nsegs ? "more" : "last"
|
||||
@@ -127,7 +126,7 @@ DECLARE_EVENT_CLASS(xprtrdma_rdch_event,
|
||||
);
|
||||
|
||||
#define DEFINE_RDCH_EVENT(name) \
|
||||
DEFINE_EVENT(xprtrdma_rdch_event, name, \
|
||||
DEFINE_EVENT(xprtrdma_rdch_event, xprtrdma_chunk_##name,\
|
||||
TP_PROTO( \
|
||||
const struct rpc_task *task, \
|
||||
unsigned int pos, \
|
||||
@@ -148,7 +147,6 @@ DECLARE_EVENT_CLASS(xprtrdma_wrch_event,
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, task_id)
|
||||
__field(unsigned int, client_id)
|
||||
__field(const void *, mr)
|
||||
__field(int, nents)
|
||||
__field(u32, handle)
|
||||
__field(u32, length)
|
||||
@@ -159,7 +157,6 @@ DECLARE_EVENT_CLASS(xprtrdma_wrch_event,
|
||||
TP_fast_assign(
|
||||
__entry->task_id = task->tk_pid;
|
||||
__entry->client_id = task->tk_client->cl_clid;
|
||||
__entry->mr = mr;
|
||||
__entry->nents = mr->mr_nents;
|
||||
__entry->handle = mr->mr_handle;
|
||||
__entry->length = mr->mr_length;
|
||||
@@ -167,8 +164,8 @@ DECLARE_EVENT_CLASS(xprtrdma_wrch_event,
|
||||
__entry->nsegs = nsegs;
|
||||
),
|
||||
|
||||
TP_printk("task:%u@%u mr=%p %u@0x%016llx:0x%08x (%s)",
|
||||
__entry->task_id, __entry->client_id, __entry->mr,
|
||||
TP_printk("task:%u@%u %u@0x%016llx:0x%08x (%s)",
|
||||
__entry->task_id, __entry->client_id,
|
||||
__entry->length, (unsigned long long)__entry->offset,
|
||||
__entry->handle,
|
||||
__entry->nents < __entry->nsegs ? "more" : "last"
|
||||
@@ -176,7 +173,7 @@ DECLARE_EVENT_CLASS(xprtrdma_wrch_event,
|
||||
);
|
||||
|
||||
#define DEFINE_WRCH_EVENT(name) \
|
||||
DEFINE_EVENT(xprtrdma_wrch_event, name, \
|
||||
DEFINE_EVENT(xprtrdma_wrch_event, xprtrdma_chunk_##name,\
|
||||
TP_PROTO( \
|
||||
const struct rpc_task *task, \
|
||||
struct rpcrdma_mr *mr, \
|
||||
@@ -234,6 +231,18 @@ DECLARE_EVENT_CLASS(xprtrdma_frwr_done,
|
||||
), \
|
||||
TP_ARGS(wc, frwr))
|
||||
|
||||
TRACE_DEFINE_ENUM(DMA_BIDIRECTIONAL);
|
||||
TRACE_DEFINE_ENUM(DMA_TO_DEVICE);
|
||||
TRACE_DEFINE_ENUM(DMA_FROM_DEVICE);
|
||||
TRACE_DEFINE_ENUM(DMA_NONE);
|
||||
|
||||
#define xprtrdma_show_direction(x) \
|
||||
__print_symbolic(x, \
|
||||
{ DMA_BIDIRECTIONAL, "BIDIR" }, \
|
||||
{ DMA_TO_DEVICE, "TO_DEVICE" }, \
|
||||
{ DMA_FROM_DEVICE, "FROM_DEVICE" }, \
|
||||
{ DMA_NONE, "NONE" })
|
||||
|
||||
DECLARE_EVENT_CLASS(xprtrdma_mr,
|
||||
TP_PROTO(
|
||||
const struct rpcrdma_mr *mr
|
||||
@@ -246,6 +255,7 @@ DECLARE_EVENT_CLASS(xprtrdma_mr,
|
||||
__field(u32, handle)
|
||||
__field(u32, length)
|
||||
__field(u64, offset)
|
||||
__field(u32, dir)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
@@ -253,12 +263,13 @@ DECLARE_EVENT_CLASS(xprtrdma_mr,
|
||||
__entry->handle = mr->mr_handle;
|
||||
__entry->length = mr->mr_length;
|
||||
__entry->offset = mr->mr_offset;
|
||||
__entry->dir = mr->mr_dir;
|
||||
),
|
||||
|
||||
TP_printk("mr=%p %u@0x%016llx:0x%08x",
|
||||
TP_printk("mr=%p %u@0x%016llx:0x%08x (%s)",
|
||||
__entry->mr, __entry->length,
|
||||
(unsigned long long)__entry->offset,
|
||||
__entry->handle
|
||||
(unsigned long long)__entry->offset, __entry->handle,
|
||||
xprtrdma_show_direction(__entry->dir)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -371,11 +382,13 @@ TRACE_EVENT(xprtrdma_disconnect,
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_conn_start);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_conn_tout);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_create);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_destroy);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_op_destroy);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_remove);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_reinsert);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_reconnect);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_inject_dsc);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_op_inject_dsc);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_op_close);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_op_connect);
|
||||
|
||||
TRACE_EVENT(xprtrdma_qp_event,
|
||||
TP_PROTO(
|
||||
@@ -437,9 +450,9 @@ TRACE_EVENT(xprtrdma_createmrs,
|
||||
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_nomrs);
|
||||
|
||||
DEFINE_RDCH_EVENT(xprtrdma_read_chunk);
|
||||
DEFINE_WRCH_EVENT(xprtrdma_write_chunk);
|
||||
DEFINE_WRCH_EVENT(xprtrdma_reply_chunk);
|
||||
DEFINE_RDCH_EVENT(read);
|
||||
DEFINE_WRCH_EVENT(write);
|
||||
DEFINE_WRCH_EVENT(reply);
|
||||
|
||||
TRACE_DEFINE_ENUM(rpcrdma_noch);
|
||||
TRACE_DEFINE_ENUM(rpcrdma_readch);
|
||||
@@ -570,7 +583,7 @@ TRACE_EVENT(xprtrdma_post_recvs,
|
||||
__entry->r_xprt = r_xprt;
|
||||
__entry->count = count;
|
||||
__entry->status = status;
|
||||
__entry->posted = r_xprt->rx_buf.rb_posted_receives;
|
||||
__entry->posted = r_xprt->rx_ep.rep_receive_count;
|
||||
__assign_str(addr, rpcrdma_addrstr(r_xprt));
|
||||
__assign_str(port, rpcrdma_portstr(r_xprt));
|
||||
),
|
||||
@@ -651,12 +664,147 @@ DEFINE_FRWR_DONE_EVENT(xprtrdma_wc_fastreg);
|
||||
DEFINE_FRWR_DONE_EVENT(xprtrdma_wc_li);
|
||||
DEFINE_FRWR_DONE_EVENT(xprtrdma_wc_li_wake);
|
||||
|
||||
TRACE_EVENT(xprtrdma_frwr_alloc,
|
||||
TP_PROTO(
|
||||
const struct rpcrdma_mr *mr,
|
||||
int rc
|
||||
),
|
||||
|
||||
TP_ARGS(mr, rc),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(const void *, mr)
|
||||
__field(int, rc)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->mr = mr;
|
||||
__entry->rc = rc;
|
||||
),
|
||||
|
||||
TP_printk("mr=%p: rc=%d",
|
||||
__entry->mr, __entry->rc
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(xprtrdma_frwr_dereg,
|
||||
TP_PROTO(
|
||||
const struct rpcrdma_mr *mr,
|
||||
int rc
|
||||
),
|
||||
|
||||
TP_ARGS(mr, rc),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(const void *, mr)
|
||||
__field(u32, handle)
|
||||
__field(u32, length)
|
||||
__field(u64, offset)
|
||||
__field(u32, dir)
|
||||
__field(int, rc)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->mr = mr;
|
||||
__entry->handle = mr->mr_handle;
|
||||
__entry->length = mr->mr_length;
|
||||
__entry->offset = mr->mr_offset;
|
||||
__entry->dir = mr->mr_dir;
|
||||
__entry->rc = rc;
|
||||
),
|
||||
|
||||
TP_printk("mr=%p %u@0x%016llx:0x%08x (%s): rc=%d",
|
||||
__entry->mr, __entry->length,
|
||||
(unsigned long long)__entry->offset, __entry->handle,
|
||||
xprtrdma_show_direction(__entry->dir),
|
||||
__entry->rc
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(xprtrdma_frwr_sgerr,
|
||||
TP_PROTO(
|
||||
const struct rpcrdma_mr *mr,
|
||||
int sg_nents
|
||||
),
|
||||
|
||||
TP_ARGS(mr, sg_nents),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(const void *, mr)
|
||||
__field(u64, addr)
|
||||
__field(u32, dir)
|
||||
__field(int, nents)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->mr = mr;
|
||||
__entry->addr = mr->mr_sg->dma_address;
|
||||
__entry->dir = mr->mr_dir;
|
||||
__entry->nents = sg_nents;
|
||||
),
|
||||
|
||||
TP_printk("mr=%p dma addr=0x%llx (%s) sg_nents=%d",
|
||||
__entry->mr, __entry->addr,
|
||||
xprtrdma_show_direction(__entry->dir),
|
||||
__entry->nents
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(xprtrdma_frwr_maperr,
|
||||
TP_PROTO(
|
||||
const struct rpcrdma_mr *mr,
|
||||
int num_mapped
|
||||
),
|
||||
|
||||
TP_ARGS(mr, num_mapped),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(const void *, mr)
|
||||
__field(u64, addr)
|
||||
__field(u32, dir)
|
||||
__field(int, num_mapped)
|
||||
__field(int, nents)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->mr = mr;
|
||||
__entry->addr = mr->mr_sg->dma_address;
|
||||
__entry->dir = mr->mr_dir;
|
||||
__entry->num_mapped = num_mapped;
|
||||
__entry->nents = mr->mr_nents;
|
||||
),
|
||||
|
||||
TP_printk("mr=%p dma addr=0x%llx (%s) nents=%d of %d",
|
||||
__entry->mr, __entry->addr,
|
||||
xprtrdma_show_direction(__entry->dir),
|
||||
__entry->num_mapped, __entry->nents
|
||||
)
|
||||
);
|
||||
|
||||
DEFINE_MR_EVENT(localinv);
|
||||
DEFINE_MR_EVENT(map);
|
||||
DEFINE_MR_EVENT(unmap);
|
||||
DEFINE_MR_EVENT(remoteinv);
|
||||
DEFINE_MR_EVENT(recycle);
|
||||
|
||||
TRACE_EVENT(xprtrdma_dma_maperr,
|
||||
TP_PROTO(
|
||||
u64 addr
|
||||
),
|
||||
|
||||
TP_ARGS(addr),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(u64, addr)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->addr = addr;
|
||||
),
|
||||
|
||||
TP_printk("dma addr=0x%llx\n", __entry->addr)
|
||||
);
|
||||
|
||||
/**
|
||||
** Reply events
|
||||
**/
|
||||
@@ -824,7 +972,7 @@ TRACE_EVENT(xprtrdma_decode_seg,
|
||||
** Allocation/release of rpcrdma_reqs and rpcrdma_reps
|
||||
**/
|
||||
|
||||
TRACE_EVENT(xprtrdma_allocate,
|
||||
TRACE_EVENT(xprtrdma_op_allocate,
|
||||
TP_PROTO(
|
||||
const struct rpc_task *task,
|
||||
const struct rpcrdma_req *req
|
||||
@@ -854,7 +1002,7 @@ TRACE_EVENT(xprtrdma_allocate,
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(xprtrdma_rpc_done,
|
||||
TRACE_EVENT(xprtrdma_op_free,
|
||||
TP_PROTO(
|
||||
const struct rpc_task *task,
|
||||
const struct rpcrdma_req *req
|
||||
@@ -917,6 +1065,34 @@ TRACE_EVENT(xprtrdma_cb_setup,
|
||||
DEFINE_CB_EVENT(xprtrdma_cb_call);
|
||||
DEFINE_CB_EVENT(xprtrdma_cb_reply);
|
||||
|
||||
TRACE_EVENT(xprtrdma_leaked_rep,
|
||||
TP_PROTO(
|
||||
const struct rpc_rqst *rqst,
|
||||
const struct rpcrdma_rep *rep
|
||||
),
|
||||
|
||||
TP_ARGS(rqst, rep),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, task_id)
|
||||
__field(unsigned int, client_id)
|
||||
__field(u32, xid)
|
||||
__field(const void *, rep)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->task_id = rqst->rq_task->tk_pid;
|
||||
__entry->client_id = rqst->rq_task->tk_client->cl_clid;
|
||||
__entry->xid = be32_to_cpu(rqst->rq_xid);
|
||||
__entry->rep = rep;
|
||||
),
|
||||
|
||||
TP_printk("task:%u@%u xid=0x%08x rep=%p",
|
||||
__entry->task_id, __entry->client_id, __entry->xid,
|
||||
__entry->rep
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
** Server-side RPC/RDMA events
|
||||
**/
|
||||
|
||||
@@ -16,40 +16,6 @@
|
||||
|
||||
DECLARE_EVENT_CLASS(rpc_task_status,
|
||||
|
||||
TP_PROTO(struct rpc_task *task),
|
||||
|
||||
TP_ARGS(task),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, task_id)
|
||||
__field(unsigned int, client_id)
|
||||
__field(int, status)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->task_id = task->tk_pid;
|
||||
__entry->client_id = task->tk_client->cl_clid;
|
||||
__entry->status = task->tk_status;
|
||||
),
|
||||
|
||||
TP_printk("task:%u@%u status=%d",
|
||||
__entry->task_id, __entry->client_id,
|
||||
__entry->status)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(rpc_task_status, rpc_call_status,
|
||||
TP_PROTO(struct rpc_task *task),
|
||||
|
||||
TP_ARGS(task)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(rpc_task_status, rpc_bind_status,
|
||||
TP_PROTO(struct rpc_task *task),
|
||||
|
||||
TP_ARGS(task)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rpc_connect_status,
|
||||
TP_PROTO(const struct rpc_task *task),
|
||||
|
||||
TP_ARGS(task),
|
||||
@@ -70,6 +36,16 @@ TRACE_EVENT(rpc_connect_status,
|
||||
__entry->task_id, __entry->client_id,
|
||||
__entry->status)
|
||||
);
|
||||
#define DEFINE_RPC_STATUS_EVENT(name) \
|
||||
DEFINE_EVENT(rpc_task_status, rpc_##name##_status, \
|
||||
TP_PROTO( \
|
||||
const struct rpc_task *task \
|
||||
), \
|
||||
TP_ARGS(task))
|
||||
|
||||
DEFINE_RPC_STATUS_EVENT(call);
|
||||
DEFINE_RPC_STATUS_EVENT(bind);
|
||||
DEFINE_RPC_STATUS_EVENT(connect);
|
||||
|
||||
TRACE_EVENT(rpc_request,
|
||||
TP_PROTO(const struct rpc_task *task),
|
||||
@@ -134,30 +110,17 @@ DECLARE_EVENT_CLASS(rpc_task_running,
|
||||
__entry->action
|
||||
)
|
||||
);
|
||||
#define DEFINE_RPC_RUNNING_EVENT(name) \
|
||||
DEFINE_EVENT(rpc_task_running, rpc_task_##name, \
|
||||
TP_PROTO( \
|
||||
const struct rpc_task *task, \
|
||||
const void *action \
|
||||
), \
|
||||
TP_ARGS(task, action))
|
||||
|
||||
DEFINE_EVENT(rpc_task_running, rpc_task_begin,
|
||||
|
||||
TP_PROTO(const struct rpc_task *task, const void *action),
|
||||
|
||||
TP_ARGS(task, action)
|
||||
|
||||
);
|
||||
|
||||
DEFINE_EVENT(rpc_task_running, rpc_task_run_action,
|
||||
|
||||
TP_PROTO(const struct rpc_task *task, const void *action),
|
||||
|
||||
TP_ARGS(task, action)
|
||||
|
||||
);
|
||||
|
||||
DEFINE_EVENT(rpc_task_running, rpc_task_complete,
|
||||
|
||||
TP_PROTO(const struct rpc_task *task, const void *action),
|
||||
|
||||
TP_ARGS(task, action)
|
||||
|
||||
);
|
||||
DEFINE_RPC_RUNNING_EVENT(begin);
|
||||
DEFINE_RPC_RUNNING_EVENT(run_action);
|
||||
DEFINE_RPC_RUNNING_EVENT(complete);
|
||||
|
||||
DECLARE_EVENT_CLASS(rpc_task_queued,
|
||||
|
||||
@@ -195,22 +158,16 @@ DECLARE_EVENT_CLASS(rpc_task_queued,
|
||||
__get_str(q_name)
|
||||
)
|
||||
);
|
||||
#define DEFINE_RPC_QUEUED_EVENT(name) \
|
||||
DEFINE_EVENT(rpc_task_queued, rpc_task_##name, \
|
||||
TP_PROTO( \
|
||||
const struct rpc_task *task, \
|
||||
const struct rpc_wait_queue *q \
|
||||
), \
|
||||
TP_ARGS(task, q))
|
||||
|
||||
DEFINE_EVENT(rpc_task_queued, rpc_task_sleep,
|
||||
|
||||
TP_PROTO(const struct rpc_task *task, const struct rpc_wait_queue *q),
|
||||
|
||||
TP_ARGS(task, q)
|
||||
|
||||
);
|
||||
|
||||
DEFINE_EVENT(rpc_task_queued, rpc_task_wakeup,
|
||||
|
||||
TP_PROTO(const struct rpc_task *task, const struct rpc_wait_queue *q),
|
||||
|
||||
TP_ARGS(task, q)
|
||||
|
||||
);
|
||||
DEFINE_RPC_QUEUED_EVENT(sleep);
|
||||
DEFINE_RPC_QUEUED_EVENT(wakeup);
|
||||
|
||||
TRACE_EVENT(rpc_stats_latency,
|
||||
|
||||
@@ -410,7 +367,11 @@ DEFINE_RPC_SOCKET_EVENT(rpc_socket_close);
|
||||
DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown);
|
||||
|
||||
DECLARE_EVENT_CLASS(rpc_xprt_event,
|
||||
TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
|
||||
TP_PROTO(
|
||||
const struct rpc_xprt *xprt,
|
||||
__be32 xid,
|
||||
int status
|
||||
),
|
||||
|
||||
TP_ARGS(xprt, xid, status),
|
||||
|
||||
@@ -432,22 +393,19 @@ DECLARE_EVENT_CLASS(rpc_xprt_event,
|
||||
__get_str(port), __entry->xid,
|
||||
__entry->status)
|
||||
);
|
||||
#define DEFINE_RPC_XPRT_EVENT(name) \
|
||||
DEFINE_EVENT(rpc_xprt_event, xprt_##name, \
|
||||
TP_PROTO( \
|
||||
const struct rpc_xprt *xprt, \
|
||||
__be32 xid, \
|
||||
int status \
|
||||
), \
|
||||
TP_ARGS(xprt, xid, status))
|
||||
|
||||
DEFINE_EVENT(rpc_xprt_event, xprt_timer,
|
||||
TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
|
||||
TP_ARGS(xprt, xid, status));
|
||||
|
||||
DEFINE_EVENT(rpc_xprt_event, xprt_lookup_rqst,
|
||||
TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
|
||||
TP_ARGS(xprt, xid, status));
|
||||
|
||||
DEFINE_EVENT(rpc_xprt_event, xprt_transmit,
|
||||
TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
|
||||
TP_ARGS(xprt, xid, status));
|
||||
|
||||
DEFINE_EVENT(rpc_xprt_event, xprt_complete_rqst,
|
||||
TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
|
||||
TP_ARGS(xprt, xid, status));
|
||||
DEFINE_RPC_XPRT_EVENT(timer);
|
||||
DEFINE_RPC_XPRT_EVENT(lookup_rqst);
|
||||
DEFINE_RPC_XPRT_EVENT(transmit);
|
||||
DEFINE_RPC_XPRT_EVENT(complete_rqst);
|
||||
|
||||
TRACE_EVENT(xprt_ping,
|
||||
TP_PROTO(const struct rpc_xprt *xprt, int status),
|
||||
@@ -589,7 +547,9 @@ TRACE_EVENT(svc_process,
|
||||
|
||||
DECLARE_EVENT_CLASS(svc_rqst_event,
|
||||
|
||||
TP_PROTO(struct svc_rqst *rqst),
|
||||
TP_PROTO(
|
||||
const struct svc_rqst *rqst
|
||||
),
|
||||
|
||||
TP_ARGS(rqst),
|
||||
|
||||
@@ -609,14 +569,15 @@ DECLARE_EVENT_CLASS(svc_rqst_event,
|
||||
__get_str(addr), __entry->xid,
|
||||
show_rqstp_flags(__entry->flags))
|
||||
);
|
||||
#define DEFINE_SVC_RQST_EVENT(name) \
|
||||
DEFINE_EVENT(svc_rqst_event, svc_##name, \
|
||||
TP_PROTO( \
|
||||
const struct svc_rqst *rqst \
|
||||
), \
|
||||
TP_ARGS(rqst))
|
||||
|
||||
DEFINE_EVENT(svc_rqst_event, svc_defer,
|
||||
TP_PROTO(struct svc_rqst *rqst),
|
||||
TP_ARGS(rqst));
|
||||
|
||||
DEFINE_EVENT(svc_rqst_event, svc_drop,
|
||||
TP_PROTO(struct svc_rqst *rqst),
|
||||
TP_ARGS(rqst));
|
||||
DEFINE_SVC_RQST_EVENT(defer);
|
||||
DEFINE_SVC_RQST_EVENT(drop);
|
||||
|
||||
DECLARE_EVENT_CLASS(svc_rqst_status,
|
||||
|
||||
@@ -803,7 +764,9 @@ TRACE_EVENT(svc_stats_latency,
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(svc_deferred_event,
|
||||
TP_PROTO(struct svc_deferred_req *dr),
|
||||
TP_PROTO(
|
||||
const struct svc_deferred_req *dr
|
||||
),
|
||||
|
||||
TP_ARGS(dr),
|
||||
|
||||
@@ -820,13 +783,16 @@ DECLARE_EVENT_CLASS(svc_deferred_event,
|
||||
|
||||
TP_printk("addr=%s xid=0x%08x", __get_str(addr), __entry->xid)
|
||||
);
|
||||
#define DEFINE_SVC_DEFERRED_EVENT(name) \
|
||||
DEFINE_EVENT(svc_deferred_event, svc_##name##_deferred, \
|
||||
TP_PROTO( \
|
||||
const struct svc_deferred_req *dr \
|
||||
), \
|
||||
TP_ARGS(dr))
|
||||
|
||||
DEFINE_SVC_DEFERRED_EVENT(drop);
|
||||
DEFINE_SVC_DEFERRED_EVENT(revisit);
|
||||
|
||||
DEFINE_EVENT(svc_deferred_event, svc_drop_deferred,
|
||||
TP_PROTO(struct svc_deferred_req *dr),
|
||||
TP_ARGS(dr));
|
||||
DEFINE_EVENT(svc_deferred_event, svc_revisit_deferred,
|
||||
TP_PROTO(struct svc_deferred_req *dr),
|
||||
TP_ARGS(dr));
|
||||
#endif /* _TRACE_SUNRPC_H */
|
||||
|
||||
#include <trace/define_trace.h>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/security.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/cn_proc.h>
|
||||
#include <linux/uidgid.h>
|
||||
|
||||
#if 0
|
||||
#define kdebug(FMT, ...) \
|
||||
@@ -194,11 +195,12 @@ const struct cred *get_task_cred(struct task_struct *task)
|
||||
do {
|
||||
cred = __task_cred((task));
|
||||
BUG_ON(!cred);
|
||||
} while (!atomic_inc_not_zero(&((struct cred *)cred)->usage));
|
||||
} while (!get_cred_rcu(cred));
|
||||
|
||||
rcu_read_unlock();
|
||||
return cred;
|
||||
}
|
||||
EXPORT_SYMBOL(get_task_cred);
|
||||
|
||||
/*
|
||||
* Allocate blank credentials, such that the credentials can be filled in at a
|
||||
@@ -564,6 +566,60 @@ void revert_creds(const struct cred *old)
|
||||
}
|
||||
EXPORT_SYMBOL(revert_creds);
|
||||
|
||||
/**
|
||||
* cred_fscmp - Compare two credentials with respect to filesystem access.
|
||||
* @a: The first credential
|
||||
* @b: The second credential
|
||||
*
|
||||
* cred_cmp() will return zero if both credentials have the same
|
||||
* fsuid, fsgid, and supplementary groups. That is, if they will both
|
||||
* provide the same access to files based on mode/uid/gid.
|
||||
* If the credentials are different, then either -1 or 1 will
|
||||
* be returned depending on whether @a comes before or after @b
|
||||
* respectively in an arbitrary, but stable, ordering of credentials.
|
||||
*
|
||||
* Return: -1, 0, or 1 depending on comparison
|
||||
*/
|
||||
int cred_fscmp(const struct cred *a, const struct cred *b)
|
||||
{
|
||||
struct group_info *ga, *gb;
|
||||
int g;
|
||||
|
||||
if (a == b)
|
||||
return 0;
|
||||
if (uid_lt(a->fsuid, b->fsuid))
|
||||
return -1;
|
||||
if (uid_gt(a->fsuid, b->fsuid))
|
||||
return 1;
|
||||
|
||||
if (gid_lt(a->fsgid, b->fsgid))
|
||||
return -1;
|
||||
if (gid_gt(a->fsgid, b->fsgid))
|
||||
return 1;
|
||||
|
||||
ga = a->group_info;
|
||||
gb = b->group_info;
|
||||
if (ga == gb)
|
||||
return 0;
|
||||
if (ga == NULL)
|
||||
return -1;
|
||||
if (gb == NULL)
|
||||
return 1;
|
||||
if (ga->ngroups < gb->ngroups)
|
||||
return -1;
|
||||
if (ga->ngroups > gb->ngroups)
|
||||
return 1;
|
||||
|
||||
for (g = 0; g < ga->ngroups; g++) {
|
||||
if (gid_lt(ga->gid[g], gb->gid[g]))
|
||||
return -1;
|
||||
if (gid_gt(ga->gid[g], gb->gid[g]))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cred_fscmp);
|
||||
|
||||
/*
|
||||
* initialise the credentials stuff
|
||||
*/
|
||||
|
||||
@@ -9,7 +9,7 @@ obj-$(CONFIG_SUNRPC_GSS) += auth_gss/
|
||||
obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma/
|
||||
|
||||
sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
|
||||
auth.o auth_null.o auth_unix.o auth_generic.o \
|
||||
auth.o auth_null.o auth_unix.o \
|
||||
svc.o svcsock.o svcauth.o svcauth_unix.o \
|
||||
addr.o rpcb_clnt.o timer.o xdr.o \
|
||||
sunrpc_syms.o cache.o rpc_pipe.o \
|
||||
|
||||
@@ -39,6 +39,20 @@ static const struct rpc_authops __rcu *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
|
||||
static LIST_HEAD(cred_unused);
|
||||
static unsigned long number_cred_unused;
|
||||
|
||||
static struct cred machine_cred = {
|
||||
.usage = ATOMIC_INIT(1),
|
||||
};
|
||||
|
||||
/*
|
||||
* Return the machine_cred pointer to be used whenever
|
||||
* the a generic machine credential is needed.
|
||||
*/
|
||||
const struct cred *rpc_machine_cred(void)
|
||||
{
|
||||
return &machine_cred;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpc_machine_cred);
|
||||
|
||||
#define MAX_HASHTABLE_BITS (14)
|
||||
static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
@@ -346,29 +360,6 @@ out_nocache:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpcauth_init_credcache);
|
||||
|
||||
/*
|
||||
* Setup a credential key lifetime timeout notification
|
||||
*/
|
||||
int
|
||||
rpcauth_key_timeout_notify(struct rpc_auth *auth, struct rpc_cred *cred)
|
||||
{
|
||||
if (!cred->cr_auth->au_ops->key_timeout)
|
||||
return 0;
|
||||
return cred->cr_auth->au_ops->key_timeout(auth, cred);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpcauth_key_timeout_notify);
|
||||
|
||||
bool
|
||||
rpcauth_cred_key_to_expire(struct rpc_auth *auth, struct rpc_cred *cred)
|
||||
{
|
||||
if (auth->au_flags & RPCAUTH_AUTH_NO_CRKEY_TIMEOUT)
|
||||
return false;
|
||||
if (!cred->cr_ops->crkey_to_expire)
|
||||
return false;
|
||||
return cred->cr_ops->crkey_to_expire(cred);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpcauth_cred_key_to_expire);
|
||||
|
||||
char *
|
||||
rpcauth_stringify_acceptor(struct rpc_cred *cred)
|
||||
{
|
||||
@@ -587,13 +578,6 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
|
||||
hlist_for_each_entry_rcu(entry, &cache->hashtable[nr], cr_hash) {
|
||||
if (!entry->cr_ops->crmatch(acred, entry, flags))
|
||||
continue;
|
||||
if (flags & RPCAUTH_LOOKUP_RCU) {
|
||||
if (test_bit(RPCAUTH_CRED_NEW, &entry->cr_flags) ||
|
||||
refcount_read(&entry->cr_count) == 0)
|
||||
continue;
|
||||
cred = entry;
|
||||
break;
|
||||
}
|
||||
cred = get_rpccred(entry);
|
||||
if (cred)
|
||||
break;
|
||||
@@ -603,9 +587,6 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
|
||||
if (cred != NULL)
|
||||
goto found;
|
||||
|
||||
if (flags & RPCAUTH_LOOKUP_RCU)
|
||||
return ERR_PTR(-ECHILD);
|
||||
|
||||
new = auth->au_ops->crcreate(auth, acred, flags, gfp);
|
||||
if (IS_ERR(new)) {
|
||||
cred = new;
|
||||
@@ -656,9 +637,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
|
||||
auth->au_ops->au_name);
|
||||
|
||||
memset(&acred, 0, sizeof(acred));
|
||||
acred.uid = cred->fsuid;
|
||||
acred.gid = cred->fsgid;
|
||||
acred.group_info = cred->group_info;
|
||||
acred.cred = cred;
|
||||
ret = auth->au_ops->lookup_cred(auth, &acred, flags);
|
||||
return ret;
|
||||
}
|
||||
@@ -672,32 +651,42 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
|
||||
INIT_LIST_HEAD(&cred->cr_lru);
|
||||
refcount_set(&cred->cr_count, 1);
|
||||
cred->cr_auth = auth;
|
||||
cred->cr_flags = 0;
|
||||
cred->cr_ops = ops;
|
||||
cred->cr_expire = jiffies;
|
||||
cred->cr_uid = acred->uid;
|
||||
cred->cr_cred = get_cred(acred->cred);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpcauth_init_cred);
|
||||
|
||||
struct rpc_cred *
|
||||
rpcauth_generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred, int lookupflags)
|
||||
{
|
||||
dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid,
|
||||
cred->cr_auth->au_ops->au_name, cred);
|
||||
return get_rpccred(cred);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpcauth_generic_bind_cred);
|
||||
|
||||
static struct rpc_cred *
|
||||
rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags)
|
||||
{
|
||||
struct rpc_auth *auth = task->tk_client->cl_auth;
|
||||
struct auth_cred acred = {
|
||||
.uid = GLOBAL_ROOT_UID,
|
||||
.gid = GLOBAL_ROOT_GID,
|
||||
.cred = get_task_cred(&init_task),
|
||||
};
|
||||
struct rpc_cred *ret;
|
||||
|
||||
dprintk("RPC: %5u looking up %s cred\n",
|
||||
task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
|
||||
ret = auth->au_ops->lookup_cred(auth, &acred, lookupflags);
|
||||
put_cred(acred.cred);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct rpc_cred *
|
||||
rpcauth_bind_machine_cred(struct rpc_task *task, int lookupflags)
|
||||
{
|
||||
struct rpc_auth *auth = task->tk_client->cl_auth;
|
||||
struct auth_cred acred = {
|
||||
.principal = task->tk_client->cl_principal,
|
||||
.cred = init_task.cred,
|
||||
};
|
||||
|
||||
if (!acred.principal)
|
||||
return NULL;
|
||||
dprintk("RPC: %5u looking up %s machine cred\n",
|
||||
task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
|
||||
return auth->au_ops->lookup_cred(auth, &acred, lookupflags);
|
||||
}
|
||||
|
||||
@@ -712,18 +701,33 @@ rpcauth_bind_new_cred(struct rpc_task *task, int lookupflags)
|
||||
}
|
||||
|
||||
static int
|
||||
rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
|
||||
rpcauth_bindcred(struct rpc_task *task, const struct cred *cred, int flags)
|
||||
{
|
||||
struct rpc_rqst *req = task->tk_rqstp;
|
||||
struct rpc_cred *new;
|
||||
struct rpc_cred *new = NULL;
|
||||
int lookupflags = 0;
|
||||
struct rpc_auth *auth = task->tk_client->cl_auth;
|
||||
struct auth_cred acred = {
|
||||
.cred = cred,
|
||||
};
|
||||
|
||||
if (flags & RPC_TASK_ASYNC)
|
||||
lookupflags |= RPCAUTH_LOOKUP_NEW;
|
||||
if (cred != NULL)
|
||||
new = cred->cr_ops->crbind(task, cred, lookupflags);
|
||||
else if (flags & RPC_TASK_ROOTCREDS)
|
||||
if (task->tk_op_cred)
|
||||
/* Task must use exactly this rpc_cred */
|
||||
new = get_rpccred(task->tk_op_cred);
|
||||
else if (cred != NULL && cred != &machine_cred)
|
||||
new = auth->au_ops->lookup_cred(auth, &acred, lookupflags);
|
||||
else if (cred == &machine_cred)
|
||||
new = rpcauth_bind_machine_cred(task, lookupflags);
|
||||
|
||||
/* If machine cred couldn't be bound, try a root cred */
|
||||
if (new)
|
||||
;
|
||||
else if (cred == &machine_cred || (flags & RPC_TASK_ROOTCREDS))
|
||||
new = rpcauth_bind_root_cred(task, lookupflags);
|
||||
else if (flags & RPC_TASK_NULLCREDS)
|
||||
new = authnull_ops.lookup_cred(NULL, NULL, 0);
|
||||
else
|
||||
new = rpcauth_bind_new_cred(task, lookupflags);
|
||||
if (IS_ERR(new))
|
||||
@@ -901,15 +905,10 @@ int __init rpcauth_init_module(void)
|
||||
err = rpc_init_authunix();
|
||||
if (err < 0)
|
||||
goto out1;
|
||||
err = rpc_init_generic_auth();
|
||||
if (err < 0)
|
||||
goto out2;
|
||||
err = register_shrinker(&rpc_cred_shrinker);
|
||||
if (err < 0)
|
||||
goto out3;
|
||||
goto out2;
|
||||
return 0;
|
||||
out3:
|
||||
rpc_destroy_generic_auth();
|
||||
out2:
|
||||
rpc_destroy_authunix();
|
||||
out1:
|
||||
@@ -919,6 +918,5 @@ out1:
|
||||
void rpcauth_remove_module(void)
|
||||
{
|
||||
rpc_destroy_authunix();
|
||||
rpc_destroy_generic_auth();
|
||||
unregister_shrinker(&rpc_cred_shrinker);
|
||||
}
|
||||
|
||||
@@ -1,293 +0,0 @@
|
||||
/*
|
||||
* Generic RPC credential
|
||||
*
|
||||
* Copyright (C) 2008, Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sunrpc/auth.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/sunrpc/debug.h>
|
||||
#include <linux/sunrpc/sched.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||
#endif
|
||||
|
||||
#define RPC_MACHINE_CRED_USERID GLOBAL_ROOT_UID
|
||||
#define RPC_MACHINE_CRED_GROUPID GLOBAL_ROOT_GID
|
||||
|
||||
struct generic_cred {
|
||||
struct rpc_cred gc_base;
|
||||
struct auth_cred acred;
|
||||
};
|
||||
|
||||
static struct rpc_auth generic_auth;
|
||||
static const struct rpc_credops generic_credops;
|
||||
|
||||
/*
|
||||
* Public call interface
|
||||
*/
|
||||
struct rpc_cred *rpc_lookup_cred(void)
|
||||
{
|
||||
return rpcauth_lookupcred(&generic_auth, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpc_lookup_cred);
|
||||
|
||||
struct rpc_cred *
|
||||
rpc_lookup_generic_cred(struct auth_cred *acred, int flags, gfp_t gfp)
|
||||
{
|
||||
return rpcauth_lookup_credcache(&generic_auth, acred, flags, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpc_lookup_generic_cred);
|
||||
|
||||
struct rpc_cred *rpc_lookup_cred_nonblock(void)
|
||||
{
|
||||
return rpcauth_lookupcred(&generic_auth, RPCAUTH_LOOKUP_RCU);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpc_lookup_cred_nonblock);
|
||||
|
||||
/*
|
||||
* Public call interface for looking up machine creds.
|
||||
*/
|
||||
struct rpc_cred *rpc_lookup_machine_cred(const char *service_name)
|
||||
{
|
||||
struct auth_cred acred = {
|
||||
.uid = RPC_MACHINE_CRED_USERID,
|
||||
.gid = RPC_MACHINE_CRED_GROUPID,
|
||||
.principal = service_name,
|
||||
.machine_cred = 1,
|
||||
};
|
||||
|
||||
dprintk("RPC: looking up machine cred for service %s\n",
|
||||
service_name);
|
||||
return generic_auth.au_ops->lookup_cred(&generic_auth, &acred, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred);
|
||||
|
||||
static struct rpc_cred *generic_bind_cred(struct rpc_task *task,
|
||||
struct rpc_cred *cred, int lookupflags)
|
||||
{
|
||||
struct rpc_auth *auth = task->tk_client->cl_auth;
|
||||
struct auth_cred *acred = &container_of(cred, struct generic_cred, gc_base)->acred;
|
||||
|
||||
return auth->au_ops->lookup_cred(auth, acred, lookupflags);
|
||||
}
|
||||
|
||||
static int
|
||||
generic_hash_cred(struct auth_cred *acred, unsigned int hashbits)
|
||||
{
|
||||
return hash_64(from_kgid(&init_user_ns, acred->gid) |
|
||||
((u64)from_kuid(&init_user_ns, acred->uid) <<
|
||||
(sizeof(gid_t) * 8)), hashbits);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup generic creds for current process
|
||||
*/
|
||||
static struct rpc_cred *
|
||||
generic_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
|
||||
{
|
||||
return rpcauth_lookup_credcache(&generic_auth, acred, flags, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static struct rpc_cred *
|
||||
generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags, gfp_t gfp)
|
||||
{
|
||||
struct generic_cred *gcred;
|
||||
|
||||
gcred = kmalloc(sizeof(*gcred), gfp);
|
||||
if (gcred == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
rpcauth_init_cred(&gcred->gc_base, acred, &generic_auth, &generic_credops);
|
||||
gcred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
|
||||
|
||||
gcred->acred.uid = acred->uid;
|
||||
gcred->acred.gid = acred->gid;
|
||||
gcred->acred.group_info = acred->group_info;
|
||||
gcred->acred.ac_flags = 0;
|
||||
if (gcred->acred.group_info != NULL)
|
||||
get_group_info(gcred->acred.group_info);
|
||||
gcred->acred.machine_cred = acred->machine_cred;
|
||||
gcred->acred.principal = acred->principal;
|
||||
|
||||
dprintk("RPC: allocated %s cred %p for uid %d gid %d\n",
|
||||
gcred->acred.machine_cred ? "machine" : "generic",
|
||||
gcred,
|
||||
from_kuid(&init_user_ns, acred->uid),
|
||||
from_kgid(&init_user_ns, acred->gid));
|
||||
return &gcred->gc_base;
|
||||
}
|
||||
|
||||
static void
|
||||
generic_free_cred(struct rpc_cred *cred)
|
||||
{
|
||||
struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
|
||||
|
||||
dprintk("RPC: generic_free_cred %p\n", gcred);
|
||||
if (gcred->acred.group_info != NULL)
|
||||
put_group_info(gcred->acred.group_info);
|
||||
kfree(gcred);
|
||||
}
|
||||
|
||||
static void
|
||||
generic_free_cred_callback(struct rcu_head *head)
|
||||
{
|
||||
struct rpc_cred *cred = container_of(head, struct rpc_cred, cr_rcu);
|
||||
generic_free_cred(cred);
|
||||
}
|
||||
|
||||
static void
|
||||
generic_destroy_cred(struct rpc_cred *cred)
|
||||
{
|
||||
call_rcu(&cred->cr_rcu, generic_free_cred_callback);
|
||||
}
|
||||
|
||||
static int
|
||||
machine_cred_match(struct auth_cred *acred, struct generic_cred *gcred, int flags)
|
||||
{
|
||||
if (!gcred->acred.machine_cred ||
|
||||
gcred->acred.principal != acred->principal ||
|
||||
!uid_eq(gcred->acred.uid, acred->uid) ||
|
||||
!gid_eq(gcred->acred.gid, acred->gid))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Match credentials against current process creds.
|
||||
*/
|
||||
static int
|
||||
generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
|
||||
{
|
||||
struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
|
||||
int i;
|
||||
|
||||
if (acred->machine_cred)
|
||||
return machine_cred_match(acred, gcred, flags);
|
||||
|
||||
if (!uid_eq(gcred->acred.uid, acred->uid) ||
|
||||
!gid_eq(gcred->acred.gid, acred->gid) ||
|
||||
gcred->acred.machine_cred != 0)
|
||||
goto out_nomatch;
|
||||
|
||||
/* Optimisation in the case where pointers are identical... */
|
||||
if (gcred->acred.group_info == acred->group_info)
|
||||
goto out_match;
|
||||
|
||||
/* Slow path... */
|
||||
if (gcred->acred.group_info->ngroups != acred->group_info->ngroups)
|
||||
goto out_nomatch;
|
||||
for (i = 0; i < gcred->acred.group_info->ngroups; i++) {
|
||||
if (!gid_eq(gcred->acred.group_info->gid[i],
|
||||
acred->group_info->gid[i]))
|
||||
goto out_nomatch;
|
||||
}
|
||||
out_match:
|
||||
return 1;
|
||||
out_nomatch:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init rpc_init_generic_auth(void)
|
||||
{
|
||||
return rpcauth_init_credcache(&generic_auth);
|
||||
}
|
||||
|
||||
void rpc_destroy_generic_auth(void)
|
||||
{
|
||||
rpcauth_destroy_credcache(&generic_auth);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the the current time (now) against the underlying credential key expiry
|
||||
* minus a timeout and setup notification.
|
||||
*
|
||||
* The normal case:
|
||||
* If 'now' is before the key expiry minus RPC_KEY_EXPIRE_TIMEO, set
|
||||
* the RPC_CRED_NOTIFY_TIMEOUT flag to setup the underlying credential
|
||||
* rpc_credops crmatch routine to notify this generic cred when it's key
|
||||
* expiration is within RPC_KEY_EXPIRE_TIMEO, and return 0.
|
||||
*
|
||||
* The error case:
|
||||
* If the underlying cred lookup fails, return -EACCES.
|
||||
*
|
||||
* The 'almost' error case:
|
||||
* If 'now' is within key expiry minus RPC_KEY_EXPIRE_TIMEO, but not within
|
||||
* key expiry minus RPC_KEY_EXPIRE_FAIL, set the RPC_CRED_EXPIRE_SOON bit
|
||||
* on the acred ac_flags and return 0.
|
||||
*/
|
||||
static int
|
||||
generic_key_timeout(struct rpc_auth *auth, struct rpc_cred *cred)
|
||||
{
|
||||
struct auth_cred *acred = &container_of(cred, struct generic_cred,
|
||||
gc_base)->acred;
|
||||
struct rpc_cred *tcred;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
/* Fast track for non crkey_timeout (no key) underlying credentials */
|
||||
if (auth->au_flags & RPCAUTH_AUTH_NO_CRKEY_TIMEOUT)
|
||||
return 0;
|
||||
|
||||
/* Fast track for the normal case */
|
||||
if (test_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags))
|
||||
return 0;
|
||||
|
||||
/* lookup_cred either returns a valid referenced rpc_cred, or PTR_ERR */
|
||||
tcred = auth->au_ops->lookup_cred(auth, acred, 0);
|
||||
if (IS_ERR(tcred))
|
||||
return -EACCES;
|
||||
|
||||
/* Test for the almost error case */
|
||||
ret = tcred->cr_ops->crkey_timeout(tcred);
|
||||
if (ret != 0) {
|
||||
set_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
|
||||
ret = 0;
|
||||
} else {
|
||||
/* In case underlying cred key has been reset */
|
||||
if (test_and_clear_bit(RPC_CRED_KEY_EXPIRE_SOON,
|
||||
&acred->ac_flags))
|
||||
dprintk("RPC: UID %d Credential key reset\n",
|
||||
from_kuid(&init_user_ns, tcred->cr_uid));
|
||||
/* set up fasttrack for the normal case */
|
||||
set_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags);
|
||||
}
|
||||
|
||||
put_rpccred(tcred);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct rpc_authops generic_auth_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.au_name = "Generic",
|
||||
.hash_cred = generic_hash_cred,
|
||||
.lookup_cred = generic_lookup_cred,
|
||||
.crcreate = generic_create_cred,
|
||||
.key_timeout = generic_key_timeout,
|
||||
};
|
||||
|
||||
static struct rpc_auth generic_auth = {
|
||||
.au_ops = &generic_auth_ops,
|
||||
.au_count = REFCOUNT_INIT(1),
|
||||
};
|
||||
|
||||
static bool generic_key_to_expire(struct rpc_cred *cred)
|
||||
{
|
||||
struct auth_cred *acred = &container_of(cred, struct generic_cred,
|
||||
gc_base)->acred;
|
||||
return test_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
|
||||
}
|
||||
|
||||
static const struct rpc_credops generic_credops = {
|
||||
.cr_name = "Generic cred",
|
||||
.crdestroy = generic_destroy_cred,
|
||||
.crbind = generic_bind_cred,
|
||||
.crmatch = generic_match,
|
||||
.crkey_to_expire = generic_key_to_expire,
|
||||
};
|
||||
@@ -565,7 +565,7 @@ gss_setup_upcall(struct gss_auth *gss_auth, struct rpc_cred *cred)
|
||||
struct gss_cred *gss_cred = container_of(cred,
|
||||
struct gss_cred, gc_base);
|
||||
struct gss_upcall_msg *gss_new, *gss_msg;
|
||||
kuid_t uid = cred->cr_uid;
|
||||
kuid_t uid = cred->cr_cred->fsuid;
|
||||
|
||||
gss_new = gss_alloc_msg(gss_auth, uid, gss_cred->gc_principal);
|
||||
if (IS_ERR(gss_new))
|
||||
@@ -604,7 +604,7 @@ gss_refresh_upcall(struct rpc_task *task)
|
||||
int err = 0;
|
||||
|
||||
dprintk("RPC: %5u %s for uid %u\n",
|
||||
task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid));
|
||||
task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_cred->fsuid));
|
||||
gss_msg = gss_setup_upcall(gss_auth, cred);
|
||||
if (PTR_ERR(gss_msg) == -EAGAIN) {
|
||||
/* XXX: warning on the first, under the assumption we
|
||||
@@ -637,7 +637,7 @@ gss_refresh_upcall(struct rpc_task *task)
|
||||
out:
|
||||
dprintk("RPC: %5u %s for uid %u result %d\n",
|
||||
task->tk_pid, __func__,
|
||||
from_kuid(&init_user_ns, cred->cr_uid), err);
|
||||
from_kuid(&init_user_ns, cred->cr_cred->fsuid), err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -653,7 +653,7 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
|
||||
int err;
|
||||
|
||||
dprintk("RPC: %s for uid %u\n",
|
||||
__func__, from_kuid(&init_user_ns, cred->cr_uid));
|
||||
__func__, from_kuid(&init_user_ns, cred->cr_cred->fsuid));
|
||||
retry:
|
||||
err = 0;
|
||||
/* if gssd is down, just skip upcalling altogether */
|
||||
@@ -701,7 +701,7 @@ out_intr:
|
||||
gss_release_msg(gss_msg);
|
||||
out:
|
||||
dprintk("RPC: %s for uid %u result %d\n",
|
||||
__func__, from_kuid(&init_user_ns, cred->cr_uid), err);
|
||||
__func__, from_kuid(&init_user_ns, cred->cr_cred->fsuid), err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1248,7 +1248,7 @@ gss_dup_cred(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
|
||||
new = kzalloc(sizeof(*gss_cred), GFP_NOIO);
|
||||
if (new) {
|
||||
struct auth_cred acred = {
|
||||
.uid = gss_cred->gc_base.cr_uid,
|
||||
.cred = gss_cred->gc_base.cr_cred,
|
||||
};
|
||||
struct gss_cl_ctx *ctx =
|
||||
rcu_dereference_protected(gss_cred->gc_ctx, 1);
|
||||
@@ -1343,6 +1343,7 @@ gss_destroy_nullcred(struct rpc_cred *cred)
|
||||
struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1);
|
||||
|
||||
RCU_INIT_POINTER(gss_cred->gc_ctx, NULL);
|
||||
put_cred(cred->cr_cred);
|
||||
call_rcu(&cred->cr_rcu, gss_free_cred_callback);
|
||||
if (ctx)
|
||||
gss_put_ctx(ctx);
|
||||
@@ -1361,7 +1362,7 @@ gss_destroy_cred(struct rpc_cred *cred)
|
||||
static int
|
||||
gss_hash_cred(struct auth_cred *acred, unsigned int hashbits)
|
||||
{
|
||||
return hash_64(from_kuid(&init_user_ns, acred->uid), hashbits);
|
||||
return hash_64(from_kuid(&init_user_ns, acred->cred->fsuid), hashbits);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1381,7 +1382,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags, gfp_t
|
||||
int err = -ENOMEM;
|
||||
|
||||
dprintk("RPC: %s for uid %d, flavor %d\n",
|
||||
__func__, from_kuid(&init_user_ns, acred->uid),
|
||||
__func__, from_kuid(&init_user_ns, acred->cred->fsuid),
|
||||
auth->au_flavor);
|
||||
|
||||
if (!(cred = kzalloc(sizeof(*cred), gfp)))
|
||||
@@ -1394,8 +1395,6 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags, gfp_t
|
||||
*/
|
||||
cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
|
||||
cred->gc_service = gss_auth->service;
|
||||
cred->gc_principal = NULL;
|
||||
if (acred->machine_cred)
|
||||
cred->gc_principal = acred->principal;
|
||||
kref_get(&gss_auth->kref);
|
||||
return &cred->gc_base;
|
||||
@@ -1518,23 +1517,10 @@ out:
|
||||
if (gss_cred->gc_principal == NULL)
|
||||
return 0;
|
||||
ret = strcmp(acred->principal, gss_cred->gc_principal) == 0;
|
||||
goto check_expire;
|
||||
}
|
||||
} else {
|
||||
if (gss_cred->gc_principal != NULL)
|
||||
return 0;
|
||||
ret = uid_eq(rc->cr_uid, acred->uid);
|
||||
|
||||
check_expire:
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
|
||||
/* Notify acred users of GSS context expiration timeout */
|
||||
if (test_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags) &&
|
||||
(gss_key_timeout(rc) != 0)) {
|
||||
/* test will now be done from generic cred */
|
||||
test_and_clear_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags);
|
||||
/* tell NFS layer that key will expire soon */
|
||||
set_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
|
||||
ret = uid_eq(rc->cr_cred->fsuid, acred->cred->fsuid);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -1607,9 +1593,8 @@ static int gss_renew_cred(struct rpc_task *task)
|
||||
gc_base);
|
||||
struct rpc_auth *auth = oldcred->cr_auth;
|
||||
struct auth_cred acred = {
|
||||
.uid = oldcred->cr_uid,
|
||||
.cred = oldcred->cr_cred,
|
||||
.principal = gss_cred->gc_principal,
|
||||
.machine_cred = (gss_cred->gc_principal != NULL ? 1 : 0),
|
||||
};
|
||||
struct rpc_cred *new;
|
||||
|
||||
@@ -2110,7 +2095,6 @@ static const struct rpc_credops gss_credops = {
|
||||
.cr_name = "AUTH_GSS",
|
||||
.crdestroy = gss_destroy_cred,
|
||||
.cr_init = gss_cred_init,
|
||||
.crbind = rpcauth_generic_bind_cred,
|
||||
.crmatch = gss_match,
|
||||
.crmarshal = gss_marshal,
|
||||
.crrefresh = gss_refresh,
|
||||
@@ -2125,7 +2109,6 @@ static const struct rpc_credops gss_credops = {
|
||||
static const struct rpc_credops gss_nullops = {
|
||||
.cr_name = "AUTH_GSS",
|
||||
.crdestroy = gss_destroy_nullcred,
|
||||
.crbind = rpcauth_generic_bind_cred,
|
||||
.crmatch = gss_match,
|
||||
.crmarshal = gss_marshal,
|
||||
.crrefresh = gss_refresh_null,
|
||||
|
||||
@@ -244,7 +244,7 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor)
|
||||
|
||||
/**
|
||||
* gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors
|
||||
* @array: array to fill in
|
||||
* @array_ptr: array to fill in
|
||||
* @size: size of "array"
|
||||
*
|
||||
* Returns the number of array items filled in, or a negative errno.
|
||||
|
||||
@@ -36,8 +36,6 @@ nul_destroy(struct rpc_auth *auth)
|
||||
static struct rpc_cred *
|
||||
nul_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
|
||||
{
|
||||
if (flags & RPCAUTH_LOOKUP_RCU)
|
||||
return &null_cred;
|
||||
return get_rpccred(&null_cred);
|
||||
}
|
||||
|
||||
@@ -116,7 +114,6 @@ static
|
||||
struct rpc_auth null_auth = {
|
||||
.au_cslack = NUL_CALLSLACK,
|
||||
.au_rslack = NUL_REPLYSLACK,
|
||||
.au_flags = RPCAUTH_AUTH_NO_CRKEY_TIMEOUT,
|
||||
.au_ops = &authnull_ops,
|
||||
.au_flavor = RPC_AUTH_NULL,
|
||||
.au_count = REFCOUNT_INIT(1),
|
||||
@@ -126,7 +123,6 @@ static
|
||||
const struct rpc_credops null_credops = {
|
||||
.cr_name = "AUTH_NULL",
|
||||
.crdestroy = nul_destroy_cred,
|
||||
.crbind = rpcauth_generic_bind_cred,
|
||||
.crmatch = nul_match,
|
||||
.crmarshal = nul_marshal,
|
||||
.crrefresh = nul_refresh,
|
||||
|
||||
@@ -11,16 +11,11 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mempool.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/sunrpc/auth.h>
|
||||
#include <linux/user_namespace.h>
|
||||
|
||||
struct unx_cred {
|
||||
struct rpc_cred uc_base;
|
||||
kgid_t uc_gid;
|
||||
kgid_t uc_gids[UNX_NGROUPS];
|
||||
};
|
||||
#define uc_uid uc_base.cr_uid
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||
@@ -28,6 +23,7 @@ struct unx_cred {
|
||||
|
||||
static struct rpc_auth unix_auth;
|
||||
static const struct rpc_credops unix_credops;
|
||||
static mempool_t *unix_pool;
|
||||
|
||||
static struct rpc_auth *
|
||||
unx_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
|
||||
@@ -42,15 +38,6 @@ static void
|
||||
unx_destroy(struct rpc_auth *auth)
|
||||
{
|
||||
dprintk("RPC: destroying UNIX authenticator %p\n", auth);
|
||||
rpcauth_clear_credcache(auth->au_credcache);
|
||||
}
|
||||
|
||||
static int
|
||||
unx_hash_cred(struct auth_cred *acred, unsigned int hashbits)
|
||||
{
|
||||
return hash_64(from_kgid(&init_user_ns, acred->gid) |
|
||||
((u64)from_kuid(&init_user_ns, acred->uid) <<
|
||||
(sizeof(gid_t) * 8)), hashbits);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -59,52 +46,24 @@ unx_hash_cred(struct auth_cred *acred, unsigned int hashbits)
|
||||
static struct rpc_cred *
|
||||
unx_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
|
||||
{
|
||||
return rpcauth_lookup_credcache(auth, acred, flags, GFP_NOFS);
|
||||
}
|
||||
|
||||
static struct rpc_cred *
|
||||
unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags, gfp_t gfp)
|
||||
{
|
||||
struct unx_cred *cred;
|
||||
unsigned int groups = 0;
|
||||
unsigned int i;
|
||||
struct rpc_cred *ret = mempool_alloc(unix_pool, GFP_NOFS);
|
||||
|
||||
dprintk("RPC: allocating UNIX cred for uid %d gid %d\n",
|
||||
from_kuid(&init_user_ns, acred->uid),
|
||||
from_kgid(&init_user_ns, acred->gid));
|
||||
from_kuid(&init_user_ns, acred->cred->fsuid),
|
||||
from_kgid(&init_user_ns, acred->cred->fsgid));
|
||||
|
||||
if (!(cred = kmalloc(sizeof(*cred), gfp)))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops);
|
||||
cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
|
||||
|
||||
if (acred->group_info != NULL)
|
||||
groups = acred->group_info->ngroups;
|
||||
if (groups > UNX_NGROUPS)
|
||||
groups = UNX_NGROUPS;
|
||||
|
||||
cred->uc_gid = acred->gid;
|
||||
for (i = 0; i < groups; i++)
|
||||
cred->uc_gids[i] = acred->group_info->gid[i];
|
||||
if (i < UNX_NGROUPS)
|
||||
cred->uc_gids[i] = INVALID_GID;
|
||||
|
||||
return &cred->uc_base;
|
||||
}
|
||||
|
||||
static void
|
||||
unx_free_cred(struct unx_cred *unx_cred)
|
||||
{
|
||||
dprintk("RPC: unx_free_cred %p\n", unx_cred);
|
||||
kfree(unx_cred);
|
||||
rpcauth_init_cred(ret, acred, auth, &unix_credops);
|
||||
ret->cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
unx_free_cred_callback(struct rcu_head *head)
|
||||
{
|
||||
struct unx_cred *unx_cred = container_of(head, struct unx_cred, uc_base.cr_rcu);
|
||||
unx_free_cred(unx_cred);
|
||||
struct rpc_cred *rpc_cred = container_of(head, struct rpc_cred, cr_rcu);
|
||||
dprintk("RPC: unx_free_cred %p\n", rpc_cred);
|
||||
put_cred(rpc_cred->cr_cred);
|
||||
mempool_free(rpc_cred, unix_pool);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -114,29 +73,31 @@ unx_destroy_cred(struct rpc_cred *cred)
|
||||
}
|
||||
|
||||
/*
|
||||
* Match credentials against current process creds.
|
||||
* The root_override argument takes care of cases where the caller may
|
||||
* request root creds (e.g. for NFS swapping).
|
||||
* Match credentials against current the auth_cred.
|
||||
*/
|
||||
static int
|
||||
unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
|
||||
unx_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
|
||||
{
|
||||
struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base);
|
||||
unsigned int groups = 0;
|
||||
unsigned int i;
|
||||
|
||||
if (cred->cr_cred == acred->cred)
|
||||
return 1;
|
||||
|
||||
if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
|
||||
if (!uid_eq(cred->cr_cred->fsuid, acred->cred->fsuid) || !gid_eq(cred->cr_cred->fsgid, acred->cred->fsgid))
|
||||
return 0;
|
||||
|
||||
if (acred->group_info != NULL)
|
||||
groups = acred->group_info->ngroups;
|
||||
if (acred->cred && acred->cred->group_info != NULL)
|
||||
groups = acred->cred->group_info->ngroups;
|
||||
if (groups > UNX_NGROUPS)
|
||||
groups = UNX_NGROUPS;
|
||||
for (i = 0; i < groups ; i++)
|
||||
if (!gid_eq(cred->uc_gids[i], acred->group_info->gid[i]))
|
||||
if (cred->cr_cred->group_info == NULL)
|
||||
return groups == 0;
|
||||
if (groups != cred->cr_cred->group_info->ngroups)
|
||||
return 0;
|
||||
if (groups < UNX_NGROUPS && gid_valid(cred->uc_gids[groups]))
|
||||
|
||||
for (i = 0; i < groups ; i++)
|
||||
if (!gid_eq(cred->cr_cred->group_info->gid[i], acred->cred->group_info->gid[i]))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -149,9 +110,10 @@ static __be32 *
|
||||
unx_marshal(struct rpc_task *task, __be32 *p)
|
||||
{
|
||||
struct rpc_clnt *clnt = task->tk_client;
|
||||
struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
|
||||
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
|
||||
__be32 *base, *hold;
|
||||
int i;
|
||||
struct group_info *gi = cred->cr_cred->group_info;
|
||||
|
||||
*p++ = htonl(RPC_AUTH_UNIX);
|
||||
base = p++;
|
||||
@@ -162,11 +124,12 @@ unx_marshal(struct rpc_task *task, __be32 *p)
|
||||
*/
|
||||
p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
|
||||
|
||||
*p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
|
||||
*p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
|
||||
*p++ = htonl((u32) from_kuid(&init_user_ns, cred->cr_cred->fsuid));
|
||||
*p++ = htonl((u32) from_kgid(&init_user_ns, cred->cr_cred->fsgid));
|
||||
hold = p++;
|
||||
for (i = 0; i < UNX_NGROUPS && gid_valid(cred->uc_gids[i]); i++)
|
||||
*p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
|
||||
if (gi)
|
||||
for (i = 0; i < UNX_NGROUPS && i < gi->ngroups; i++)
|
||||
*p++ = htonl((u32) from_kgid(&init_user_ns, gi->gid[i]));
|
||||
*hold = htonl(p - hold - 1); /* gid array length */
|
||||
*base = htonl((p - base - 1) << 2); /* cred length */
|
||||
|
||||
@@ -213,12 +176,13 @@ unx_validate(struct rpc_task *task, __be32 *p)
|
||||
|
||||
int __init rpc_init_authunix(void)
|
||||
{
|
||||
return rpcauth_init_credcache(&unix_auth);
|
||||
unix_pool = mempool_create_kmalloc_pool(16, sizeof(struct rpc_cred));
|
||||
return unix_pool ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
void rpc_destroy_authunix(void)
|
||||
{
|
||||
rpcauth_destroy_credcache(&unix_auth);
|
||||
mempool_destroy(unix_pool);
|
||||
}
|
||||
|
||||
const struct rpc_authops authunix_ops = {
|
||||
@@ -227,16 +191,13 @@ const struct rpc_authops authunix_ops = {
|
||||
.au_name = "UNIX",
|
||||
.create = unx_create,
|
||||
.destroy = unx_destroy,
|
||||
.hash_cred = unx_hash_cred,
|
||||
.lookup_cred = unx_lookup_cred,
|
||||
.crcreate = unx_create_cred,
|
||||
};
|
||||
|
||||
static
|
||||
struct rpc_auth unix_auth = {
|
||||
.au_cslack = UNX_CALLSLACK,
|
||||
.au_rslack = NUL_REPLYSLACK,
|
||||
.au_flags = RPCAUTH_AUTH_NO_CRKEY_TIMEOUT,
|
||||
.au_ops = &authunix_ops,
|
||||
.au_flavor = RPC_AUTH_UNIX,
|
||||
.au_count = REFCOUNT_INIT(1),
|
||||
@@ -246,7 +207,6 @@ static
|
||||
const struct rpc_credops unix_credops = {
|
||||
.cr_name = "AUTH_UNIX",
|
||||
.crdestroy = unx_destroy_cred,
|
||||
.crbind = rpcauth_generic_bind_cred,
|
||||
.crmatch = unx_match,
|
||||
.crmarshal = unx_marshal,
|
||||
.crrefresh = unx_refresh,
|
||||
|
||||
@@ -197,7 +197,7 @@ out_free:
|
||||
/**
|
||||
* xprt_destroy_backchannel - Destroys the backchannel preallocated structures.
|
||||
* @xprt: the transport holding the preallocated strucures
|
||||
* @max_reqs the maximum number of preallocated structures to destroy
|
||||
* @max_reqs: the maximum number of preallocated structures to destroy
|
||||
*
|
||||
* Since these structures may have been allocated by multiple calls
|
||||
* to xprt_setup_backchannel, we only destroy up to the maximum number
|
||||
|
||||
@@ -627,6 +627,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
|
||||
new->cl_noretranstimeo = clnt->cl_noretranstimeo;
|
||||
new->cl_discrtry = clnt->cl_discrtry;
|
||||
new->cl_chatty = clnt->cl_chatty;
|
||||
new->cl_principal = clnt->cl_principal;
|
||||
return new;
|
||||
|
||||
out_err:
|
||||
@@ -1029,7 +1030,7 @@ rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg)
|
||||
task->tk_msg.rpc_argp = msg->rpc_argp;
|
||||
task->tk_msg.rpc_resp = msg->rpc_resp;
|
||||
if (msg->rpc_cred != NULL)
|
||||
task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred);
|
||||
task->tk_msg.rpc_cred = get_cred(msg->rpc_cred);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2521,9 +2522,8 @@ static int rpc_ping(struct rpc_clnt *clnt)
|
||||
.rpc_proc = &rpcproc_null,
|
||||
};
|
||||
int err;
|
||||
msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0);
|
||||
err = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN);
|
||||
put_rpccred(msg.rpc_cred);
|
||||
err = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN |
|
||||
RPC_TASK_NULLCREDS);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2534,15 +2534,15 @@ struct rpc_task *rpc_call_null_helper(struct rpc_clnt *clnt,
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &rpcproc_null,
|
||||
.rpc_cred = cred,
|
||||
};
|
||||
struct rpc_task_setup task_setup_data = {
|
||||
.rpc_client = clnt,
|
||||
.rpc_xprt = xprt,
|
||||
.rpc_message = &msg,
|
||||
.rpc_op_cred = cred,
|
||||
.callback_ops = (ops != NULL) ? ops : &rpc_default_ops,
|
||||
.callback_data = data,
|
||||
.flags = flags,
|
||||
.flags = flags | RPC_TASK_NULLCREDS,
|
||||
};
|
||||
|
||||
return rpc_run_task(&task_setup_data);
|
||||
@@ -2593,7 +2593,6 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
|
||||
void *dummy)
|
||||
{
|
||||
struct rpc_cb_add_xprt_calldata *data;
|
||||
struct rpc_cred *cred;
|
||||
struct rpc_task *task;
|
||||
|
||||
data = kmalloc(sizeof(*data), GFP_NOFS);
|
||||
@@ -2602,11 +2601,9 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
|
||||
data->xps = xprt_switch_get(xps);
|
||||
data->xprt = xprt_get(xprt);
|
||||
|
||||
cred = authnull_ops.lookup_cred(NULL, NULL, 0);
|
||||
task = rpc_call_null_helper(clnt, xprt, cred,
|
||||
RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC,
|
||||
task = rpc_call_null_helper(clnt, xprt, NULL,
|
||||
RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC|RPC_TASK_NULLCREDS,
|
||||
&rpc_cb_add_xprt_call_ops, data);
|
||||
put_rpccred(cred);
|
||||
if (IS_ERR(task))
|
||||
return PTR_ERR(task);
|
||||
rpc_put_task(task);
|
||||
@@ -2637,7 +2634,6 @@ int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *clnt,
|
||||
struct rpc_xprt *xprt,
|
||||
void *data)
|
||||
{
|
||||
struct rpc_cred *cred;
|
||||
struct rpc_task *task;
|
||||
struct rpc_add_xprt_test *xtest = (struct rpc_add_xprt_test *)data;
|
||||
int status = -EADDRINUSE;
|
||||
@@ -2649,11 +2645,9 @@ int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *clnt,
|
||||
goto out_err;
|
||||
|
||||
/* Test the connection */
|
||||
cred = authnull_ops.lookup_cred(NULL, NULL, 0);
|
||||
task = rpc_call_null_helper(clnt, xprt, cred,
|
||||
RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
|
||||
task = rpc_call_null_helper(clnt, xprt, NULL,
|
||||
RPC_TASK_SOFT | RPC_TASK_SOFTCONN | RPC_TASK_NULLCREDS,
|
||||
NULL, NULL);
|
||||
put_rpccred(cred);
|
||||
if (IS_ERR(task)) {
|
||||
status = PTR_ERR(task);
|
||||
goto out_err;
|
||||
@@ -2667,6 +2661,9 @@ int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *clnt,
|
||||
/* rpc_xprt_switch and rpc_xprt are deferrenced by add_xprt_test() */
|
||||
xtest->add_xprt_test(clnt, xprt, xtest->data);
|
||||
|
||||
xprt_put(xprt);
|
||||
xprt_switch_put(xps);
|
||||
|
||||
/* so that rpc_clnt_add_xprt does not call rpc_xprt_switch_add_xprt */
|
||||
return 1;
|
||||
out_err:
|
||||
|
||||
@@ -1266,7 +1266,7 @@ static const struct rpc_pipe_ops gssd_dummy_pipe_ops = {
|
||||
* that this file will be there and have a certain format.
|
||||
*/
|
||||
static int
|
||||
rpc_show_dummy_info(struct seq_file *m, void *v)
|
||||
rpc_dummy_info_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_printf(m, "RPC server: %s\n", utsname()->nodename);
|
||||
seq_printf(m, "service: foo (1) version 0\n");
|
||||
@@ -1275,25 +1275,12 @@ rpc_show_dummy_info(struct seq_file *m, void *v)
|
||||
seq_printf(m, "port: 0\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rpc_dummy_info_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, rpc_show_dummy_info, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations rpc_dummy_info_operations = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = rpc_dummy_info_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(rpc_dummy_info);
|
||||
|
||||
static const struct rpc_filelist gssd_dummy_info_file[] = {
|
||||
[0] = {
|
||||
.name = "info",
|
||||
.i_fop = &rpc_dummy_info_operations,
|
||||
.i_fop = &rpc_dummy_info_fops,
|
||||
.mode = S_IFREG | 0400,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -752,7 +752,7 @@ void rpcb_getport_async(struct rpc_task *task)
|
||||
goto bailout_nofree;
|
||||
}
|
||||
|
||||
map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
|
||||
map = kzalloc(sizeof(struct rpcbind_args), GFP_NOFS);
|
||||
if (!map) {
|
||||
status = -ENOMEM;
|
||||
dprintk("RPC: %5u %s: no memory available\n",
|
||||
@@ -770,7 +770,13 @@ void rpcb_getport_async(struct rpc_task *task)
|
||||
case RPCBVERS_4:
|
||||
case RPCBVERS_3:
|
||||
map->r_netid = xprt->address_strings[RPC_DISPLAY_NETID];
|
||||
map->r_addr = rpc_sockaddr2uaddr(sap, GFP_ATOMIC);
|
||||
map->r_addr = rpc_sockaddr2uaddr(sap, GFP_NOFS);
|
||||
if (!map->r_addr) {
|
||||
status = -ENOMEM;
|
||||
dprintk("RPC: %5u %s: no memory available\n",
|
||||
task->tk_pid, __func__);
|
||||
goto bailout_free_args;
|
||||
}
|
||||
map->r_owner = "";
|
||||
break;
|
||||
case RPCBVERS_2:
|
||||
@@ -793,6 +799,8 @@ void rpcb_getport_async(struct rpc_task *task)
|
||||
rpc_put_task(child);
|
||||
return;
|
||||
|
||||
bailout_free_args:
|
||||
kfree(map);
|
||||
bailout_release_client:
|
||||
rpc_release_client(rpcb_clnt);
|
||||
bailout_nofree:
|
||||
|
||||
@@ -997,6 +997,8 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
|
||||
|
||||
task->tk_xprt = xprt_get(task_setup_data->rpc_xprt);
|
||||
|
||||
task->tk_op_cred = get_rpccred(task_setup_data->rpc_op_cred);
|
||||
|
||||
if (task->tk_ops->rpc_call_prepare != NULL)
|
||||
task->tk_action = rpc_prepare_task;
|
||||
|
||||
@@ -1054,6 +1056,7 @@ static void rpc_free_task(struct rpc_task *task)
|
||||
{
|
||||
unsigned short tk_flags = task->tk_flags;
|
||||
|
||||
put_rpccred(task->tk_op_cred);
|
||||
rpc_release_calldata(task->tk_ops, task->tk_calldata);
|
||||
|
||||
if (tk_flags & RPC_TASK_DYNAMIC) {
|
||||
@@ -1071,7 +1074,7 @@ static void rpc_release_resources_task(struct rpc_task *task)
|
||||
{
|
||||
xprt_release(task);
|
||||
if (task->tk_msg.rpc_cred) {
|
||||
put_rpccred(task->tk_msg.rpc_cred);
|
||||
put_cred(task->tk_msg.rpc_cred);
|
||||
task->tk_msg.rpc_cred = NULL;
|
||||
}
|
||||
rpc_task_release_client(task);
|
||||
|
||||
@@ -383,7 +383,7 @@ void xprt_iter_init_listall(struct rpc_xprt_iter *xpi,
|
||||
/**
|
||||
* xprt_iter_xchg_switch - Atomically swap out the rpc_xprt_switch
|
||||
* @xpi: pointer to rpc_xprt_iter
|
||||
* @xps: pointer to a new rpc_xprt_switch or NULL
|
||||
* @newswitch: pointer to a new rpc_xprt_switch or NULL
|
||||
*
|
||||
* Swaps out the existing xpi->xpi_xpswitch with a new value.
|
||||
*/
|
||||
@@ -401,7 +401,7 @@ struct rpc_xprt_switch *xprt_iter_xchg_switch(struct rpc_xprt_iter *xpi,
|
||||
|
||||
/**
|
||||
* xprt_iter_destroy - Destroys the xprt iterator
|
||||
* @xpi pointer to rpc_xprt_iter
|
||||
* @xpi: pointer to rpc_xprt_iter
|
||||
*/
|
||||
void xprt_iter_destroy(struct rpc_xprt_iter *xpi)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_SUNRPC_XPRT_RDMA) += rpcrdma.o
|
||||
|
||||
rpcrdma-y := transport.o rpc_rdma.o verbs.o \
|
||||
fmr_ops.o frwr_ops.o \
|
||||
rpcrdma-y := transport.o rpc_rdma.o verbs.o frwr_ops.o \
|
||||
svc_rdma.o svc_rdma_backchannel.o svc_rdma_transport.o \
|
||||
svc_rdma_sendto.o svc_rdma_recvfrom.o svc_rdma_rw.o \
|
||||
module.o
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
* Support for backward direction RPCs on RPC/RDMA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sunrpc/xprt.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/sunrpc/svc_xprt.h>
|
||||
@@ -20,29 +19,16 @@
|
||||
|
||||
#undef RPCRDMA_BACKCHANNEL_DEBUG
|
||||
|
||||
static void rpcrdma_bc_free_rqst(struct rpcrdma_xprt *r_xprt,
|
||||
struct rpc_rqst *rqst)
|
||||
{
|
||||
struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
|
||||
struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
|
||||
|
||||
spin_lock(&buf->rb_reqslock);
|
||||
list_del(&req->rl_all);
|
||||
spin_unlock(&buf->rb_reqslock);
|
||||
|
||||
rpcrdma_destroy_req(req);
|
||||
}
|
||||
|
||||
static int rpcrdma_bc_setup_reqs(struct rpcrdma_xprt *r_xprt,
|
||||
unsigned int count)
|
||||
{
|
||||
struct rpc_xprt *xprt = &r_xprt->rx_xprt;
|
||||
struct rpcrdma_req *req;
|
||||
struct rpc_rqst *rqst;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < (count << 1); i++) {
|
||||
struct rpcrdma_regbuf *rb;
|
||||
struct rpcrdma_req *req;
|
||||
size_t size;
|
||||
|
||||
req = rpcrdma_create_req(r_xprt);
|
||||
@@ -68,7 +54,7 @@ static int rpcrdma_bc_setup_reqs(struct rpcrdma_xprt *r_xprt,
|
||||
return 0;
|
||||
|
||||
out_fail:
|
||||
rpcrdma_bc_free_rqst(r_xprt, rqst);
|
||||
rpcrdma_req_destroy(req);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -101,7 +87,6 @@ int xprt_rdma_bc_setup(struct rpc_xprt *xprt, unsigned int reqs)
|
||||
goto out_free;
|
||||
|
||||
r_xprt->rx_buf.rb_bc_srv_max_requests = reqs;
|
||||
request_module("svcrdma");
|
||||
trace_xprtrdma_cb_setup(r_xprt, reqs);
|
||||
return 0;
|
||||
|
||||
@@ -173,21 +158,21 @@ static int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst)
|
||||
*/
|
||||
int xprt_rdma_bc_send_reply(struct rpc_rqst *rqst)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt);
|
||||
struct rpc_xprt *xprt = rqst->rq_xprt;
|
||||
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
|
||||
struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
|
||||
int rc;
|
||||
|
||||
if (!xprt_connected(rqst->rq_xprt))
|
||||
goto drop_connection;
|
||||
if (!xprt_connected(xprt))
|
||||
return -ENOTCONN;
|
||||
|
||||
if (!xprt_request_get_cong(rqst->rq_xprt, rqst))
|
||||
if (!xprt_request_get_cong(xprt, rqst))
|
||||
return -EBADSLT;
|
||||
|
||||
rc = rpcrdma_bc_marshal_reply(rqst);
|
||||
if (rc < 0)
|
||||
goto failed_marshal;
|
||||
|
||||
rpcrdma_post_recvs(r_xprt, true);
|
||||
if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req))
|
||||
goto drop_connection;
|
||||
return 0;
|
||||
@@ -196,7 +181,7 @@ failed_marshal:
|
||||
if (rc != -ENOTCONN)
|
||||
return rc;
|
||||
drop_connection:
|
||||
xprt_disconnect_done(rqst->rq_xprt);
|
||||
xprt_rdma_close(xprt);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
@@ -207,7 +192,6 @@ drop_connection:
|
||||
*/
|
||||
void xprt_rdma_bc_destroy(struct rpc_xprt *xprt, unsigned int reqs)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
|
||||
struct rpc_rqst *rqst, *tmp;
|
||||
|
||||
spin_lock(&xprt->bc_pa_lock);
|
||||
@@ -215,7 +199,7 @@ void xprt_rdma_bc_destroy(struct rpc_xprt *xprt, unsigned int reqs)
|
||||
list_del(&rqst->rq_bc_pa_list);
|
||||
spin_unlock(&xprt->bc_pa_lock);
|
||||
|
||||
rpcrdma_bc_free_rqst(r_xprt, rqst);
|
||||
rpcrdma_req_destroy(rpcr_to_rdmar(rqst));
|
||||
|
||||
spin_lock(&xprt->bc_pa_lock);
|
||||
}
|
||||
@@ -231,9 +215,6 @@ void xprt_rdma_bc_free_rqst(struct rpc_rqst *rqst)
|
||||
struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
|
||||
struct rpc_xprt *xprt = rqst->rq_xprt;
|
||||
|
||||
dprintk("RPC: %s: freeing rqst %p (req %p)\n",
|
||||
__func__, rqst, req);
|
||||
|
||||
rpcrdma_recv_buffer_put(req->rl_reply);
|
||||
req->rl_reply = NULL;
|
||||
|
||||
@@ -319,7 +300,7 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt,
|
||||
|
||||
out_overflow:
|
||||
pr_warn("RPC/RDMA backchannel overflow\n");
|
||||
xprt_disconnect_done(xprt);
|
||||
xprt_force_disconnect(xprt);
|
||||
/* This receive buffer gets reposted automatically
|
||||
* when the connection is re-established.
|
||||
*/
|
||||
|
||||
@@ -1,337 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2015, 2017 Oracle. All rights reserved.
|
||||
* Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Lightweight memory registration using Fast Memory Regions (FMR).
|
||||
* Referred to sometimes as MTHCAFMR mode.
|
||||
*
|
||||
* FMR uses synchronous memory registration and deregistration.
|
||||
* FMR registration is known to be fast, but FMR deregistration
|
||||
* can take tens of usecs to complete.
|
||||
*/
|
||||
|
||||
/* Normal operation
|
||||
*
|
||||
* A Memory Region is prepared for RDMA READ or WRITE using the
|
||||
* ib_map_phys_fmr verb (fmr_op_map). When the RDMA operation is
|
||||
* finished, the Memory Region is unmapped using the ib_unmap_fmr
|
||||
* verb (fmr_op_unmap).
|
||||
*/
|
||||
|
||||
#include <linux/sunrpc/svc_rdma.h>
|
||||
|
||||
#include "xprt_rdma.h"
|
||||
#include <trace/events/rpcrdma.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||
#endif
|
||||
|
||||
/* Maximum scatter/gather per FMR */
|
||||
#define RPCRDMA_MAX_FMR_SGES (64)
|
||||
|
||||
/* Access mode of externally registered pages */
|
||||
enum {
|
||||
RPCRDMA_FMR_ACCESS_FLAGS = IB_ACCESS_REMOTE_WRITE |
|
||||
IB_ACCESS_REMOTE_READ,
|
||||
};
|
||||
|
||||
bool
|
||||
fmr_is_supported(struct rpcrdma_ia *ia)
|
||||
{
|
||||
if (!ia->ri_device->ops.alloc_fmr) {
|
||||
pr_info("rpcrdma: 'fmr' mode is not supported by device %s\n",
|
||||
ia->ri_device->name);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
__fmr_unmap(struct rpcrdma_mr *mr)
|
||||
{
|
||||
LIST_HEAD(l);
|
||||
int rc;
|
||||
|
||||
list_add(&mr->fmr.fm_mr->list, &l);
|
||||
rc = ib_unmap_fmr(&l);
|
||||
list_del(&mr->fmr.fm_mr->list);
|
||||
if (rc)
|
||||
pr_err("rpcrdma: final ib_unmap_fmr for %p failed %i\n",
|
||||
mr, rc);
|
||||
}
|
||||
|
||||
/* Release an MR.
|
||||
*/
|
||||
static void
|
||||
fmr_op_release_mr(struct rpcrdma_mr *mr)
|
||||
{
|
||||
int rc;
|
||||
|
||||
kfree(mr->fmr.fm_physaddrs);
|
||||
kfree(mr->mr_sg);
|
||||
|
||||
/* In case this one was left mapped, try to unmap it
|
||||
* to prevent dealloc_fmr from failing with EBUSY
|
||||
*/
|
||||
__fmr_unmap(mr);
|
||||
|
||||
rc = ib_dealloc_fmr(mr->fmr.fm_mr);
|
||||
if (rc)
|
||||
pr_err("rpcrdma: final ib_dealloc_fmr for %p returned %i\n",
|
||||
mr, rc);
|
||||
|
||||
kfree(mr);
|
||||
}
|
||||
|
||||
/* MRs are dynamically allocated, so simply clean up and release the MR.
|
||||
* A replacement MR will subsequently be allocated on demand.
|
||||
*/
|
||||
static void
|
||||
fmr_mr_recycle_worker(struct work_struct *work)
|
||||
{
|
||||
struct rpcrdma_mr *mr = container_of(work, struct rpcrdma_mr, mr_recycle);
|
||||
struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
|
||||
|
||||
trace_xprtrdma_mr_recycle(mr);
|
||||
|
||||
trace_xprtrdma_mr_unmap(mr);
|
||||
ib_dma_unmap_sg(r_xprt->rx_ia.ri_device,
|
||||
mr->mr_sg, mr->mr_nents, mr->mr_dir);
|
||||
|
||||
spin_lock(&r_xprt->rx_buf.rb_mrlock);
|
||||
list_del(&mr->mr_all);
|
||||
r_xprt->rx_stats.mrs_recycled++;
|
||||
spin_unlock(&r_xprt->rx_buf.rb_mrlock);
|
||||
fmr_op_release_mr(mr);
|
||||
}
|
||||
|
||||
static int
|
||||
fmr_op_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr)
|
||||
{
|
||||
static struct ib_fmr_attr fmr_attr = {
|
||||
.max_pages = RPCRDMA_MAX_FMR_SGES,
|
||||
.max_maps = 1,
|
||||
.page_shift = PAGE_SHIFT
|
||||
};
|
||||
|
||||
mr->fmr.fm_physaddrs = kcalloc(RPCRDMA_MAX_FMR_SGES,
|
||||
sizeof(u64), GFP_KERNEL);
|
||||
if (!mr->fmr.fm_physaddrs)
|
||||
goto out_free;
|
||||
|
||||
mr->mr_sg = kcalloc(RPCRDMA_MAX_FMR_SGES,
|
||||
sizeof(*mr->mr_sg), GFP_KERNEL);
|
||||
if (!mr->mr_sg)
|
||||
goto out_free;
|
||||
|
||||
sg_init_table(mr->mr_sg, RPCRDMA_MAX_FMR_SGES);
|
||||
|
||||
mr->fmr.fm_mr = ib_alloc_fmr(ia->ri_pd, RPCRDMA_FMR_ACCESS_FLAGS,
|
||||
&fmr_attr);
|
||||
if (IS_ERR(mr->fmr.fm_mr))
|
||||
goto out_fmr_err;
|
||||
|
||||
INIT_LIST_HEAD(&mr->mr_list);
|
||||
INIT_WORK(&mr->mr_recycle, fmr_mr_recycle_worker);
|
||||
return 0;
|
||||
|
||||
out_fmr_err:
|
||||
dprintk("RPC: %s: ib_alloc_fmr returned %ld\n", __func__,
|
||||
PTR_ERR(mr->fmr.fm_mr));
|
||||
|
||||
out_free:
|
||||
kfree(mr->mr_sg);
|
||||
kfree(mr->fmr.fm_physaddrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* On success, sets:
|
||||
* ep->rep_attr.cap.max_send_wr
|
||||
* ep->rep_attr.cap.max_recv_wr
|
||||
* cdata->max_requests
|
||||
* ia->ri_max_segs
|
||||
*/
|
||||
static int
|
||||
fmr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
|
||||
struct rpcrdma_create_data_internal *cdata)
|
||||
{
|
||||
int max_qp_wr;
|
||||
|
||||
max_qp_wr = ia->ri_device->attrs.max_qp_wr;
|
||||
max_qp_wr -= RPCRDMA_BACKWARD_WRS;
|
||||
max_qp_wr -= 1;
|
||||
if (max_qp_wr < RPCRDMA_MIN_SLOT_TABLE)
|
||||
return -ENOMEM;
|
||||
if (cdata->max_requests > max_qp_wr)
|
||||
cdata->max_requests = max_qp_wr;
|
||||
ep->rep_attr.cap.max_send_wr = cdata->max_requests;
|
||||
ep->rep_attr.cap.max_send_wr += RPCRDMA_BACKWARD_WRS;
|
||||
ep->rep_attr.cap.max_send_wr += 1; /* for ib_drain_sq */
|
||||
ep->rep_attr.cap.max_recv_wr = cdata->max_requests;
|
||||
ep->rep_attr.cap.max_recv_wr += RPCRDMA_BACKWARD_WRS;
|
||||
ep->rep_attr.cap.max_recv_wr += 1; /* for ib_drain_rq */
|
||||
|
||||
ia->ri_max_segs = max_t(unsigned int, 1, RPCRDMA_MAX_DATA_SEGS /
|
||||
RPCRDMA_MAX_FMR_SGES);
|
||||
ia->ri_max_segs += 2; /* segments for head and tail buffers */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FMR mode conveys up to 64 pages of payload per chunk segment.
|
||||
*/
|
||||
static size_t
|
||||
fmr_op_maxpages(struct rpcrdma_xprt *r_xprt)
|
||||
{
|
||||
return min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS,
|
||||
RPCRDMA_MAX_HDR_SEGS * RPCRDMA_MAX_FMR_SGES);
|
||||
}
|
||||
|
||||
/* Use the ib_map_phys_fmr() verb to register a memory region
|
||||
* for remote access via RDMA READ or RDMA WRITE.
|
||||
*/
|
||||
static struct rpcrdma_mr_seg *
|
||||
fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
|
||||
int nsegs, bool writing, struct rpcrdma_mr **out)
|
||||
{
|
||||
struct rpcrdma_mr_seg *seg1 = seg;
|
||||
int len, pageoff, i, rc;
|
||||
struct rpcrdma_mr *mr;
|
||||
u64 *dma_pages;
|
||||
|
||||
mr = rpcrdma_mr_get(r_xprt);
|
||||
if (!mr)
|
||||
return ERR_PTR(-EAGAIN);
|
||||
|
||||
pageoff = offset_in_page(seg1->mr_offset);
|
||||
seg1->mr_offset -= pageoff; /* start of page */
|
||||
seg1->mr_len += pageoff;
|
||||
len = -pageoff;
|
||||
if (nsegs > RPCRDMA_MAX_FMR_SGES)
|
||||
nsegs = RPCRDMA_MAX_FMR_SGES;
|
||||
for (i = 0; i < nsegs;) {
|
||||
if (seg->mr_page)
|
||||
sg_set_page(&mr->mr_sg[i],
|
||||
seg->mr_page,
|
||||
seg->mr_len,
|
||||
offset_in_page(seg->mr_offset));
|
||||
else
|
||||
sg_set_buf(&mr->mr_sg[i], seg->mr_offset,
|
||||
seg->mr_len);
|
||||
len += seg->mr_len;
|
||||
++seg;
|
||||
++i;
|
||||
/* Check for holes */
|
||||
if ((i < nsegs && offset_in_page(seg->mr_offset)) ||
|
||||
offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
|
||||
break;
|
||||
}
|
||||
mr->mr_dir = rpcrdma_data_dir(writing);
|
||||
|
||||
mr->mr_nents = ib_dma_map_sg(r_xprt->rx_ia.ri_device,
|
||||
mr->mr_sg, i, mr->mr_dir);
|
||||
if (!mr->mr_nents)
|
||||
goto out_dmamap_err;
|
||||
trace_xprtrdma_mr_map(mr);
|
||||
|
||||
for (i = 0, dma_pages = mr->fmr.fm_physaddrs; i < mr->mr_nents; i++)
|
||||
dma_pages[i] = sg_dma_address(&mr->mr_sg[i]);
|
||||
rc = ib_map_phys_fmr(mr->fmr.fm_mr, dma_pages, mr->mr_nents,
|
||||
dma_pages[0]);
|
||||
if (rc)
|
||||
goto out_maperr;
|
||||
|
||||
mr->mr_handle = mr->fmr.fm_mr->rkey;
|
||||
mr->mr_length = len;
|
||||
mr->mr_offset = dma_pages[0] + pageoff;
|
||||
|
||||
*out = mr;
|
||||
return seg;
|
||||
|
||||
out_dmamap_err:
|
||||
pr_err("rpcrdma: failed to DMA map sg %p sg_nents %d\n",
|
||||
mr->mr_sg, i);
|
||||
rpcrdma_mr_put(mr);
|
||||
return ERR_PTR(-EIO);
|
||||
|
||||
out_maperr:
|
||||
pr_err("rpcrdma: ib_map_phys_fmr %u@0x%llx+%i (%d) status %i\n",
|
||||
len, (unsigned long long)dma_pages[0],
|
||||
pageoff, mr->mr_nents, rc);
|
||||
rpcrdma_mr_unmap_and_put(mr);
|
||||
return ERR_PTR(-EIO);
|
||||
}
|
||||
|
||||
/* Post Send WR containing the RPC Call message.
|
||||
*/
|
||||
static int
|
||||
fmr_op_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req)
|
||||
{
|
||||
return ib_post_send(ia->ri_id->qp, &req->rl_sendctx->sc_wr, NULL);
|
||||
}
|
||||
|
||||
/* Invalidate all memory regions that were registered for "req".
|
||||
*
|
||||
* Sleeps until it is safe for the host CPU to access the
|
||||
* previously mapped memory regions.
|
||||
*
|
||||
* Caller ensures that @mrs is not empty before the call. This
|
||||
* function empties the list.
|
||||
*/
|
||||
static void
|
||||
fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mrs)
|
||||
{
|
||||
struct rpcrdma_mr *mr;
|
||||
LIST_HEAD(unmap_list);
|
||||
int rc;
|
||||
|
||||
/* ORDER: Invalidate all of the req's MRs first
|
||||
*
|
||||
* ib_unmap_fmr() is slow, so use a single call instead
|
||||
* of one call per mapped FMR.
|
||||
*/
|
||||
list_for_each_entry(mr, mrs, mr_list) {
|
||||
dprintk("RPC: %s: unmapping fmr %p\n",
|
||||
__func__, &mr->fmr);
|
||||
trace_xprtrdma_mr_localinv(mr);
|
||||
list_add_tail(&mr->fmr.fm_mr->list, &unmap_list);
|
||||
}
|
||||
r_xprt->rx_stats.local_inv_needed++;
|
||||
rc = ib_unmap_fmr(&unmap_list);
|
||||
if (rc)
|
||||
goto out_release;
|
||||
|
||||
/* ORDER: Now DMA unmap all of the req's MRs, and return
|
||||
* them to the free MW list.
|
||||
*/
|
||||
while (!list_empty(mrs)) {
|
||||
mr = rpcrdma_mr_pop(mrs);
|
||||
list_del(&mr->fmr.fm_mr->list);
|
||||
rpcrdma_mr_unmap_and_put(mr);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
out_release:
|
||||
pr_err("rpcrdma: ib_unmap_fmr failed (%i)\n", rc);
|
||||
|
||||
while (!list_empty(mrs)) {
|
||||
mr = rpcrdma_mr_pop(mrs);
|
||||
list_del(&mr->fmr.fm_mr->list);
|
||||
rpcrdma_mr_recycle(mr);
|
||||
}
|
||||
}
|
||||
|
||||
const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = {
|
||||
.ro_map = fmr_op_map,
|
||||
.ro_send = fmr_op_send,
|
||||
.ro_unmap_sync = fmr_op_unmap_sync,
|
||||
.ro_open = fmr_op_open,
|
||||
.ro_maxpages = fmr_op_maxpages,
|
||||
.ro_init_mr = fmr_op_init_mr,
|
||||
.ro_release_mr = fmr_op_release_mr,
|
||||
.ro_displayname = "fmr",
|
||||
.ro_send_w_inv_ok = 0,
|
||||
};
|
||||
@@ -15,21 +15,21 @@
|
||||
/* Normal operation
|
||||
*
|
||||
* A Memory Region is prepared for RDMA READ or WRITE using a FAST_REG
|
||||
* Work Request (frwr_op_map). When the RDMA operation is finished, this
|
||||
* Work Request (frwr_map). When the RDMA operation is finished, this
|
||||
* Memory Region is invalidated using a LOCAL_INV Work Request
|
||||
* (frwr_op_unmap_sync).
|
||||
* (frwr_unmap_sync).
|
||||
*
|
||||
* Typically these Work Requests are not signaled, and neither are RDMA
|
||||
* SEND Work Requests (with the exception of signaling occasionally to
|
||||
* prevent provider work queue overflows). This greatly reduces HCA
|
||||
* interrupt workload.
|
||||
*
|
||||
* As an optimization, frwr_op_unmap marks MRs INVALID before the
|
||||
* As an optimization, frwr_unmap marks MRs INVALID before the
|
||||
* LOCAL_INV WR is posted. If posting succeeds, the MR is placed on
|
||||
* rb_mrs immediately so that no work (like managing a linked list
|
||||
* under a spinlock) is needed in the completion upcall.
|
||||
*
|
||||
* But this means that frwr_op_map() can occasionally encounter an MR
|
||||
* But this means that frwr_map() can occasionally encounter an MR
|
||||
* that is INVALID but the LOCAL_INV WR has not completed. Work Queue
|
||||
* ordering prevents a subsequent FAST_REG WR from executing against
|
||||
* that MR while it is still being invalidated.
|
||||
@@ -57,14 +57,14 @@
|
||||
* FLUSHED_LI: The MR was being invalidated when the QP entered ERROR
|
||||
* state, and the pending WR was flushed.
|
||||
*
|
||||
* When frwr_op_map encounters FLUSHED and VALID MRs, they are recovered
|
||||
* When frwr_map encounters FLUSHED and VALID MRs, they are recovered
|
||||
* with ib_dereg_mr and then are re-initialized. Because MR recovery
|
||||
* allocates fresh resources, it is deferred to a workqueue, and the
|
||||
* recovered MRs are placed back on the rb_mrs list when recovery is
|
||||
* complete. frwr_op_map allocates another MR for the current RPC while
|
||||
* complete. frwr_map allocates another MR for the current RPC while
|
||||
* the broken MR is reset.
|
||||
*
|
||||
* To ensure that frwr_op_map doesn't encounter an MR that is marked
|
||||
* To ensure that frwr_map doesn't encounter an MR that is marked
|
||||
* INVALID but that is about to be flushed due to a previous transport
|
||||
* disconnect, the transport connect worker attempts to drain all
|
||||
* pending send queue WRs before the transport is reconnected.
|
||||
@@ -80,8 +80,13 @@
|
||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||
#endif
|
||||
|
||||
bool
|
||||
frwr_is_supported(struct rpcrdma_ia *ia)
|
||||
/**
|
||||
* frwr_is_supported - Check if device supports FRWR
|
||||
* @ia: interface adapter to check
|
||||
*
|
||||
* Returns true if device supports FRWR, otherwise false
|
||||
*/
|
||||
bool frwr_is_supported(struct rpcrdma_ia *ia)
|
||||
{
|
||||
struct ib_device_attr *attrs = &ia->ri_device->attrs;
|
||||
|
||||
@@ -97,15 +102,18 @@ out_not_supported:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
frwr_op_release_mr(struct rpcrdma_mr *mr)
|
||||
/**
|
||||
* frwr_release_mr - Destroy one MR
|
||||
* @mr: MR allocated by frwr_init_mr
|
||||
*
|
||||
*/
|
||||
void frwr_release_mr(struct rpcrdma_mr *mr)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ib_dereg_mr(mr->frwr.fr_mr);
|
||||
if (rc)
|
||||
pr_err("rpcrdma: final ib_dereg_mr for %p returned %i\n",
|
||||
mr, rc);
|
||||
trace_xprtrdma_frwr_dereg(mr, rc);
|
||||
kfree(mr->mr_sg);
|
||||
kfree(mr);
|
||||
}
|
||||
@@ -117,60 +125,78 @@ static void
|
||||
frwr_mr_recycle_worker(struct work_struct *work)
|
||||
{
|
||||
struct rpcrdma_mr *mr = container_of(work, struct rpcrdma_mr, mr_recycle);
|
||||
enum rpcrdma_frwr_state state = mr->frwr.fr_state;
|
||||
struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
|
||||
|
||||
trace_xprtrdma_mr_recycle(mr);
|
||||
|
||||
if (state != FRWR_FLUSHED_LI) {
|
||||
if (mr->mr_dir != DMA_NONE) {
|
||||
trace_xprtrdma_mr_unmap(mr);
|
||||
ib_dma_unmap_sg(r_xprt->rx_ia.ri_device,
|
||||
mr->mr_sg, mr->mr_nents, mr->mr_dir);
|
||||
mr->mr_dir = DMA_NONE;
|
||||
}
|
||||
|
||||
spin_lock(&r_xprt->rx_buf.rb_mrlock);
|
||||
list_del(&mr->mr_all);
|
||||
r_xprt->rx_stats.mrs_recycled++;
|
||||
spin_unlock(&r_xprt->rx_buf.rb_mrlock);
|
||||
frwr_op_release_mr(mr);
|
||||
|
||||
frwr_release_mr(mr);
|
||||
}
|
||||
|
||||
static int
|
||||
frwr_op_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr)
|
||||
/**
|
||||
* frwr_init_mr - Initialize one MR
|
||||
* @ia: interface adapter
|
||||
* @mr: generic MR to prepare for FRWR
|
||||
*
|
||||
* Returns zero if successful. Otherwise a negative errno
|
||||
* is returned.
|
||||
*/
|
||||
int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr)
|
||||
{
|
||||
unsigned int depth = ia->ri_max_frwr_depth;
|
||||
struct rpcrdma_frwr *frwr = &mr->frwr;
|
||||
struct scatterlist *sg;
|
||||
struct ib_mr *frmr;
|
||||
int rc;
|
||||
|
||||
frwr->fr_mr = ib_alloc_mr(ia->ri_pd, ia->ri_mrtype, depth);
|
||||
if (IS_ERR(frwr->fr_mr))
|
||||
frmr = ib_alloc_mr(ia->ri_pd, ia->ri_mrtype, depth);
|
||||
if (IS_ERR(frmr))
|
||||
goto out_mr_err;
|
||||
|
||||
mr->mr_sg = kcalloc(depth, sizeof(*mr->mr_sg), GFP_KERNEL);
|
||||
if (!mr->mr_sg)
|
||||
sg = kcalloc(depth, sizeof(*sg), GFP_KERNEL);
|
||||
if (!sg)
|
||||
goto out_list_err;
|
||||
|
||||
mr->frwr.fr_mr = frmr;
|
||||
mr->frwr.fr_state = FRWR_IS_INVALID;
|
||||
mr->mr_dir = DMA_NONE;
|
||||
INIT_LIST_HEAD(&mr->mr_list);
|
||||
INIT_WORK(&mr->mr_recycle, frwr_mr_recycle_worker);
|
||||
sg_init_table(mr->mr_sg, depth);
|
||||
init_completion(&frwr->fr_linv_done);
|
||||
init_completion(&mr->frwr.fr_linv_done);
|
||||
|
||||
sg_init_table(sg, depth);
|
||||
mr->mr_sg = sg;
|
||||
return 0;
|
||||
|
||||
out_mr_err:
|
||||
rc = PTR_ERR(frwr->fr_mr);
|
||||
dprintk("RPC: %s: ib_alloc_mr status %i\n",
|
||||
__func__, rc);
|
||||
rc = PTR_ERR(frmr);
|
||||
trace_xprtrdma_frwr_alloc(mr, rc);
|
||||
return rc;
|
||||
|
||||
out_list_err:
|
||||
rc = -ENOMEM;
|
||||
dprintk("RPC: %s: sg allocation failure\n",
|
||||
__func__);
|
||||
ib_dereg_mr(frwr->fr_mr);
|
||||
return rc;
|
||||
ib_dereg_mr(frmr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* On success, sets:
|
||||
/**
|
||||
* frwr_open - Prepare an endpoint for use with FRWR
|
||||
* @ia: interface adapter this endpoint will use
|
||||
* @ep: endpoint to prepare
|
||||
* @cdata: transport parameters
|
||||
*
|
||||
* On success, sets:
|
||||
* ep->rep_attr.cap.max_send_wr
|
||||
* ep->rep_attr.cap.max_recv_wr
|
||||
* cdata->max_requests
|
||||
@@ -179,9 +205,10 @@ out_list_err:
|
||||
* And these FRWR-related fields:
|
||||
* ia->ri_max_frwr_depth
|
||||
* ia->ri_mrtype
|
||||
*
|
||||
* On failure, a negative errno is returned.
|
||||
*/
|
||||
static int
|
||||
frwr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
|
||||
int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
|
||||
struct rpcrdma_create_data_internal *cdata)
|
||||
{
|
||||
struct ib_device_attr *attrs = &ia->ri_device->attrs;
|
||||
@@ -191,10 +218,17 @@ frwr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
|
||||
if (attrs->device_cap_flags & IB_DEVICE_SG_GAPS_REG)
|
||||
ia->ri_mrtype = IB_MR_TYPE_SG_GAPS;
|
||||
|
||||
ia->ri_max_frwr_depth =
|
||||
min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS,
|
||||
attrs->max_fast_reg_page_list_len);
|
||||
dprintk("RPC: %s: device's max FR page list len = %u\n",
|
||||
/* Quirk: Some devices advertise a large max_fast_reg_page_list_len
|
||||
* capability, but perform optimally when the MRs are not larger
|
||||
* than a page.
|
||||
*/
|
||||
if (attrs->max_sge_rd > 1)
|
||||
ia->ri_max_frwr_depth = attrs->max_sge_rd;
|
||||
else
|
||||
ia->ri_max_frwr_depth = attrs->max_fast_reg_page_list_len;
|
||||
if (ia->ri_max_frwr_depth > RPCRDMA_MAX_DATA_SEGS)
|
||||
ia->ri_max_frwr_depth = RPCRDMA_MAX_DATA_SEGS;
|
||||
dprintk("RPC: %s: max FR page list depth = %u\n",
|
||||
__func__, ia->ri_max_frwr_depth);
|
||||
|
||||
/* Add room for frwr register and invalidate WRs.
|
||||
@@ -242,20 +276,28 @@ frwr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
|
||||
|
||||
ia->ri_max_segs = max_t(unsigned int, 1, RPCRDMA_MAX_DATA_SEGS /
|
||||
ia->ri_max_frwr_depth);
|
||||
ia->ri_max_segs += 2; /* segments for head and tail buffers */
|
||||
/* Reply chunks require segments for head and tail buffers */
|
||||
ia->ri_max_segs += 2;
|
||||
if (ia->ri_max_segs > RPCRDMA_MAX_HDR_SEGS)
|
||||
ia->ri_max_segs = RPCRDMA_MAX_HDR_SEGS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FRWR mode conveys a list of pages per chunk segment. The
|
||||
/**
|
||||
* frwr_maxpages - Compute size of largest payload
|
||||
* @r_xprt: transport
|
||||
*
|
||||
* Returns maximum size of an RPC message, in pages.
|
||||
*
|
||||
* FRWR mode conveys a list of pages per chunk segment. The
|
||||
* maximum length of that list is the FRWR page list depth.
|
||||
*/
|
||||
static size_t
|
||||
frwr_op_maxpages(struct rpcrdma_xprt *r_xprt)
|
||||
size_t frwr_maxpages(struct rpcrdma_xprt *r_xprt)
|
||||
{
|
||||
struct rpcrdma_ia *ia = &r_xprt->rx_ia;
|
||||
|
||||
return min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS,
|
||||
RPCRDMA_MAX_HDR_SEGS * ia->ri_max_frwr_depth);
|
||||
(ia->ri_max_segs - 2) * ia->ri_max_frwr_depth);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -332,12 +374,25 @@ frwr_wc_localinv_wake(struct ib_cq *cq, struct ib_wc *wc)
|
||||
trace_xprtrdma_wc_li_wake(wc, frwr);
|
||||
}
|
||||
|
||||
/* Post a REG_MR Work Request to register a memory region
|
||||
/**
|
||||
* frwr_map - Register a memory region
|
||||
* @r_xprt: controlling transport
|
||||
* @seg: memory region co-ordinates
|
||||
* @nsegs: number of segments remaining
|
||||
* @writing: true when RDMA Write will be used
|
||||
* @xid: XID of RPC using the registered memory
|
||||
* @out: initialized MR
|
||||
*
|
||||
* Prepare a REG_MR Work Request to register a memory region
|
||||
* for remote access via RDMA READ or RDMA WRITE.
|
||||
*
|
||||
* Returns the next segment or a negative errno pointer.
|
||||
* On success, the prepared MR is planted in @out.
|
||||
*/
|
||||
static struct rpcrdma_mr_seg *
|
||||
frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
|
||||
int nsegs, bool writing, struct rpcrdma_mr **out)
|
||||
struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
|
||||
struct rpcrdma_mr_seg *seg,
|
||||
int nsegs, bool writing, u32 xid,
|
||||
struct rpcrdma_mr **out)
|
||||
{
|
||||
struct rpcrdma_ia *ia = &r_xprt->rx_ia;
|
||||
bool holes_ok = ia->ri_mrtype == IB_MR_TYPE_SG_GAPS;
|
||||
@@ -384,13 +439,14 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
|
||||
mr->mr_nents = ib_dma_map_sg(ia->ri_device, mr->mr_sg, i, mr->mr_dir);
|
||||
if (!mr->mr_nents)
|
||||
goto out_dmamap_err;
|
||||
trace_xprtrdma_mr_map(mr);
|
||||
|
||||
ibmr = frwr->fr_mr;
|
||||
n = ib_map_mr_sg(ibmr, mr->mr_sg, mr->mr_nents, NULL, PAGE_SIZE);
|
||||
if (unlikely(n != mr->mr_nents))
|
||||
goto out_mapmr_err;
|
||||
|
||||
ibmr->iova &= 0x00000000ffffffff;
|
||||
ibmr->iova |= ((u64)cpu_to_be32(xid)) << 32;
|
||||
key = (u8)(ibmr->rkey & 0x000000FF);
|
||||
ib_update_fast_reg_key(ibmr, ++key);
|
||||
|
||||
@@ -404,32 +460,35 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
|
||||
mr->mr_handle = ibmr->rkey;
|
||||
mr->mr_length = ibmr->length;
|
||||
mr->mr_offset = ibmr->iova;
|
||||
trace_xprtrdma_mr_map(mr);
|
||||
|
||||
*out = mr;
|
||||
return seg;
|
||||
|
||||
out_dmamap_err:
|
||||
pr_err("rpcrdma: failed to DMA map sg %p sg_nents %d\n",
|
||||
mr->mr_sg, i);
|
||||
frwr->fr_state = FRWR_IS_INVALID;
|
||||
trace_xprtrdma_frwr_sgerr(mr, i);
|
||||
rpcrdma_mr_put(mr);
|
||||
return ERR_PTR(-EIO);
|
||||
|
||||
out_mapmr_err:
|
||||
pr_err("rpcrdma: failed to map mr %p (%d/%d)\n",
|
||||
frwr->fr_mr, n, mr->mr_nents);
|
||||
trace_xprtrdma_frwr_maperr(mr, n);
|
||||
rpcrdma_mr_recycle(mr);
|
||||
return ERR_PTR(-EIO);
|
||||
}
|
||||
|
||||
/* Post Send WR containing the RPC Call message.
|
||||
/**
|
||||
* frwr_send - post Send WR containing the RPC Call message
|
||||
* @ia: interface adapter
|
||||
* @req: Prepared RPC Call
|
||||
*
|
||||
* For FRMR, chain any FastReg WRs to the Send WR. Only a
|
||||
* For FRWR, chain any FastReg WRs to the Send WR. Only a
|
||||
* single ib_post_send call is needed to register memory
|
||||
* and then post the Send WR.
|
||||
*
|
||||
* Returns the result of ib_post_send.
|
||||
*/
|
||||
static int
|
||||
frwr_op_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req)
|
||||
int frwr_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req)
|
||||
{
|
||||
struct ib_send_wr *post_wr;
|
||||
struct rpcrdma_mr *mr;
|
||||
@@ -451,15 +510,18 @@ frwr_op_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req)
|
||||
}
|
||||
|
||||
/* If ib_post_send fails, the next ->send_request for
|
||||
* @req will queue these MWs for recovery.
|
||||
* @req will queue these MRs for recovery.
|
||||
*/
|
||||
return ib_post_send(ia->ri_id->qp, post_wr, NULL);
|
||||
}
|
||||
|
||||
/* Handle a remotely invalidated mr on the @mrs list
|
||||
/**
|
||||
* frwr_reminv - handle a remotely invalidated mr on the @mrs list
|
||||
* @rep: Received reply
|
||||
* @mrs: list of MRs to check
|
||||
*
|
||||
*/
|
||||
static void
|
||||
frwr_op_reminv(struct rpcrdma_rep *rep, struct list_head *mrs)
|
||||
void frwr_reminv(struct rpcrdma_rep *rep, struct list_head *mrs)
|
||||
{
|
||||
struct rpcrdma_mr *mr;
|
||||
|
||||
@@ -473,7 +535,10 @@ frwr_op_reminv(struct rpcrdma_rep *rep, struct list_head *mrs)
|
||||
}
|
||||
}
|
||||
|
||||
/* Invalidate all memory regions that were registered for "req".
|
||||
/**
|
||||
* frwr_unmap_sync - invalidate memory regions that were registered for @req
|
||||
* @r_xprt: controlling transport
|
||||
* @mrs: list of MRs to process
|
||||
*
|
||||
* Sleeps until it is safe for the host CPU to access the
|
||||
* previously mapped memory regions.
|
||||
@@ -481,8 +546,7 @@ frwr_op_reminv(struct rpcrdma_rep *rep, struct list_head *mrs)
|
||||
* Caller ensures that @mrs is not empty before the call. This
|
||||
* function empties the list.
|
||||
*/
|
||||
static void
|
||||
frwr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mrs)
|
||||
void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mrs)
|
||||
{
|
||||
struct ib_send_wr *first, **prev, *last;
|
||||
const struct ib_send_wr *bad_wr;
|
||||
@@ -561,20 +625,7 @@ out_release:
|
||||
mr = container_of(frwr, struct rpcrdma_mr, frwr);
|
||||
bad_wr = bad_wr->next;
|
||||
|
||||
list_del(&mr->mr_list);
|
||||
frwr_op_release_mr(mr);
|
||||
list_del_init(&mr->mr_list);
|
||||
rpcrdma_mr_recycle(mr);
|
||||
}
|
||||
}
|
||||
|
||||
const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = {
|
||||
.ro_map = frwr_op_map,
|
||||
.ro_send = frwr_op_send,
|
||||
.ro_reminv = frwr_op_reminv,
|
||||
.ro_unmap_sync = frwr_op_unmap_sync,
|
||||
.ro_open = frwr_op_open,
|
||||
.ro_maxpages = frwr_op_maxpages,
|
||||
.ro_init_mr = frwr_op_init_mr,
|
||||
.ro_release_mr = frwr_op_release_mr,
|
||||
.ro_displayname = "frwr",
|
||||
.ro_send_w_inv_ok = RPCRDMA_CMP_F_SND_W_INV_OK,
|
||||
};
|
||||
|
||||
@@ -218,10 +218,11 @@ rpcrdma_convert_iovs(struct rpcrdma_xprt *r_xprt, struct xdr_buf *xdrbuf,
|
||||
ppages = xdrbuf->pages + (xdrbuf->page_base >> PAGE_SHIFT);
|
||||
page_base = offset_in_page(xdrbuf->page_base);
|
||||
while (len) {
|
||||
if (unlikely(!*ppages)) {
|
||||
/* XXX: Certain upper layer operations do
|
||||
* not provide receive buffer pages.
|
||||
/* ACL likes to be lazy in allocating pages - ACLs
|
||||
* are small by default but can get huge.
|
||||
*/
|
||||
if (unlikely(xdrbuf->flags & XDRBUF_SPARSE_PAGES)) {
|
||||
if (!*ppages)
|
||||
*ppages = alloc_page(GFP_ATOMIC);
|
||||
if (!*ppages)
|
||||
return -ENOBUFS;
|
||||
@@ -356,8 +357,7 @@ rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
|
||||
return nsegs;
|
||||
|
||||
do {
|
||||
seg = r_xprt->rx_ia.ri_ops->ro_map(r_xprt, seg, nsegs,
|
||||
false, &mr);
|
||||
seg = frwr_map(r_xprt, seg, nsegs, false, rqst->rq_xid, &mr);
|
||||
if (IS_ERR(seg))
|
||||
return PTR_ERR(seg);
|
||||
rpcrdma_mr_push(mr, &req->rl_registered);
|
||||
@@ -365,7 +365,7 @@ rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
|
||||
if (encode_read_segment(xdr, mr, pos) < 0)
|
||||
return -EMSGSIZE;
|
||||
|
||||
trace_xprtrdma_read_chunk(rqst->rq_task, pos, mr, nsegs);
|
||||
trace_xprtrdma_chunk_read(rqst->rq_task, pos, mr, nsegs);
|
||||
r_xprt->rx_stats.read_chunk_count++;
|
||||
nsegs -= mr->mr_nents;
|
||||
} while (nsegs);
|
||||
@@ -414,8 +414,7 @@ rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
|
||||
|
||||
nchunks = 0;
|
||||
do {
|
||||
seg = r_xprt->rx_ia.ri_ops->ro_map(r_xprt, seg, nsegs,
|
||||
true, &mr);
|
||||
seg = frwr_map(r_xprt, seg, nsegs, true, rqst->rq_xid, &mr);
|
||||
if (IS_ERR(seg))
|
||||
return PTR_ERR(seg);
|
||||
rpcrdma_mr_push(mr, &req->rl_registered);
|
||||
@@ -423,7 +422,7 @@ rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
|
||||
if (encode_rdma_segment(xdr, mr) < 0)
|
||||
return -EMSGSIZE;
|
||||
|
||||
trace_xprtrdma_write_chunk(rqst->rq_task, mr, nsegs);
|
||||
trace_xprtrdma_chunk_write(rqst->rq_task, mr, nsegs);
|
||||
r_xprt->rx_stats.write_chunk_count++;
|
||||
r_xprt->rx_stats.total_rdma_request += mr->mr_length;
|
||||
nchunks++;
|
||||
@@ -472,8 +471,7 @@ rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
|
||||
|
||||
nchunks = 0;
|
||||
do {
|
||||
seg = r_xprt->rx_ia.ri_ops->ro_map(r_xprt, seg, nsegs,
|
||||
true, &mr);
|
||||
seg = frwr_map(r_xprt, seg, nsegs, true, rqst->rq_xid, &mr);
|
||||
if (IS_ERR(seg))
|
||||
return PTR_ERR(seg);
|
||||
rpcrdma_mr_push(mr, &req->rl_registered);
|
||||
@@ -481,7 +479,7 @@ rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
|
||||
if (encode_rdma_segment(xdr, mr) < 0)
|
||||
return -EMSGSIZE;
|
||||
|
||||
trace_xprtrdma_reply_chunk(rqst->rq_task, mr, nsegs);
|
||||
trace_xprtrdma_chunk_reply(rqst->rq_task, mr, nsegs);
|
||||
r_xprt->rx_stats.reply_chunk_count++;
|
||||
r_xprt->rx_stats.total_rdma_request += mr->mr_length;
|
||||
nchunks++;
|
||||
@@ -667,7 +665,7 @@ out_mapping_overflow:
|
||||
|
||||
out_mapping_err:
|
||||
rpcrdma_unmap_sendctx(sc);
|
||||
pr_err("rpcrdma: Send mapping error\n");
|
||||
trace_xprtrdma_dma_maperr(sge[sge_no].addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1188,17 +1186,20 @@ rpcrdma_decode_error(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep,
|
||||
p = xdr_inline_decode(xdr, 2 * sizeof(*p));
|
||||
if (!p)
|
||||
break;
|
||||
dprintk("RPC: %5u: %s: server reports version error (%u-%u)\n",
|
||||
rqst->rq_task->tk_pid, __func__,
|
||||
be32_to_cpup(p), be32_to_cpu(*(p + 1)));
|
||||
dprintk("RPC: %s: server reports "
|
||||
"version error (%u-%u), xid %08x\n", __func__,
|
||||
be32_to_cpup(p), be32_to_cpu(*(p + 1)),
|
||||
be32_to_cpu(rep->rr_xid));
|
||||
break;
|
||||
case err_chunk:
|
||||
dprintk("RPC: %5u: %s: server reports header decoding error\n",
|
||||
rqst->rq_task->tk_pid, __func__);
|
||||
dprintk("RPC: %s: server reports "
|
||||
"header decoding error, xid %08x\n", __func__,
|
||||
be32_to_cpu(rep->rr_xid));
|
||||
break;
|
||||
default:
|
||||
dprintk("RPC: %5u: %s: server reports unrecognized error %d\n",
|
||||
rqst->rq_task->tk_pid, __func__, be32_to_cpup(p));
|
||||
dprintk("RPC: %s: server reports "
|
||||
"unrecognized error %d, xid %08x\n", __func__,
|
||||
be32_to_cpup(p), be32_to_cpu(rep->rr_xid));
|
||||
}
|
||||
|
||||
r_xprt->rx_stats.bad_reply_count++;
|
||||
@@ -1248,7 +1249,6 @@ out:
|
||||
out_badheader:
|
||||
trace_xprtrdma_reply_hdr(rep);
|
||||
r_xprt->rx_stats.bad_reply_count++;
|
||||
status = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1262,8 +1262,7 @@ void rpcrdma_release_rqst(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
|
||||
* RPC has relinquished all its Send Queue entries.
|
||||
*/
|
||||
if (!list_empty(&req->rl_registered))
|
||||
r_xprt->rx_ia.ri_ops->ro_unmap_sync(r_xprt,
|
||||
&req->rl_registered);
|
||||
frwr_unmap_sync(r_xprt, &req->rl_registered);
|
||||
|
||||
/* Ensure that any DMA mapped pages associated with
|
||||
* the Send of the RPC Call have been unmapped before
|
||||
@@ -1292,7 +1291,7 @@ void rpcrdma_deferred_completion(struct work_struct *work)
|
||||
|
||||
trace_xprtrdma_defer_cmp(rep);
|
||||
if (rep->rr_wc_flags & IB_WC_WITH_INVALIDATE)
|
||||
r_xprt->rx_ia.ri_ops->ro_reminv(rep, &req->rl_registered);
|
||||
frwr_reminv(rep, &req->rl_registered);
|
||||
rpcrdma_release_rqst(r_xprt, req);
|
||||
rpcrdma_complete_rqst(rep);
|
||||
}
|
||||
@@ -1312,11 +1311,6 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
|
||||
u32 credits;
|
||||
__be32 *p;
|
||||
|
||||
--buf->rb_posted_receives;
|
||||
|
||||
if (rep->rr_hdrbuf.head[0].iov_len == 0)
|
||||
goto out_badstatus;
|
||||
|
||||
/* Fixed transport header fields */
|
||||
xdr_init_decode(&rep->rr_stream, &rep->rr_hdrbuf,
|
||||
rep->rr_hdrbuf.head[0].iov_base);
|
||||
@@ -1356,36 +1350,30 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
|
||||
}
|
||||
|
||||
req = rpcr_to_rdmar(rqst);
|
||||
if (req->rl_reply) {
|
||||
trace_xprtrdma_leaked_rep(rqst, req->rl_reply);
|
||||
rpcrdma_recv_buffer_put(req->rl_reply);
|
||||
}
|
||||
req->rl_reply = rep;
|
||||
rep->rr_rqst = rqst;
|
||||
clear_bit(RPCRDMA_REQ_F_PENDING, &req->rl_flags);
|
||||
|
||||
trace_xprtrdma_reply(rqst->rq_task, rep, req, credits);
|
||||
|
||||
rpcrdma_post_recvs(r_xprt, false);
|
||||
queue_work(rpcrdma_receive_wq, &rep->rr_work);
|
||||
queue_work(buf->rb_completion_wq, &rep->rr_work);
|
||||
return;
|
||||
|
||||
out_badversion:
|
||||
trace_xprtrdma_reply_vers(rep);
|
||||
goto repost;
|
||||
goto out;
|
||||
|
||||
/* The RPC transaction has already been terminated, or the header
|
||||
* is corrupt.
|
||||
*/
|
||||
out_norqst:
|
||||
spin_unlock(&xprt->queue_lock);
|
||||
trace_xprtrdma_reply_rqst(rep);
|
||||
goto repost;
|
||||
goto out;
|
||||
|
||||
out_shortreply:
|
||||
trace_xprtrdma_reply_short(rep);
|
||||
|
||||
/* If no pending RPC transaction was matched, post a replacement
|
||||
* receive buffer before returning.
|
||||
*/
|
||||
repost:
|
||||
rpcrdma_post_recvs(r_xprt, false);
|
||||
out_badstatus:
|
||||
out:
|
||||
rpcrdma_recv_buffer_put(rep);
|
||||
}
|
||||
|
||||
@@ -200,11 +200,10 @@ rpcrdma_bc_send_request(struct svcxprt_rdma *rdma, struct rpc_rqst *rqst)
|
||||
svc_rdma_send_ctxt_put(rdma, ctxt);
|
||||
goto drop_connection;
|
||||
}
|
||||
return rc;
|
||||
return 0;
|
||||
|
||||
drop_connection:
|
||||
dprintk("svcrdma: failed to send bc call\n");
|
||||
xprt_disconnect_done(xprt);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
@@ -225,8 +224,11 @@ xprt_rdma_bc_send_request(struct rpc_rqst *rqst)
|
||||
|
||||
ret = -ENOTCONN;
|
||||
rdma = container_of(sxprt, struct svcxprt_rdma, sc_xprt);
|
||||
if (!test_bit(XPT_DEAD, &sxprt->xpt_flags))
|
||||
if (!test_bit(XPT_DEAD, &sxprt->xpt_flags)) {
|
||||
ret = rpcrdma_bc_send_request(rdma, rqst);
|
||||
if (ret == -ENOTCONN)
|
||||
svc_close_xprt(sxprt);
|
||||
}
|
||||
|
||||
mutex_unlock(&sxprt->xpt_mutex);
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@ xprt_rdma_inject_disconnect(struct rpc_xprt *xprt)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
|
||||
|
||||
trace_xprtrdma_inject_dsc(r_xprt);
|
||||
trace_xprtrdma_op_inject_dsc(r_xprt);
|
||||
rdma_disconnect(r_xprt->rx_ia.ri_id);
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ xprt_rdma_destroy(struct rpc_xprt *xprt)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
|
||||
|
||||
trace_xprtrdma_destroy(r_xprt);
|
||||
trace_xprtrdma_op_destroy(r_xprt);
|
||||
|
||||
cancel_delayed_work_sync(&r_xprt->rx_connect_worker);
|
||||
|
||||
@@ -318,17 +318,12 @@ xprt_setup_rdma(struct xprt_create *args)
|
||||
struct sockaddr *sap;
|
||||
int rc;
|
||||
|
||||
if (args->addrlen > sizeof(xprt->addr)) {
|
||||
dprintk("RPC: %s: address too large\n", __func__);
|
||||
if (args->addrlen > sizeof(xprt->addr))
|
||||
return ERR_PTR(-EBADF);
|
||||
}
|
||||
|
||||
xprt = xprt_alloc(args->net, sizeof(struct rpcrdma_xprt), 0, 0);
|
||||
if (xprt == NULL) {
|
||||
dprintk("RPC: %s: couldn't allocate rpcrdma_xprt\n",
|
||||
__func__);
|
||||
if (!xprt)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
/* 60 second timeout, no retries */
|
||||
xprt->timeout = &xprt_rdma_default_timeout;
|
||||
@@ -399,7 +394,7 @@ xprt_setup_rdma(struct xprt_create *args)
|
||||
INIT_DELAYED_WORK(&new_xprt->rx_connect_worker,
|
||||
xprt_rdma_connect_worker);
|
||||
|
||||
xprt->max_payload = new_xprt->rx_ia.ri_ops->ro_maxpages(new_xprt);
|
||||
xprt->max_payload = frwr_maxpages(new_xprt);
|
||||
if (xprt->max_payload == 0)
|
||||
goto out4;
|
||||
xprt->max_payload <<= PAGE_SHIFT;
|
||||
@@ -423,7 +418,7 @@ out3:
|
||||
out2:
|
||||
rpcrdma_ia_close(&new_xprt->rx_ia);
|
||||
out1:
|
||||
trace_xprtrdma_destroy(new_xprt);
|
||||
trace_xprtrdma_op_destroy(new_xprt);
|
||||
xprt_rdma_free_addresses(xprt);
|
||||
xprt_free(xprt);
|
||||
return ERR_PTR(rc);
|
||||
@@ -433,29 +428,33 @@ out1:
|
||||
* xprt_rdma_close - close a transport connection
|
||||
* @xprt: transport context
|
||||
*
|
||||
* Called during transport shutdown, reconnect, or device removal.
|
||||
* Called during autoclose or device removal.
|
||||
*
|
||||
* Caller holds @xprt's send lock to prevent activity on this
|
||||
* transport while the connection is torn down.
|
||||
*/
|
||||
static void
|
||||
xprt_rdma_close(struct rpc_xprt *xprt)
|
||||
void xprt_rdma_close(struct rpc_xprt *xprt)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
|
||||
struct rpcrdma_ep *ep = &r_xprt->rx_ep;
|
||||
struct rpcrdma_ia *ia = &r_xprt->rx_ia;
|
||||
|
||||
dprintk("RPC: %s: closing xprt %p\n", __func__, xprt);
|
||||
might_sleep();
|
||||
|
||||
trace_xprtrdma_op_close(r_xprt);
|
||||
|
||||
/* Prevent marshaling and sending of new requests */
|
||||
xprt_clear_connected(xprt);
|
||||
|
||||
if (test_and_clear_bit(RPCRDMA_IAF_REMOVING, &ia->ri_flags)) {
|
||||
xprt_clear_connected(xprt);
|
||||
rpcrdma_ia_remove(ia);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ep->rep_connected == -ENODEV)
|
||||
return;
|
||||
if (ep->rep_connected > 0)
|
||||
xprt->reestablish_timeout = 0;
|
||||
xprt_disconnect_done(xprt);
|
||||
rpcrdma_ep_disconnect(ep, ia);
|
||||
|
||||
/* Prepare @xprt for the next connection by reinitializing
|
||||
@@ -463,6 +462,10 @@ xprt_rdma_close(struct rpc_xprt *xprt)
|
||||
*/
|
||||
r_xprt->rx_buf.rb_credits = 1;
|
||||
xprt->cwnd = RPC_CWNDSHIFT;
|
||||
|
||||
out:
|
||||
++xprt->connect_cookie;
|
||||
xprt_disconnect_done(xprt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -525,6 +528,7 @@ xprt_rdma_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
|
||||
|
||||
trace_xprtrdma_op_connect(r_xprt);
|
||||
if (r_xprt->rx_ep.rep_connected != 0) {
|
||||
/* Reconnect */
|
||||
schedule_delayed_work(&r_xprt->rx_connect_worker,
|
||||
@@ -659,11 +663,11 @@ xprt_rdma_allocate(struct rpc_task *task)
|
||||
|
||||
rqst->rq_buffer = req->rl_sendbuf->rg_base;
|
||||
rqst->rq_rbuffer = req->rl_recvbuf->rg_base;
|
||||
trace_xprtrdma_allocate(task, req);
|
||||
trace_xprtrdma_op_allocate(task, req);
|
||||
return 0;
|
||||
|
||||
out_fail:
|
||||
trace_xprtrdma_allocate(task, NULL);
|
||||
trace_xprtrdma_op_allocate(task, NULL);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -682,7 +686,7 @@ xprt_rdma_free(struct rpc_task *task)
|
||||
|
||||
if (test_bit(RPCRDMA_REQ_F_PENDING, &req->rl_flags))
|
||||
rpcrdma_release_rqst(r_xprt, req);
|
||||
trace_xprtrdma_rpc_done(task, req);
|
||||
trace_xprtrdma_op_free(task, req);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -696,8 +700,10 @@ xprt_rdma_free(struct rpc_task *task)
|
||||
* %-ENOTCONN if the caller should reconnect and call again
|
||||
* %-EAGAIN if the caller should call again
|
||||
* %-ENOBUFS if the caller should call again after a delay
|
||||
* %-EIO if a permanent error occurred and the request was not
|
||||
* sent. Do not try to send this message again.
|
||||
* %-EMSGSIZE if encoding ran out of buffer space. The request
|
||||
* was not sent. Do not try to send this message again.
|
||||
* %-EIO if an I/O error occurred. The request was not sent.
|
||||
* Do not try to send this message again.
|
||||
*/
|
||||
static int
|
||||
xprt_rdma_send_request(struct rpc_rqst *rqst)
|
||||
@@ -713,7 +719,7 @@ xprt_rdma_send_request(struct rpc_rqst *rqst)
|
||||
#endif /* CONFIG_SUNRPC_BACKCHANNEL */
|
||||
|
||||
if (!xprt_connected(xprt))
|
||||
goto drop_connection;
|
||||
return -ENOTCONN;
|
||||
|
||||
if (!xprt_request_get_cong(xprt, rqst))
|
||||
return -EBADSLT;
|
||||
@@ -745,8 +751,8 @@ failed_marshal:
|
||||
if (rc != -ENOTCONN)
|
||||
return rc;
|
||||
drop_connection:
|
||||
xprt_disconnect_done(xprt);
|
||||
return -ENOTCONN; /* implies disconnect */
|
||||
xprt_rdma_close(xprt);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
|
||||
@@ -843,58 +849,31 @@ static struct xprt_class xprt_rdma = {
|
||||
|
||||
void xprt_rdma_cleanup(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n");
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
if (sunrpc_table_header) {
|
||||
unregister_sysctl_table(sunrpc_table_header);
|
||||
sunrpc_table_header = NULL;
|
||||
}
|
||||
#endif
|
||||
rc = xprt_unregister_transport(&xprt_rdma);
|
||||
if (rc)
|
||||
dprintk("RPC: %s: xprt_unregister returned %i\n",
|
||||
__func__, rc);
|
||||
|
||||
rpcrdma_destroy_wq();
|
||||
|
||||
rc = xprt_unregister_transport(&xprt_rdma_bc);
|
||||
if (rc)
|
||||
dprintk("RPC: %s: xprt_unregister(bc) returned %i\n",
|
||||
__func__, rc);
|
||||
xprt_unregister_transport(&xprt_rdma);
|
||||
xprt_unregister_transport(&xprt_rdma_bc);
|
||||
}
|
||||
|
||||
int xprt_rdma_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = rpcrdma_alloc_wq();
|
||||
rc = xprt_register_transport(&xprt_rdma);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = xprt_register_transport(&xprt_rdma);
|
||||
if (rc) {
|
||||
rpcrdma_destroy_wq();
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = xprt_register_transport(&xprt_rdma_bc);
|
||||
if (rc) {
|
||||
xprt_unregister_transport(&xprt_rdma);
|
||||
rpcrdma_destroy_wq();
|
||||
return rc;
|
||||
}
|
||||
|
||||
dprintk("RPCRDMA Module Init, register RPC RDMA transport\n");
|
||||
|
||||
dprintk("Defaults:\n");
|
||||
dprintk("\tSlots %d\n"
|
||||
"\tMaxInlineRead %d\n\tMaxInlineWrite %d\n",
|
||||
xprt_rdma_slot_table_entries,
|
||||
xprt_rdma_max_inline_read, xprt_rdma_max_inline_write);
|
||||
dprintk("\tPadding 0\n\tMemreg %d\n", xprt_rdma_memreg_strategy);
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
if (!sunrpc_table_header)
|
||||
sunrpc_table_header = register_sysctl_table(sunrpc_table);
|
||||
|
||||
@@ -78,53 +78,25 @@ static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt);
|
||||
static void rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf);
|
||||
static int rpcrdma_create_rep(struct rpcrdma_xprt *r_xprt, bool temp);
|
||||
static void rpcrdma_dma_unmap_regbuf(struct rpcrdma_regbuf *rb);
|
||||
static void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp);
|
||||
|
||||
struct workqueue_struct *rpcrdma_receive_wq __read_mostly;
|
||||
|
||||
int
|
||||
rpcrdma_alloc_wq(void)
|
||||
{
|
||||
struct workqueue_struct *recv_wq;
|
||||
|
||||
recv_wq = alloc_workqueue("xprtrdma_receive",
|
||||
WQ_MEM_RECLAIM | WQ_HIGHPRI,
|
||||
0);
|
||||
if (!recv_wq)
|
||||
return -ENOMEM;
|
||||
|
||||
rpcrdma_receive_wq = recv_wq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rpcrdma_destroy_wq(void)
|
||||
{
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
if (rpcrdma_receive_wq) {
|
||||
wq = rpcrdma_receive_wq;
|
||||
rpcrdma_receive_wq = NULL;
|
||||
destroy_workqueue(wq);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rpcrdma_disconnect_worker - Force a disconnect
|
||||
* @work: endpoint to be disconnected
|
||||
*
|
||||
* Provider callbacks can possibly run in an IRQ context. This function
|
||||
* is invoked in a worker thread to guarantee that disconnect wake-up
|
||||
* calls are always done in process context.
|
||||
/* Wait for outstanding transport work to finish.
|
||||
*/
|
||||
static void
|
||||
rpcrdma_disconnect_worker(struct work_struct *work)
|
||||
static void rpcrdma_xprt_drain(struct rpcrdma_xprt *r_xprt)
|
||||
{
|
||||
struct rpcrdma_ep *ep = container_of(work, struct rpcrdma_ep,
|
||||
rep_disconnect_worker.work);
|
||||
struct rpcrdma_xprt *r_xprt =
|
||||
container_of(ep, struct rpcrdma_xprt, rx_ep);
|
||||
struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
|
||||
struct rpcrdma_ia *ia = &r_xprt->rx_ia;
|
||||
|
||||
xprt_force_disconnect(&r_xprt->rx_xprt);
|
||||
/* Flush Receives, then wait for deferred Reply work
|
||||
* to complete.
|
||||
*/
|
||||
ib_drain_qp(ia->ri_id->qp);
|
||||
drain_workqueue(buf->rb_completion_wq);
|
||||
|
||||
/* Deferred Reply processing might have scheduled
|
||||
* local invalidations.
|
||||
*/
|
||||
ib_drain_sq(ia->ri_id->qp);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,15 +115,6 @@ rpcrdma_qp_event_handler(struct ib_event *event, void *context)
|
||||
rx_ep);
|
||||
|
||||
trace_xprtrdma_qp_event(r_xprt, event);
|
||||
pr_err("rpcrdma: %s on device %s connected to %s:%s\n",
|
||||
ib_event_msg(event->event), event->device->name,
|
||||
rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt));
|
||||
|
||||
if (ep->rep_connected == 1) {
|
||||
ep->rep_connected = -EIO;
|
||||
schedule_delayed_work(&ep->rep_disconnect_worker, 0);
|
||||
wake_up_all(&ep->rep_connect_wait);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,11 +152,13 @@ rpcrdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc)
|
||||
struct ib_cqe *cqe = wc->wr_cqe;
|
||||
struct rpcrdma_rep *rep = container_of(cqe, struct rpcrdma_rep,
|
||||
rr_cqe);
|
||||
struct rpcrdma_xprt *r_xprt = rep->rr_rxprt;
|
||||
|
||||
/* WARNING: Only wr_id and status are reliable at this point */
|
||||
/* WARNING: Only wr_cqe and status are reliable at this point */
|
||||
trace_xprtrdma_wc_receive(wc);
|
||||
--r_xprt->rx_ep.rep_receive_count;
|
||||
if (wc->status != IB_WC_SUCCESS)
|
||||
goto out_fail;
|
||||
goto out_flushed;
|
||||
|
||||
/* status == SUCCESS means all fields in wc are trustworthy */
|
||||
rpcrdma_set_xdrlen(&rep->rr_hdrbuf, wc->byte_len);
|
||||
@@ -204,17 +169,16 @@ rpcrdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc)
|
||||
rdmab_addr(rep->rr_rdmabuf),
|
||||
wc->byte_len, DMA_FROM_DEVICE);
|
||||
|
||||
out_schedule:
|
||||
rpcrdma_post_recvs(r_xprt, false);
|
||||
rpcrdma_reply_handler(rep);
|
||||
return;
|
||||
|
||||
out_fail:
|
||||
out_flushed:
|
||||
if (wc->status != IB_WC_WR_FLUSH_ERR)
|
||||
pr_err("rpcrdma: Recv: %s (%u/0x%x)\n",
|
||||
ib_wc_status_msg(wc->status),
|
||||
wc->status, wc->vendor_err);
|
||||
rpcrdma_set_xdrlen(&rep->rr_hdrbuf, 0);
|
||||
goto out_schedule;
|
||||
rpcrdma_recv_buffer_put(rep);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -316,7 +280,6 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
|
||||
ep->rep_connected = -EAGAIN;
|
||||
goto disconnected;
|
||||
case RDMA_CM_EVENT_DISCONNECTED:
|
||||
++xprt->connect_cookie;
|
||||
ep->rep_connected = -ECONNABORTED;
|
||||
disconnected:
|
||||
xprt_force_disconnect(xprt);
|
||||
@@ -326,10 +289,9 @@ disconnected:
|
||||
break;
|
||||
}
|
||||
|
||||
dprintk("RPC: %s: %s:%s on %s/%s: %s\n", __func__,
|
||||
dprintk("RPC: %s: %s:%s on %s/frwr: %s\n", __func__,
|
||||
rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt),
|
||||
ia->ri_device->name, ia->ri_ops->ro_displayname,
|
||||
rdma_event_msg(event->event));
|
||||
ia->ri_device->name, rdma_event_msg(event->event));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -347,22 +309,15 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia)
|
||||
|
||||
id = rdma_create_id(xprt->rx_xprt.xprt_net, rpcrdma_cm_event_handler,
|
||||
xprt, RDMA_PS_TCP, IB_QPT_RC);
|
||||
if (IS_ERR(id)) {
|
||||
rc = PTR_ERR(id);
|
||||
dprintk("RPC: %s: rdma_create_id() failed %i\n",
|
||||
__func__, rc);
|
||||
if (IS_ERR(id))
|
||||
return id;
|
||||
}
|
||||
|
||||
ia->ri_async_rc = -ETIMEDOUT;
|
||||
rc = rdma_resolve_addr(id, NULL,
|
||||
(struct sockaddr *)&xprt->rx_xprt.addr,
|
||||
RDMA_RESOLVE_TIMEOUT);
|
||||
if (rc) {
|
||||
dprintk("RPC: %s: rdma_resolve_addr() failed %i\n",
|
||||
__func__, rc);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
rc = wait_for_completion_interruptible_timeout(&ia->ri_done, wtimeout);
|
||||
if (rc < 0) {
|
||||
trace_xprtrdma_conn_tout(xprt);
|
||||
@@ -375,11 +330,8 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia)
|
||||
|
||||
ia->ri_async_rc = -ETIMEDOUT;
|
||||
rc = rdma_resolve_route(id, RDMA_RESOLVE_TIMEOUT);
|
||||
if (rc) {
|
||||
dprintk("RPC: %s: rdma_resolve_route() failed %i\n",
|
||||
__func__, rc);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
rc = wait_for_completion_interruptible_timeout(&ia->ri_done, wtimeout);
|
||||
if (rc < 0) {
|
||||
trace_xprtrdma_conn_tout(xprt);
|
||||
@@ -429,16 +381,8 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt)
|
||||
|
||||
switch (xprt_rdma_memreg_strategy) {
|
||||
case RPCRDMA_FRWR:
|
||||
if (frwr_is_supported(ia)) {
|
||||
ia->ri_ops = &rpcrdma_frwr_memreg_ops;
|
||||
if (frwr_is_supported(ia))
|
||||
break;
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
case RPCRDMA_MTHCAFMR:
|
||||
if (fmr_is_supported(ia)) {
|
||||
ia->ri_ops = &rpcrdma_fmr_memreg_ops;
|
||||
break;
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
pr_err("rpcrdma: Device %s does not support memreg mode %d\n",
|
||||
@@ -481,7 +425,7 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
|
||||
* connection is already gone.
|
||||
*/
|
||||
if (ia->ri_id->qp) {
|
||||
ib_drain_qp(ia->ri_id->qp);
|
||||
rpcrdma_xprt_drain(r_xprt);
|
||||
rdma_destroy_qp(ia->ri_id);
|
||||
ia->ri_id->qp = NULL;
|
||||
}
|
||||
@@ -552,7 +496,7 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
|
||||
}
|
||||
ia->ri_max_send_sges = max_sge;
|
||||
|
||||
rc = ia->ri_ops->ro_open(ia, ep, cdata);
|
||||
rc = frwr_open(ia, ep, cdata);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -579,16 +523,13 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
|
||||
cdata->max_requests >> 2);
|
||||
ep->rep_send_count = ep->rep_send_batch;
|
||||
init_waitqueue_head(&ep->rep_connect_wait);
|
||||
INIT_DELAYED_WORK(&ep->rep_disconnect_worker,
|
||||
rpcrdma_disconnect_worker);
|
||||
ep->rep_receive_count = 0;
|
||||
|
||||
sendcq = ib_alloc_cq(ia->ri_device, NULL,
|
||||
ep->rep_attr.cap.max_send_wr + 1,
|
||||
1, IB_POLL_WORKQUEUE);
|
||||
if (IS_ERR(sendcq)) {
|
||||
rc = PTR_ERR(sendcq);
|
||||
dprintk("RPC: %s: failed to create send CQ: %i\n",
|
||||
__func__, rc);
|
||||
goto out1;
|
||||
}
|
||||
|
||||
@@ -597,8 +538,6 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
|
||||
0, IB_POLL_WORKQUEUE);
|
||||
if (IS_ERR(recvcq)) {
|
||||
rc = PTR_ERR(recvcq);
|
||||
dprintk("RPC: %s: failed to create recv CQ: %i\n",
|
||||
__func__, rc);
|
||||
goto out2;
|
||||
}
|
||||
|
||||
@@ -611,7 +550,7 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
|
||||
/* Prepare RDMA-CM private message */
|
||||
pmsg->cp_magic = rpcrdma_cmp_magic;
|
||||
pmsg->cp_version = RPCRDMA_CMP_VERSION;
|
||||
pmsg->cp_flags |= ia->ri_ops->ro_send_w_inv_ok;
|
||||
pmsg->cp_flags |= RPCRDMA_CMP_F_SND_W_INV_OK;
|
||||
pmsg->cp_send_size = rpcrdma_encode_buffer_size(cdata->inline_wsize);
|
||||
pmsg->cp_recv_size = rpcrdma_encode_buffer_size(cdata->inline_rsize);
|
||||
ep->rep_remote_cma.private_data = pmsg;
|
||||
@@ -653,8 +592,6 @@ out1:
|
||||
void
|
||||
rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
|
||||
{
|
||||
cancel_delayed_work_sync(&ep->rep_disconnect_worker);
|
||||
|
||||
if (ia->ri_id && ia->ri_id->qp) {
|
||||
rpcrdma_ep_disconnect(ep, ia);
|
||||
rdma_destroy_qp(ia->ri_id);
|
||||
@@ -740,11 +677,8 @@ rpcrdma_ep_reconnect(struct rpcrdma_xprt *r_xprt, struct rpcrdma_ep *ep,
|
||||
}
|
||||
|
||||
err = rdma_create_qp(id, ia->ri_pd, &ep->rep_attr);
|
||||
if (err) {
|
||||
dprintk("RPC: %s: rdma_create_qp returned %d\n",
|
||||
__func__, err);
|
||||
if (err)
|
||||
goto out_destroy;
|
||||
}
|
||||
|
||||
/* Atomically replace the transport's ID and QP. */
|
||||
rc = 0;
|
||||
@@ -775,8 +709,6 @@ retry:
|
||||
dprintk("RPC: %s: connecting...\n", __func__);
|
||||
rc = rdma_create_qp(ia->ri_id, ia->ri_pd, &ep->rep_attr);
|
||||
if (rc) {
|
||||
dprintk("RPC: %s: rdma_create_qp failed %i\n",
|
||||
__func__, rc);
|
||||
rc = -ENETUNREACH;
|
||||
goto out_noupdate;
|
||||
}
|
||||
@@ -798,11 +730,8 @@ retry:
|
||||
rpcrdma_post_recvs(r_xprt, true);
|
||||
|
||||
rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);
|
||||
if (rc) {
|
||||
dprintk("RPC: %s: rdma_connect() failed with %i\n",
|
||||
__func__, rc);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
|
||||
wait_event_interruptible(ep->rep_connect_wait, ep->rep_connected != 0);
|
||||
if (ep->rep_connected <= 0) {
|
||||
@@ -822,8 +751,10 @@ out_noupdate:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* rpcrdma_ep_disconnect
|
||||
/**
|
||||
* rpcrdma_ep_disconnect - Disconnect underlying transport
|
||||
* @ep: endpoint to disconnect
|
||||
* @ia: associated interface adapter
|
||||
*
|
||||
* This is separate from destroy to facilitate the ability
|
||||
* to reconnect without recreating the endpoint.
|
||||
@@ -834,19 +765,20 @@ out_noupdate:
|
||||
void
|
||||
rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = container_of(ep, struct rpcrdma_xprt,
|
||||
rx_ep);
|
||||
int rc;
|
||||
|
||||
/* returns without wait if ID is not connected */
|
||||
rc = rdma_disconnect(ia->ri_id);
|
||||
if (!rc)
|
||||
/* returns without wait if not connected */
|
||||
wait_event_interruptible(ep->rep_connect_wait,
|
||||
ep->rep_connected != 1);
|
||||
else
|
||||
ep->rep_connected = rc;
|
||||
trace_xprtrdma_disconnect(container_of(ep, struct rpcrdma_xprt,
|
||||
rx_ep), rc);
|
||||
trace_xprtrdma_disconnect(r_xprt, rc);
|
||||
|
||||
ib_drain_qp(ia->ri_id->qp);
|
||||
rpcrdma_xprt_drain(r_xprt);
|
||||
}
|
||||
|
||||
/* Fixed-size circular FIFO queue. This implementation is wait-free and
|
||||
@@ -1034,7 +966,7 @@ rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
|
||||
if (!mr)
|
||||
break;
|
||||
|
||||
rc = ia->ri_ops->ro_init_mr(ia, mr);
|
||||
rc = frwr_init_mr(ia, mr);
|
||||
if (rc) {
|
||||
kfree(mr);
|
||||
break;
|
||||
@@ -1089,9 +1021,9 @@ rpcrdma_create_req(struct rpcrdma_xprt *r_xprt)
|
||||
req->rl_buffer = buffer;
|
||||
INIT_LIST_HEAD(&req->rl_registered);
|
||||
|
||||
spin_lock(&buffer->rb_reqslock);
|
||||
spin_lock(&buffer->rb_lock);
|
||||
list_add(&req->rl_all, &buffer->rb_allreqs);
|
||||
spin_unlock(&buffer->rb_reqslock);
|
||||
spin_unlock(&buffer->rb_lock);
|
||||
return req;
|
||||
}
|
||||
|
||||
@@ -1134,8 +1066,6 @@ rpcrdma_create_rep(struct rpcrdma_xprt *r_xprt, bool temp)
|
||||
out_free:
|
||||
kfree(rep);
|
||||
out:
|
||||
dprintk("RPC: %s: reply buffer %d alloc failed\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1159,7 +1089,6 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
|
||||
|
||||
INIT_LIST_HEAD(&buf->rb_send_bufs);
|
||||
INIT_LIST_HEAD(&buf->rb_allreqs);
|
||||
spin_lock_init(&buf->rb_reqslock);
|
||||
for (i = 0; i < buf->rb_max_requests; i++) {
|
||||
struct rpcrdma_req *req;
|
||||
|
||||
@@ -1174,13 +1103,19 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
|
||||
}
|
||||
|
||||
buf->rb_credits = 1;
|
||||
buf->rb_posted_receives = 0;
|
||||
INIT_LIST_HEAD(&buf->rb_recv_bufs);
|
||||
|
||||
rc = rpcrdma_sendctxs_create(r_xprt);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
buf->rb_completion_wq = alloc_workqueue("rpcrdma-%s",
|
||||
WQ_MEM_RECLAIM | WQ_HIGHPRI,
|
||||
0,
|
||||
r_xprt->rx_xprt.address_strings[RPC_DISPLAY_ADDR]);
|
||||
if (!buf->rb_completion_wq)
|
||||
goto out;
|
||||
|
||||
return 0;
|
||||
out:
|
||||
rpcrdma_buffer_destroy(buf);
|
||||
@@ -1194,9 +1129,18 @@ rpcrdma_destroy_rep(struct rpcrdma_rep *rep)
|
||||
kfree(rep);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpcrdma_req_destroy - Destroy an rpcrdma_req object
|
||||
* @req: unused object to be destroyed
|
||||
*
|
||||
* This function assumes that the caller prevents concurrent device
|
||||
* unload and transport tear-down.
|
||||
*/
|
||||
void
|
||||
rpcrdma_destroy_req(struct rpcrdma_req *req)
|
||||
rpcrdma_req_destroy(struct rpcrdma_req *req)
|
||||
{
|
||||
list_del(&req->rl_all);
|
||||
|
||||
rpcrdma_free_regbuf(req->rl_recvbuf);
|
||||
rpcrdma_free_regbuf(req->rl_sendbuf);
|
||||
rpcrdma_free_regbuf(req->rl_rdmabuf);
|
||||
@@ -1208,7 +1152,6 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = container_of(buf, struct rpcrdma_xprt,
|
||||
rx_buf);
|
||||
struct rpcrdma_ia *ia = rdmab_to_ia(buf);
|
||||
struct rpcrdma_mr *mr;
|
||||
unsigned int count;
|
||||
|
||||
@@ -1224,7 +1167,7 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
|
||||
if (!list_empty(&mr->mr_list))
|
||||
list_del(&mr->mr_list);
|
||||
|
||||
ia->ri_ops->ro_release_mr(mr);
|
||||
frwr_release_mr(mr);
|
||||
count++;
|
||||
spin_lock(&buf->rb_mrlock);
|
||||
}
|
||||
@@ -1234,11 +1177,24 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
|
||||
dprintk("RPC: %s: released %u MRs\n", __func__, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpcrdma_buffer_destroy - Release all hw resources
|
||||
* @buf: root control block for resources
|
||||
*
|
||||
* ORDERING: relies on a prior ib_drain_qp :
|
||||
* - No more Send or Receive completions can occur
|
||||
* - All MRs, reps, and reqs are returned to their free lists
|
||||
*/
|
||||
void
|
||||
rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
|
||||
{
|
||||
cancel_delayed_work_sync(&buf->rb_refresh_worker);
|
||||
|
||||
if (buf->rb_completion_wq) {
|
||||
destroy_workqueue(buf->rb_completion_wq);
|
||||
buf->rb_completion_wq = NULL;
|
||||
}
|
||||
|
||||
rpcrdma_sendctxs_destroy(buf);
|
||||
|
||||
while (!list_empty(&buf->rb_recv_bufs)) {
|
||||
@@ -1250,19 +1206,14 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
|
||||
rpcrdma_destroy_rep(rep);
|
||||
}
|
||||
|
||||
spin_lock(&buf->rb_reqslock);
|
||||
while (!list_empty(&buf->rb_allreqs)) {
|
||||
while (!list_empty(&buf->rb_send_bufs)) {
|
||||
struct rpcrdma_req *req;
|
||||
|
||||
req = list_first_entry(&buf->rb_allreqs,
|
||||
struct rpcrdma_req, rl_all);
|
||||
list_del(&req->rl_all);
|
||||
|
||||
spin_unlock(&buf->rb_reqslock);
|
||||
rpcrdma_destroy_req(req);
|
||||
spin_lock(&buf->rb_reqslock);
|
||||
req = list_first_entry(&buf->rb_send_bufs,
|
||||
struct rpcrdma_req, rl_list);
|
||||
list_del(&req->rl_list);
|
||||
rpcrdma_req_destroy(req);
|
||||
}
|
||||
spin_unlock(&buf->rb_reqslock);
|
||||
|
||||
rpcrdma_mrs_destroy(buf);
|
||||
}
|
||||
@@ -1329,9 +1280,12 @@ rpcrdma_mr_unmap_and_put(struct rpcrdma_mr *mr)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
|
||||
|
||||
if (mr->mr_dir != DMA_NONE) {
|
||||
trace_xprtrdma_mr_unmap(mr);
|
||||
ib_dma_unmap_sg(r_xprt->rx_ia.ri_device,
|
||||
mr->mr_sg, mr->mr_nents, mr->mr_dir);
|
||||
mr->mr_dir = DMA_NONE;
|
||||
}
|
||||
__rpcrdma_mr_put(&r_xprt->rx_buf, mr);
|
||||
}
|
||||
|
||||
@@ -1410,7 +1364,7 @@ rpcrdma_recv_buffer_put(struct rpcrdma_rep *rep)
|
||||
*
|
||||
* xprtrdma uses a regbuf for posting an outgoing RDMA SEND, or for
|
||||
* receiving the payload of RDMA RECV operations. During Long Calls
|
||||
* or Replies they may be registered externally via ro_map.
|
||||
* or Replies they may be registered externally via frwr_map.
|
||||
*/
|
||||
struct rpcrdma_regbuf *
|
||||
rpcrdma_alloc_regbuf(size_t size, enum dma_data_direction direction,
|
||||
@@ -1446,8 +1400,10 @@ __rpcrdma_dma_map_regbuf(struct rpcrdma_ia *ia, struct rpcrdma_regbuf *rb)
|
||||
(void *)rb->rg_base,
|
||||
rdmab_length(rb),
|
||||
rb->rg_direction);
|
||||
if (ib_dma_mapping_error(device, rdmab_addr(rb)))
|
||||
if (ib_dma_mapping_error(device, rdmab_addr(rb))) {
|
||||
trace_xprtrdma_dma_maperr(rdmab_addr(rb));
|
||||
return false;
|
||||
}
|
||||
|
||||
rb->rg_device = device;
|
||||
rb->rg_iov.lkey = ia->ri_pd->local_dma_lkey;
|
||||
@@ -1479,10 +1435,14 @@ rpcrdma_free_regbuf(struct rpcrdma_regbuf *rb)
|
||||
kfree(rb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepost any receive buffer, then post send.
|
||||
/**
|
||||
* rpcrdma_ep_post - Post WRs to a transport's Send Queue
|
||||
* @ia: transport's device information
|
||||
* @ep: transport's RDMA endpoint information
|
||||
* @req: rpcrdma_req containing the Send WR to post
|
||||
*
|
||||
* Receive buffer is donated to hardware, reclaimed upon recv completion.
|
||||
* Returns 0 if the post was successful, otherwise -ENOTCONN
|
||||
* is returned.
|
||||
*/
|
||||
int
|
||||
rpcrdma_ep_post(struct rpcrdma_ia *ia,
|
||||
@@ -1501,32 +1461,27 @@ rpcrdma_ep_post(struct rpcrdma_ia *ia,
|
||||
--ep->rep_send_count;
|
||||
}
|
||||
|
||||
rc = ia->ri_ops->ro_send(ia, req);
|
||||
rc = frwr_send(ia, req);
|
||||
trace_xprtrdma_post_send(req, rc);
|
||||
if (rc)
|
||||
return -ENOTCONN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* rpcrdma_post_recvs - Maybe post some Receive buffers
|
||||
* @r_xprt: controlling transport
|
||||
* @temp: when true, allocate temp rpcrdma_rep objects
|
||||
*
|
||||
*/
|
||||
void
|
||||
static void
|
||||
rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp)
|
||||
{
|
||||
struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
|
||||
struct rpcrdma_ep *ep = &r_xprt->rx_ep;
|
||||
struct ib_recv_wr *wr, *bad_wr;
|
||||
int needed, count, rc;
|
||||
|
||||
rc = 0;
|
||||
count = 0;
|
||||
needed = buf->rb_credits + (buf->rb_bc_srv_max_requests << 1);
|
||||
if (buf->rb_posted_receives > needed)
|
||||
if (ep->rep_receive_count > needed)
|
||||
goto out;
|
||||
needed -= buf->rb_posted_receives;
|
||||
needed -= ep->rep_receive_count;
|
||||
|
||||
count = 0;
|
||||
wr = NULL;
|
||||
@@ -1574,7 +1529,7 @@ rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp)
|
||||
--count;
|
||||
}
|
||||
}
|
||||
buf->rb_posted_receives += count;
|
||||
ep->rep_receive_count += count;
|
||||
out:
|
||||
trace_xprtrdma_post_recvs(r_xprt, count, rc);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
* Interface Adapter -- one per transport instance
|
||||
*/
|
||||
struct rpcrdma_ia {
|
||||
const struct rpcrdma_memreg_ops *ri_ops;
|
||||
struct ib_device *ri_device;
|
||||
struct rdma_cm_id *ri_id;
|
||||
struct ib_pd *ri_pd;
|
||||
@@ -81,8 +80,6 @@ struct rpcrdma_ia {
|
||||
bool ri_implicit_roundup;
|
||||
enum ib_mr_type ri_mrtype;
|
||||
unsigned long ri_flags;
|
||||
struct ib_qp_attr ri_qp_attr;
|
||||
struct ib_qp_init_attr ri_qp_init_attr;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -101,7 +98,7 @@ struct rpcrdma_ep {
|
||||
wait_queue_head_t rep_connect_wait;
|
||||
struct rpcrdma_connect_private rep_cm_private;
|
||||
struct rdma_conn_param rep_remote_cma;
|
||||
struct delayed_work rep_disconnect_worker;
|
||||
int rep_receive_count;
|
||||
};
|
||||
|
||||
/* Pre-allocate extra Work Requests for handling backward receives
|
||||
@@ -262,20 +259,12 @@ struct rpcrdma_frwr {
|
||||
};
|
||||
};
|
||||
|
||||
struct rpcrdma_fmr {
|
||||
struct ib_fmr *fm_mr;
|
||||
u64 *fm_physaddrs;
|
||||
};
|
||||
|
||||
struct rpcrdma_mr {
|
||||
struct list_head mr_list;
|
||||
struct scatterlist *mr_sg;
|
||||
int mr_nents;
|
||||
enum dma_data_direction mr_dir;
|
||||
union {
|
||||
struct rpcrdma_fmr fmr;
|
||||
struct rpcrdma_frwr frwr;
|
||||
};
|
||||
struct rpcrdma_xprt *mr_xprt;
|
||||
u32 mr_handle;
|
||||
u32 mr_length;
|
||||
@@ -401,20 +390,18 @@ struct rpcrdma_buffer {
|
||||
spinlock_t rb_lock; /* protect buf lists */
|
||||
struct list_head rb_send_bufs;
|
||||
struct list_head rb_recv_bufs;
|
||||
struct list_head rb_allreqs;
|
||||
|
||||
unsigned long rb_flags;
|
||||
u32 rb_max_requests;
|
||||
u32 rb_credits; /* most recent credit grant */
|
||||
int rb_posted_receives;
|
||||
|
||||
u32 rb_bc_srv_max_requests;
|
||||
spinlock_t rb_reqslock; /* protect rb_allreqs */
|
||||
struct list_head rb_allreqs;
|
||||
|
||||
u32 rb_bc_max_requests;
|
||||
|
||||
struct workqueue_struct *rb_completion_wq;
|
||||
struct delayed_work rb_refresh_worker;
|
||||
};
|
||||
#define rdmab_to_ia(b) (&container_of((b), struct rpcrdma_xprt, rx_buf)->rx_ia)
|
||||
|
||||
/* rb_flags */
|
||||
enum {
|
||||
@@ -464,35 +451,6 @@ struct rpcrdma_stats {
|
||||
unsigned long bcall_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* Per-registration mode operations
|
||||
*/
|
||||
struct rpcrdma_xprt;
|
||||
struct rpcrdma_memreg_ops {
|
||||
struct rpcrdma_mr_seg *
|
||||
(*ro_map)(struct rpcrdma_xprt *,
|
||||
struct rpcrdma_mr_seg *, int, bool,
|
||||
struct rpcrdma_mr **);
|
||||
int (*ro_send)(struct rpcrdma_ia *ia,
|
||||
struct rpcrdma_req *req);
|
||||
void (*ro_reminv)(struct rpcrdma_rep *rep,
|
||||
struct list_head *mrs);
|
||||
void (*ro_unmap_sync)(struct rpcrdma_xprt *,
|
||||
struct list_head *);
|
||||
int (*ro_open)(struct rpcrdma_ia *,
|
||||
struct rpcrdma_ep *,
|
||||
struct rpcrdma_create_data_internal *);
|
||||
size_t (*ro_maxpages)(struct rpcrdma_xprt *);
|
||||
int (*ro_init_mr)(struct rpcrdma_ia *,
|
||||
struct rpcrdma_mr *);
|
||||
void (*ro_release_mr)(struct rpcrdma_mr *mr);
|
||||
const char *ro_displayname;
|
||||
const int ro_send_w_inv_ok;
|
||||
};
|
||||
|
||||
extern const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops;
|
||||
extern const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops;
|
||||
|
||||
/*
|
||||
* RPCRDMA transport -- encapsulates the structures above for
|
||||
* integration with RPC.
|
||||
@@ -544,10 +502,6 @@ extern unsigned int xprt_rdma_memreg_strategy;
|
||||
int rpcrdma_ia_open(struct rpcrdma_xprt *xprt);
|
||||
void rpcrdma_ia_remove(struct rpcrdma_ia *ia);
|
||||
void rpcrdma_ia_close(struct rpcrdma_ia *);
|
||||
bool frwr_is_supported(struct rpcrdma_ia *);
|
||||
bool fmr_is_supported(struct rpcrdma_ia *);
|
||||
|
||||
extern struct workqueue_struct *rpcrdma_receive_wq;
|
||||
|
||||
/*
|
||||
* Endpoint calls - xprtrdma/verbs.c
|
||||
@@ -560,13 +514,12 @@ void rpcrdma_ep_disconnect(struct rpcrdma_ep *, struct rpcrdma_ia *);
|
||||
|
||||
int rpcrdma_ep_post(struct rpcrdma_ia *, struct rpcrdma_ep *,
|
||||
struct rpcrdma_req *);
|
||||
void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp);
|
||||
|
||||
/*
|
||||
* Buffer calls - xprtrdma/verbs.c
|
||||
*/
|
||||
struct rpcrdma_req *rpcrdma_create_req(struct rpcrdma_xprt *);
|
||||
void rpcrdma_destroy_req(struct rpcrdma_req *);
|
||||
void rpcrdma_req_destroy(struct rpcrdma_req *req);
|
||||
int rpcrdma_buffer_create(struct rpcrdma_xprt *);
|
||||
void rpcrdma_buffer_destroy(struct rpcrdma_buffer *);
|
||||
struct rpcrdma_sendctx *rpcrdma_sendctx_get_locked(struct rpcrdma_buffer *buf);
|
||||
@@ -604,9 +557,6 @@ rpcrdma_dma_map_regbuf(struct rpcrdma_ia *ia, struct rpcrdma_regbuf *rb)
|
||||
return __rpcrdma_dma_map_regbuf(ia, rb);
|
||||
}
|
||||
|
||||
int rpcrdma_alloc_wq(void);
|
||||
void rpcrdma_destroy_wq(void);
|
||||
|
||||
/*
|
||||
* Wrappers for chunk registration, shared by read/write chunk code.
|
||||
*/
|
||||
@@ -617,6 +567,23 @@ rpcrdma_data_dir(bool writing)
|
||||
return writing ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
||||
}
|
||||
|
||||
/* Memory registration calls xprtrdma/frwr_ops.c
|
||||
*/
|
||||
bool frwr_is_supported(struct rpcrdma_ia *);
|
||||
int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
|
||||
struct rpcrdma_create_data_internal *cdata);
|
||||
int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr);
|
||||
void frwr_release_mr(struct rpcrdma_mr *mr);
|
||||
size_t frwr_maxpages(struct rpcrdma_xprt *r_xprt);
|
||||
struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
|
||||
struct rpcrdma_mr_seg *seg,
|
||||
int nsegs, bool writing, u32 xid,
|
||||
struct rpcrdma_mr **mr);
|
||||
int frwr_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req);
|
||||
void frwr_reminv(struct rpcrdma_rep *rep, struct list_head *mrs);
|
||||
void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt,
|
||||
struct list_head *mrs);
|
||||
|
||||
/*
|
||||
* RPC/RDMA protocol calls - xprtrdma/rpc_rdma.c
|
||||
*/
|
||||
@@ -653,6 +620,7 @@ static inline void rpcrdma_set_xdrlen(struct xdr_buf *xdr, size_t len)
|
||||
extern unsigned int xprt_rdma_max_inline_read;
|
||||
void xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap);
|
||||
void xprt_rdma_free_addresses(struct rpc_xprt *xprt);
|
||||
void xprt_rdma_close(struct rpc_xprt *xprt);
|
||||
void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq);
|
||||
int xprt_rdma_init(void);
|
||||
void xprt_rdma_cleanup(void);
|
||||
|
||||
@@ -68,8 +68,6 @@ static unsigned int xprt_max_tcp_slot_table_entries = RPC_MAX_SLOT_TABLE;
|
||||
static unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT;
|
||||
static unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT;
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
|
||||
#define XS_TCP_LINGER_TO (15U * HZ)
|
||||
static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO;
|
||||
|
||||
@@ -159,8 +157,6 @@ static struct ctl_table sunrpc_table[] = {
|
||||
{ },
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wait duration for a reply from the RPC portmapper.
|
||||
*/
|
||||
@@ -1589,6 +1585,7 @@ static void xs_udp_set_buffer_size(struct rpc_xprt *xprt, size_t sndsize, size_t
|
||||
|
||||
/**
|
||||
* xs_udp_timer - called when a retransmit timeout occurs on a UDP transport
|
||||
* @xprt: controlling transport
|
||||
* @task: task that timed out
|
||||
*
|
||||
* Adjust the congestion window after a retransmit timeout has occurred.
|
||||
@@ -2246,6 +2243,7 @@ out:
|
||||
|
||||
/**
|
||||
* xs_tcp_setup_socket - create a TCP socket and connect to a remote endpoint
|
||||
* @work: queued work item
|
||||
*
|
||||
* Invoked by a work queue tasklet.
|
||||
*/
|
||||
@@ -3095,10 +3093,8 @@ static struct xprt_class xs_bc_tcp_transport = {
|
||||
*/
|
||||
int init_socket_xprt(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
if (!sunrpc_table_header)
|
||||
sunrpc_table_header = register_sysctl_table(sunrpc_table);
|
||||
#endif
|
||||
|
||||
xprt_register_transport(&xs_local_transport);
|
||||
xprt_register_transport(&xs_udp_transport);
|
||||
@@ -3114,12 +3110,10 @@ int init_socket_xprt(void)
|
||||
*/
|
||||
void cleanup_socket_xprt(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
if (sunrpc_table_header) {
|
||||
unregister_sysctl_table(sunrpc_table_header);
|
||||
sunrpc_table_header = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
xprt_unregister_transport(&xs_local_transport);
|
||||
xprt_unregister_transport(&xs_udp_transport);
|
||||
|
||||
Reference in New Issue
Block a user