aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2016-09-09 09:22:21 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2016-09-19 13:08:36 -0400
commitba84db96aa07995b853db403a3eba2249f0fa4e3 (patch)
treeb513ff1fc7ba28e8b7d4fbd8289b8d3b02bc0147 /fs/nfs
parente7b7cbf662deb857539cd4b594451ea89c4d7ee6 (diff)
NFS detect session trunking
Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4client.c90
2 files changed, 92 insertions, 0 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index f230aa62ca59..cf744aa0fa74 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -278,6 +278,8 @@ extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
278 struct nfs_fsinfo *fsinfo); 278 struct nfs_fsinfo *fsinfo);
279extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, 279extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data,
280 bool sync); 280 bool sync);
281extern int nfs4_detect_session_trunking(struct nfs_client *clp,
282 struct nfs41_exchange_id_res *res, struct rpc_xprt *xprt);
281 283
282static inline bool 284static inline bool
283is_ds_only_client(struct nfs_client *clp) 285is_ds_only_client(struct nfs_client *clp)
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 0077b2eadfae..6914d4b176ae 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -595,6 +595,96 @@ out_major_mismatch:
595 return false; 595 return false;
596} 596}
597 597
598/*
599 * Returns true if server minor ids match
600 */
601static bool
602nfs4_check_serverowner_minor_id(struct nfs41_server_owner *o1,
603 struct nfs41_server_owner *o2)
604{
605 /* Check eir_server_owner so_minor_id */
606 if (o1->minor_id != o2->minor_id)
607 goto out_minor_mismatch;
608
609 dprintk("NFS: --> %s server owner minor IDs match\n", __func__);
610 return true;
611
612out_minor_mismatch:
613 dprintk("NFS: --> %s server owner minor IDs do not match\n", __func__);
614 return false;
615}
616
617/*
618 * Returns true if the server scopes match
619 */
620static bool
621nfs4_check_server_scope(struct nfs41_server_scope *s1,
622 struct nfs41_server_scope *s2)
623{
624 if (s1->server_scope_sz != s2->server_scope_sz)
625 goto out_scope_mismatch;
626 if (memcmp(s1->server_scope, s2->server_scope,
627 s1->server_scope_sz) != 0)
628 goto out_scope_mismatch;
629
630 dprintk("NFS: --> %s server scopes match\n", __func__);
631 return true;
632
633out_scope_mismatch:
634 dprintk("NFS: --> %s server scopes do not match\n",
635 __func__);
636 return false;
637}
638
639/**
640 * nfs4_detect_session_trunking - Checks for session trunking called
641 * after a successful EXCHANGE_ID testing a multi-addr connection to be
642 * potentially added as a session trunk
643 *
644 * @clp: original mount nfs_client
645 * @res: result structure from an exchange_id using the original mount
646 * nfs_client with a new multi_addr transport
647 *
648 * Returns zero on success, otherwise -EINVAL
649 *
650 * Note: since the exchange_id for the new multi_addr transport uses the
651 * same nfs_client from the original mount, the cl_owner_id is reused,
652 * so eir_clientowner is the same.
653 */
654int nfs4_detect_session_trunking(struct nfs_client *clp,
655 struct nfs41_exchange_id_res *res,
656 struct rpc_xprt *xprt)
657{
658 /* Check eir_clientid */
659 if (!nfs4_match_clientids(clp->cl_clientid, res->clientid))
660 goto out_err;
661
662 /* Check eir_server_owner so_major_id */
663 if (!nfs4_check_serverowner_major_id(clp->cl_serverowner,
664 res->server_owner))
665 goto out_err;
666
667 /* Check eir_server_owner so_minor_id */
668 if (!nfs4_check_serverowner_minor_id(clp->cl_serverowner,
669 res->server_owner))
670 goto out_err;
671
672 /* Check eir_server_scope */
673 if (!nfs4_check_server_scope(clp->cl_serverscope, res->server_scope))
674 goto out_err;
675
676 pr_info("NFS: %s: Session trunking succeeded for %s\n",
677 clp->cl_hostname,
678 xprt->address_strings[RPC_DISPLAY_ADDR]);
679
680 return 0;
681out_err:
682 pr_info("NFS: %s: Session trunking failed for %s\n", clp->cl_hostname,
683 xprt->address_strings[RPC_DISPLAY_ADDR]);
684
685 return -EINVAL;
686}
687
598/** 688/**
599 * nfs41_walk_client_list - Find nfs_client that matches a client/server owner 689 * nfs41_walk_client_list - Find nfs_client that matches a client/server owner
600 * 690 *