]> git.dujemihanovic.xyz Git - linux.git/commitdiff
sunrpc: Add xprt after nfs4_test_session_trunk()
authorSantosh kumar pradhan <santoshkumar.pradhan@wdc.com>
Wed, 19 Dec 2018 06:59:57 +0000 (12:29 +0530)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Wed, 2 Jan 2019 17:05:19 +0000 (12:05 -0500)
Multipathing: In case of NFSv3, rpc_clnt_test_and_add_xprt() adds
the xprt to xprt switch (i.e. xps) if rpc_call_null_helper() returns
success. But in case of NFSv4.1, it needs to do EXCHANGEID to verify
the path along with check for session trunking.

Add the xprt in nfs4_test_session_trunk() only when
nfs4_detect_session_trunking() returns success. Also release refcount
hold by rpc_clnt_setup_test_and_add_xprt().

Signed-off-by: Santosh kumar pradhan <santoshkumar.pradhan@wdc.com>
Tested-by: Suresh Jayaraman <suresh.jayaraman@wdc.com>
Reported-by: Aditya Agnihotri <aditya.agnihotri@wdc.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/internal.h
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c
include/linux/sunrpc/clnt.h
net/sunrpc/clnt.c

index 78d83b4bc39812ccf756716265fe7acf977a3b35..7f80f036ebd9948f62fd46bea5afe3ee319920d3 100644 (file)
@@ -568,9 +568,9 @@ extern int nfs40_walk_client_list(struct nfs_client *clp,
 extern int nfs41_walk_client_list(struct nfs_client *clp,
                                struct nfs_client **result,
                                const struct cred *cred);
-extern int nfs4_test_session_trunk(struct rpc_clnt *,
-                               struct rpc_xprt *,
-                               void *);
+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)
 {
index 993378a8f14f31d0f41bf132c2717874c106ab3b..06ac3d9ac7c6ad467be0e7f0be44ff615ee24a9d 100644 (file)
@@ -65,7 +65,8 @@ struct nfs4_minor_version_ops {
                        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;
index 7d1f080e7de11997922f42027ceafa9ec9cbce10..72961b5f69933d2df807f6842bc6e88101e05495 100644 (file)
@@ -8082,7 +8082,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, const struct 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;
@@ -8099,15 +8099,17 @@ 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);
 
index fc6dfbf77a9d24ceceef01fdf1586b466e23c2d4..1c441714d569bcb46ecae21cf96c882a7a235502 100644 (file)
@@ -128,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;
 };
index cad26f816d20b530700c3fbd53fdc4e9925a06e7..71d9599b5816591bd12751703d8487a8dda688a4 100644 (file)
@@ -2661,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: