SUNRPC: Convert rpc_client refcount to use refcount_t
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 26 Jul 2021 12:01:27 +0000 (08:01 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Mon, 9 Aug 2021 20:57:04 +0000 (16:57 -0400)
There are now tools in the refcount library that allow us to convert the
client shutdown code.

Reported-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
include/linux/sunrpc/clnt.h
net/sunrpc/auth_gss/gss_rpc_upcall.c
net/sunrpc/clnt.c
net/sunrpc/debugfs.c
net/sunrpc/rpc_pipe.c

index 8b5d5c9..b2edd5f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/in6.h>
+#include <linux/refcount.h>
 
 #include <linux/sunrpc/msg_prot.h>
 #include <linux/sunrpc/sched.h>
@@ -35,7 +36,7 @@ struct rpc_sysfs_client;
  * The high-level client handle
  */
 struct rpc_clnt {
-       atomic_t                cl_count;       /* Number of references */
+       refcount_t              cl_count;       /* Number of references */
        unsigned int            cl_clid;        /* client id */
        struct list_head        cl_clients;     /* Global list of clients */
        struct list_head        cl_tasks;       /* List of tasks */
index d1c003a..61c276b 100644 (file)
@@ -160,7 +160,7 @@ static struct rpc_clnt *get_gssp_clnt(struct sunrpc_net *sn)
        mutex_lock(&sn->gssp_lock);
        clnt = sn->gssp_clnt;
        if (clnt)
-               atomic_inc(&clnt->cl_count);
+               refcount_inc(&clnt->cl_count);
        mutex_unlock(&sn->gssp_lock);
        return clnt;
 }
index d34737a..a5b7f6e 100644 (file)
@@ -167,7 +167,7 @@ static int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event)
        case RPC_PIPEFS_MOUNT:
                if (clnt->cl_pipedir_objects.pdh_dentry != NULL)
                        return 1;
-               if (atomic_read(&clnt->cl_count) == 0)
+               if (refcount_read(&clnt->cl_count) == 0)
                        return 1;
                break;
        case RPC_PIPEFS_UMOUNT:
@@ -419,7 +419,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
        clnt->cl_rtt = &clnt->cl_rtt_default;
        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)
                nodename = utsname()->nodename;
@@ -431,7 +431,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
        if (err)
                goto out_no_path;
        if (parent)
-               atomic_inc(&parent->cl_count);
+               refcount_inc(&parent->cl_count);
 
        trace_rpc_clnt_new(clnt, xprt, program->name, args->servername);
        return clnt;
@@ -918,18 +918,16 @@ rpc_free_client(struct rpc_clnt *clnt)
 static struct rpc_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
         *       release remaining GSS contexts. This mechanism ensures
         *       that it can do so safely.
         */
-       atomic_inc(&clnt->cl_count);
-       rpcauth_release(clnt->cl_auth);
-       clnt->cl_auth = NULL;
-       if (atomic_dec_and_test(&clnt->cl_count))
+       if (clnt->cl_auth != NULL) {
+               rpcauth_release(clnt->cl_auth);
+               clnt->cl_auth = NULL;
+       }
+       if (refcount_dec_and_test(&clnt->cl_count))
                return rpc_free_client(clnt);
        return NULL;
 }
@@ -943,7 +941,7 @@ rpc_release_client(struct rpc_clnt *clnt)
        do {
                if (list_empty(&clnt->cl_tasks))
                        wake_up(&destroy_wait);
-               if (!atomic_dec_and_test(&clnt->cl_count))
+               if (refcount_dec_not_one(&clnt->cl_count))
                        break;
                clnt = rpc_free_auth(clnt);
        } while (clnt != NULL);
@@ -1082,7 +1080,7 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
        if (clnt != NULL) {
                rpc_task_set_transport(task, clnt);
                task->tk_client = clnt;
-               atomic_inc(&clnt->cl_count);
+               refcount_inc(&clnt->cl_count);
                if (clnt->cl_softrtry)
                        task->tk_flags |= RPC_TASK_SOFT;
                if (clnt->cl_softerr)
index 56029e3..79995eb 100644 (file)
@@ -90,7 +90,7 @@ static int tasks_open(struct inode *inode, struct file *filp)
                struct seq_file *seq = filp->private_data;
                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);
                        ret = -EINVAL;
                }
index 09c000d..ee5336d 100644 (file)
@@ -423,7 +423,7 @@ rpc_info_open(struct inode *inode, struct file *file)
                spin_lock(&file->f_path.dentry->d_lock);
                if (!d_unhashed(file->f_path.dentry))
                        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);
                        m->private = clnt;
                } else {