@@ -469,6 +469,50 @@ static bool nfs4_same_verifier(nfs4_verifier *v1, nfs4_verifier *v2)
469
469
return memcmp (v1 -> data , v2 -> data , sizeof (v1 -> data )) == 0 ;
470
470
}
471
471
472
+ static int nfs4_match_client (struct nfs_client * pos , struct nfs_client * new ,
473
+ struct nfs_client * * prev , struct nfs_net * nn )
474
+ {
475
+ int status ;
476
+
477
+ if (pos -> rpc_ops != new -> rpc_ops )
478
+ return 1 ;
479
+
480
+ if (pos -> cl_minorversion != new -> cl_minorversion )
481
+ return 1 ;
482
+
483
+ /* If "pos" isn't marked ready, we can't trust the
484
+ * remaining fields in "pos", especially the client
485
+ * ID and serverowner fields. Wait for CREATE_SESSION
486
+ * to finish. */
487
+ if (pos -> cl_cons_state > NFS_CS_READY ) {
488
+ atomic_inc (& pos -> cl_count );
489
+ spin_unlock (& nn -> nfs_client_lock );
490
+
491
+ nfs_put_client (* prev );
492
+ * prev = pos ;
493
+
494
+ status = nfs_wait_client_init_complete (pos );
495
+ spin_lock (& nn -> nfs_client_lock );
496
+
497
+ if (status < 0 )
498
+ return status ;
499
+ }
500
+
501
+ if (pos -> cl_cons_state != NFS_CS_READY )
502
+ return 1 ;
503
+
504
+ if (pos -> cl_clientid != new -> cl_clientid )
505
+ return 1 ;
506
+
507
+ /* NFSv4.1 always uses the uniform string, however someone
508
+ * might switch the uniquifier string on us.
509
+ */
510
+ if (!nfs4_match_client_owner_id (pos , new ))
511
+ return 1 ;
512
+
513
+ return 0 ;
514
+ }
515
+
472
516
/**
473
517
* nfs40_walk_client_list - Find server that recognizes a client ID
474
518
*
@@ -497,34 +541,10 @@ int nfs40_walk_client_list(struct nfs_client *new,
497
541
spin_lock (& nn -> nfs_client_lock );
498
542
list_for_each_entry (pos , & nn -> nfs_client_list , cl_share_link ) {
499
543
500
- if (pos -> rpc_ops != new -> rpc_ops )
501
- continue ;
502
-
503
- if (pos -> cl_minorversion != new -> cl_minorversion )
504
- continue ;
505
-
506
- /* If "pos" isn't marked ready, we can't trust the
507
- * remaining fields in "pos" */
508
- if (pos -> cl_cons_state > NFS_CS_READY ) {
509
- atomic_inc (& pos -> cl_count );
510
- spin_unlock (& nn -> nfs_client_lock );
511
-
512
- nfs_put_client (prev );
513
- prev = pos ;
514
-
515
- status = nfs_wait_client_init_complete (pos );
516
- if (status < 0 )
517
- goto out ;
518
- status = - NFS4ERR_STALE_CLIENTID ;
519
- spin_lock (& nn -> nfs_client_lock );
520
- }
521
- if (pos -> cl_cons_state != NFS_CS_READY )
522
- continue ;
523
-
524
- if (pos -> cl_clientid != new -> cl_clientid )
525
- continue ;
526
-
527
- if (!nfs4_match_client_owner_id (pos , new ))
544
+ status = nfs4_match_client (pos , new , & prev , nn );
545
+ if (status < 0 )
546
+ goto out_unlock ;
547
+ if (status != 0 )
528
548
continue ;
529
549
/*
530
550
* We just sent a new SETCLIENTID, which should have
@@ -567,11 +587,13 @@ int nfs40_walk_client_list(struct nfs_client *new,
567
587
*/
568
588
nfs4_schedule_path_down_recovery (pos );
569
589
default :
590
+ spin_lock (& nn -> nfs_client_lock );
570
591
goto out ;
571
592
}
572
593
573
594
spin_lock (& nn -> nfs_client_lock );
574
595
}
596
+ out_unlock :
575
597
spin_unlock (& nn -> nfs_client_lock );
576
598
577
599
/* No match found. The server lost our clientid */
@@ -704,33 +726,10 @@ int nfs41_walk_client_list(struct nfs_client *new,
704
726
if (pos == new )
705
727
goto found ;
706
728
707
- if (pos -> rpc_ops != new -> rpc_ops )
708
- continue ;
709
-
710
- if (pos -> cl_minorversion != new -> cl_minorversion )
711
- continue ;
712
-
713
- /* If "pos" isn't marked ready, we can't trust the
714
- * remaining fields in "pos", especially the client
715
- * ID and serverowner fields. Wait for CREATE_SESSION
716
- * to finish. */
717
- if (pos -> cl_cons_state > NFS_CS_READY ) {
718
- atomic_inc (& pos -> cl_count );
719
- spin_unlock (& nn -> nfs_client_lock );
720
-
721
- nfs_put_client (prev );
722
- prev = pos ;
723
-
724
- status = nfs_wait_client_init_complete (pos );
725
- spin_lock (& nn -> nfs_client_lock );
726
- if (status < 0 )
727
- break ;
728
- status = - NFS4ERR_STALE_CLIENTID ;
729
- }
730
- if (pos -> cl_cons_state != NFS_CS_READY )
731
- continue ;
732
-
733
- if (pos -> cl_clientid != new -> cl_clientid )
729
+ status = nfs4_match_client (pos , new , & prev , nn );
730
+ if (status < 0 )
731
+ goto out ;
732
+ if (status != 0 )
734
733
continue ;
735
734
736
735
/*
@@ -742,23 +741,15 @@ int nfs41_walk_client_list(struct nfs_client *new,
742
741
new -> cl_serverowner ))
743
742
continue ;
744
743
745
- /* Unlike NFSv4.0, we know that NFSv4.1 always uses the
746
- * uniform string, however someone might switch the
747
- * uniquifier string on us.
748
- */
749
- if (!nfs4_match_client_owner_id (pos , new ))
750
- continue ;
751
744
found :
752
745
atomic_inc (& pos -> cl_count );
753
746
* result = pos ;
754
747
status = 0 ;
755
- dprintk ("NFS: <-- %s using nfs_client = %p ({%d})\n" ,
756
- __func__ , pos , atomic_read (& pos -> cl_count ));
757
748
break ;
758
749
}
759
750
751
+ out :
760
752
spin_unlock (& nn -> nfs_client_lock );
761
- dprintk ("NFS: <-- %s status = %d\n" , __func__ , status );
762
753
nfs_put_client (prev );
763
754
return status ;
764
755
}
0 commit comments