@@ -469,6 +469,50 @@ static bool nfs4_same_verifier(nfs4_verifier *v1, nfs4_verifier *v2)
469469 return memcmp (v1 -> data , v2 -> data , sizeof (v1 -> data )) == 0 ;
470470}
471471
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+
472516/**
473517 * nfs40_walk_client_list - Find server that recognizes a client ID
474518 *
@@ -497,34 +541,10 @@ int nfs40_walk_client_list(struct nfs_client *new,
497541 spin_lock (& nn -> nfs_client_lock );
498542 list_for_each_entry (pos , & nn -> nfs_client_list , cl_share_link ) {
499543
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 )
528548 continue ;
529549 /*
530550 * We just sent a new SETCLIENTID, which should have
@@ -567,11 +587,13 @@ int nfs40_walk_client_list(struct nfs_client *new,
567587 */
568588 nfs4_schedule_path_down_recovery (pos );
569589 default :
590+ spin_lock (& nn -> nfs_client_lock );
570591 goto out ;
571592 }
572593
573594 spin_lock (& nn -> nfs_client_lock );
574595 }
596+ out_unlock :
575597 spin_unlock (& nn -> nfs_client_lock );
576598
577599 /* No match found. The server lost our clientid */
@@ -704,33 +726,10 @@ int nfs41_walk_client_list(struct nfs_client *new,
704726 if (pos == new )
705727 goto found ;
706728
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 )
734733 continue ;
735734
736735 /*
@@ -742,23 +741,15 @@ int nfs41_walk_client_list(struct nfs_client *new,
742741 new -> cl_serverowner ))
743742 continue ;
744743
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 ;
751744found :
752745 atomic_inc (& pos -> cl_count );
753746 * result = pos ;
754747 status = 0 ;
755- dprintk ("NFS: <-- %s using nfs_client = %p ({%d})\n" ,
756- __func__ , pos , atomic_read (& pos -> cl_count ));
757748 break ;
758749 }
759750
751+ out :
760752 spin_unlock (& nn -> nfs_client_lock );
761- dprintk ("NFS: <-- %s status = %d\n" , __func__ , status );
762753 nfs_put_client (prev );
763754 return status ;
764755}
0 commit comments