diff options
author | Andy Adamson <andros@netapp.com> | 2016-09-09 09:22:21 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2016-09-19 13:08:36 -0400 |
commit | ba84db96aa07995b853db403a3eba2249f0fa4e3 (patch) | |
tree | b513ff1fc7ba28e8b7d4fbd8289b8d3b02bc0147 /fs/nfs | |
parent | e7b7cbf662deb857539cd4b594451ea89c4d7ee6 (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.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4client.c | 90 |
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); |
279 | extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, | 279 | extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, |
280 | bool sync); | 280 | bool sync); |
281 | extern int nfs4_detect_session_trunking(struct nfs_client *clp, | ||
282 | struct nfs41_exchange_id_res *res, struct rpc_xprt *xprt); | ||
281 | 283 | ||
282 | static inline bool | 284 | static inline bool |
283 | is_ds_only_client(struct nfs_client *clp) | 285 | is_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 | */ | ||
601 | static bool | ||
602 | nfs4_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 | |||
612 | out_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 | */ | ||
620 | static bool | ||
621 | nfs4_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 | |||
633 | out_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 | */ | ||
654 | int 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; | ||
681 | out_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 | * |