Commit 71d3d0eb authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker

SUNRPC: Convert rpc_client refcount to use refcount_t

There are now tools in the refcount library that allow us to convert the
client shutdown code.
Reported-by: default avatarXiyu Yang <xiyuyang19@fudan.edu.cn>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 8d863b1f
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/in6.h> #include <linux/in6.h>
#include <linux/refcount.h>
#include <linux/sunrpc/msg_prot.h> #include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/sched.h> #include <linux/sunrpc/sched.h>
...@@ -35,7 +36,7 @@ struct rpc_sysfs_client; ...@@ -35,7 +36,7 @@ struct rpc_sysfs_client;
* The high-level client handle * The high-level client handle
*/ */
struct rpc_clnt { struct rpc_clnt {
atomic_t cl_count; /* Number of references */ refcount_t cl_count; /* Number of references */
unsigned int cl_clid; /* client id */ unsigned int cl_clid; /* client id */
struct list_head cl_clients; /* Global list of clients */ struct list_head cl_clients; /* Global list of clients */
struct list_head cl_tasks; /* List of tasks */ struct list_head cl_tasks; /* List of tasks */
......
...@@ -160,7 +160,7 @@ static struct rpc_clnt *get_gssp_clnt(struct sunrpc_net *sn) ...@@ -160,7 +160,7 @@ static struct rpc_clnt *get_gssp_clnt(struct sunrpc_net *sn)
mutex_lock(&sn->gssp_lock); mutex_lock(&sn->gssp_lock);
clnt = sn->gssp_clnt; clnt = sn->gssp_clnt;
if (clnt) if (clnt)
atomic_inc(&clnt->cl_count); refcount_inc(&clnt->cl_count);
mutex_unlock(&sn->gssp_lock); mutex_unlock(&sn->gssp_lock);
return clnt; return clnt;
} }
......
...@@ -167,7 +167,7 @@ static int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event) ...@@ -167,7 +167,7 @@ static int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event)
case RPC_PIPEFS_MOUNT: case RPC_PIPEFS_MOUNT:
if (clnt->cl_pipedir_objects.pdh_dentry != NULL) if (clnt->cl_pipedir_objects.pdh_dentry != NULL)
return 1; return 1;
if (atomic_read(&clnt->cl_count) == 0) if (refcount_read(&clnt->cl_count) == 0)
return 1; return 1;
break; break;
case RPC_PIPEFS_UMOUNT: case RPC_PIPEFS_UMOUNT:
...@@ -419,7 +419,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, ...@@ -419,7 +419,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
clnt->cl_rtt = &clnt->cl_rtt_default; clnt->cl_rtt = &clnt->cl_rtt_default;
rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
atomic_set(&clnt->cl_count, 1); refcount_set(&clnt->cl_count, 1);
if (nodename == NULL) if (nodename == NULL)
nodename = utsname()->nodename; nodename = utsname()->nodename;
...@@ -431,7 +431,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, ...@@ -431,7 +431,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
if (err) if (err)
goto out_no_path; goto out_no_path;
if (parent) if (parent)
atomic_inc(&parent->cl_count); refcount_inc(&parent->cl_count);
trace_rpc_clnt_new(clnt, xprt, program->name, args->servername); trace_rpc_clnt_new(clnt, xprt, program->name, args->servername);
return clnt; return clnt;
...@@ -918,18 +918,16 @@ rpc_free_client(struct rpc_clnt *clnt) ...@@ -918,18 +918,16 @@ rpc_free_client(struct rpc_clnt *clnt)
static struct rpc_clnt * static struct rpc_clnt *
rpc_free_auth(struct rpc_clnt *clnt) rpc_free_auth(struct rpc_clnt *clnt)
{ {
if (clnt->cl_auth == NULL)
return rpc_free_client(clnt);
/* /*
* Note: RPCSEC_GSS may need to send NULL RPC calls in order to * Note: RPCSEC_GSS may need to send NULL RPC calls in order to
* release remaining GSS contexts. This mechanism ensures * release remaining GSS contexts. This mechanism ensures
* that it can do so safely. * that it can do so safely.
*/ */
atomic_inc(&clnt->cl_count); if (clnt->cl_auth != NULL) {
rpcauth_release(clnt->cl_auth); rpcauth_release(clnt->cl_auth);
clnt->cl_auth = NULL; clnt->cl_auth = NULL;
if (atomic_dec_and_test(&clnt->cl_count)) }
if (refcount_dec_and_test(&clnt->cl_count))
return rpc_free_client(clnt); return rpc_free_client(clnt);
return NULL; return NULL;
} }
...@@ -943,7 +941,7 @@ rpc_release_client(struct rpc_clnt *clnt) ...@@ -943,7 +941,7 @@ rpc_release_client(struct rpc_clnt *clnt)
do { do {
if (list_empty(&clnt->cl_tasks)) if (list_empty(&clnt->cl_tasks))
wake_up(&destroy_wait); wake_up(&destroy_wait);
if (!atomic_dec_and_test(&clnt->cl_count)) if (refcount_dec_not_one(&clnt->cl_count))
break; break;
clnt = rpc_free_auth(clnt); clnt = rpc_free_auth(clnt);
} while (clnt != NULL); } while (clnt != NULL);
...@@ -1082,7 +1080,7 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) ...@@ -1082,7 +1080,7 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
if (clnt != NULL) { if (clnt != NULL) {
rpc_task_set_transport(task, clnt); rpc_task_set_transport(task, clnt);
task->tk_client = clnt; task->tk_client = clnt;
atomic_inc(&clnt->cl_count); refcount_inc(&clnt->cl_count);
if (clnt->cl_softrtry) if (clnt->cl_softrtry)
task->tk_flags |= RPC_TASK_SOFT; task->tk_flags |= RPC_TASK_SOFT;
if (clnt->cl_softerr) if (clnt->cl_softerr)
......
...@@ -90,7 +90,7 @@ static int tasks_open(struct inode *inode, struct file *filp) ...@@ -90,7 +90,7 @@ static int tasks_open(struct inode *inode, struct file *filp)
struct seq_file *seq = filp->private_data; struct seq_file *seq = filp->private_data;
struct rpc_clnt *clnt = seq->private = inode->i_private; struct rpc_clnt *clnt = seq->private = inode->i_private;
if (!atomic_inc_not_zero(&clnt->cl_count)) { if (!refcount_inc_not_zero(&clnt->cl_count)) {
seq_release(inode, filp); seq_release(inode, filp);
ret = -EINVAL; ret = -EINVAL;
} }
......
...@@ -423,7 +423,7 @@ rpc_info_open(struct inode *inode, struct file *file) ...@@ -423,7 +423,7 @@ rpc_info_open(struct inode *inode, struct file *file)
spin_lock(&file->f_path.dentry->d_lock); spin_lock(&file->f_path.dentry->d_lock);
if (!d_unhashed(file->f_path.dentry)) if (!d_unhashed(file->f_path.dentry))
clnt = RPC_I(inode)->private; clnt = RPC_I(inode)->private;
if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) { if (clnt != NULL && refcount_inc_not_zero(&clnt->cl_count)) {
spin_unlock(&file->f_path.dentry->d_lock); spin_unlock(&file->f_path.dentry->d_lock);
m->private = clnt; m->private = clnt;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment