diff options
Diffstat (limited to 'fs/nfs/nfs4client.c')
-rw-r--r-- | fs/nfs/nfs4client.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 03311259b0c4..953daa44a282 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -228,6 +228,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp) | |||
228 | kfree(clp->cl_serverowner); | 228 | kfree(clp->cl_serverowner); |
229 | kfree(clp->cl_serverscope); | 229 | kfree(clp->cl_serverscope); |
230 | kfree(clp->cl_implid); | 230 | kfree(clp->cl_implid); |
231 | kfree(clp->cl_owner_id); | ||
231 | } | 232 | } |
232 | 233 | ||
233 | void nfs4_free_client(struct nfs_client *clp) | 234 | void nfs4_free_client(struct nfs_client *clp) |
@@ -452,6 +453,14 @@ static void nfs4_swap_callback_idents(struct nfs_client *keep, | |||
452 | spin_unlock(&nn->nfs_client_lock); | 453 | spin_unlock(&nn->nfs_client_lock); |
453 | } | 454 | } |
454 | 455 | ||
456 | static bool nfs4_match_client_owner_id(const struct nfs_client *clp1, | ||
457 | const struct nfs_client *clp2) | ||
458 | { | ||
459 | if (clp1->cl_owner_id == NULL || clp2->cl_owner_id == NULL) | ||
460 | return true; | ||
461 | return strcmp(clp1->cl_owner_id, clp2->cl_owner_id) == 0; | ||
462 | } | ||
463 | |||
455 | /** | 464 | /** |
456 | * nfs40_walk_client_list - Find server that recognizes a client ID | 465 | * nfs40_walk_client_list - Find server that recognizes a client ID |
457 | * | 466 | * |
@@ -483,9 +492,6 @@ int nfs40_walk_client_list(struct nfs_client *new, | |||
483 | if (pos->rpc_ops != new->rpc_ops) | 492 | if (pos->rpc_ops != new->rpc_ops) |
484 | continue; | 493 | continue; |
485 | 494 | ||
486 | if (pos->cl_proto != new->cl_proto) | ||
487 | continue; | ||
488 | |||
489 | if (pos->cl_minorversion != new->cl_minorversion) | 495 | if (pos->cl_minorversion != new->cl_minorversion) |
490 | continue; | 496 | continue; |
491 | 497 | ||
@@ -510,6 +516,9 @@ int nfs40_walk_client_list(struct nfs_client *new, | |||
510 | if (pos->cl_clientid != new->cl_clientid) | 516 | if (pos->cl_clientid != new->cl_clientid) |
511 | continue; | 517 | continue; |
512 | 518 | ||
519 | if (!nfs4_match_client_owner_id(pos, new)) | ||
520 | continue; | ||
521 | |||
513 | atomic_inc(&pos->cl_count); | 522 | atomic_inc(&pos->cl_count); |
514 | spin_unlock(&nn->nfs_client_lock); | 523 | spin_unlock(&nn->nfs_client_lock); |
515 | 524 | ||
@@ -566,20 +575,14 @@ static bool nfs4_match_clientids(struct nfs_client *a, struct nfs_client *b) | |||
566 | } | 575 | } |
567 | 576 | ||
568 | /* | 577 | /* |
569 | * Returns true if the server owners match | 578 | * Returns true if the server major ids match |
570 | */ | 579 | */ |
571 | static bool | 580 | static bool |
572 | nfs4_match_serverowners(struct nfs_client *a, struct nfs_client *b) | 581 | nfs4_check_clientid_trunking(struct nfs_client *a, struct nfs_client *b) |
573 | { | 582 | { |
574 | struct nfs41_server_owner *o1 = a->cl_serverowner; | 583 | struct nfs41_server_owner *o1 = a->cl_serverowner; |
575 | struct nfs41_server_owner *o2 = b->cl_serverowner; | 584 | struct nfs41_server_owner *o2 = b->cl_serverowner; |
576 | 585 | ||
577 | if (o1->minor_id != o2->minor_id) { | ||
578 | dprintk("NFS: --> %s server owner minor IDs do not match\n", | ||
579 | __func__); | ||
580 | return false; | ||
581 | } | ||
582 | |||
583 | if (o1->major_id_sz != o2->major_id_sz) | 586 | if (o1->major_id_sz != o2->major_id_sz) |
584 | goto out_major_mismatch; | 587 | goto out_major_mismatch; |
585 | if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0) | 588 | if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0) |
@@ -621,9 +624,6 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
621 | if (pos->rpc_ops != new->rpc_ops) | 624 | if (pos->rpc_ops != new->rpc_ops) |
622 | continue; | 625 | continue; |
623 | 626 | ||
624 | if (pos->cl_proto != new->cl_proto) | ||
625 | continue; | ||
626 | |||
627 | if (pos->cl_minorversion != new->cl_minorversion) | 627 | if (pos->cl_minorversion != new->cl_minorversion) |
628 | continue; | 628 | continue; |
629 | 629 | ||
@@ -654,7 +654,19 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
654 | if (!nfs4_match_clientids(pos, new)) | 654 | if (!nfs4_match_clientids(pos, new)) |
655 | continue; | 655 | continue; |
656 | 656 | ||
657 | if (!nfs4_match_serverowners(pos, new)) | 657 | /* |
658 | * Note that session trunking is just a special subcase of | ||
659 | * client id trunking. In either case, we want to fall back | ||
660 | * to using the existing nfs_client. | ||
661 | */ | ||
662 | if (!nfs4_check_clientid_trunking(pos, new)) | ||
663 | continue; | ||
664 | |||
665 | /* Unlike NFSv4.0, we know that NFSv4.1 always uses the | ||
666 | * uniform string, however someone might switch the | ||
667 | * uniquifier string on us. | ||
668 | */ | ||
669 | if (!nfs4_match_client_owner_id(pos, new)) | ||
658 | continue; | 670 | continue; |
659 | 671 | ||
660 | atomic_inc(&pos->cl_count); | 672 | atomic_inc(&pos->cl_count); |