]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
nfsd: update percpu_ref to manage references on nfsd_net
authorMike Snitzer <snitzer@kernel.org>
Sat, 16 Nov 2024 01:40:58 +0000 (20:40 -0500)
committerAnna Schumaker <anna.schumaker@oracle.com>
Tue, 14 Jan 2025 22:04:05 +0000 (17:04 -0500)
Holding a reference on nfsd_net is what is required, it was never
actually about ensuring nn->nfsd_serv available.

Move waiting for outstanding percpu references from
nfsd_destroy_serv() to nfsd_shutdown_net().

By moving it later it will be possible to invalidate localio clients
during nfsd_file_cache_shutdown_net() via __nfsd_file_cache_purge().

Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Acked-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
fs/nfsd/nfssvc.c

index 49e2f32102ab59b8a973f1a82bf6aa33e7e3b3cc..6ca5540424266381d66f5bbf2ff054f3f70ee47b 100644 (file)
@@ -436,6 +436,10 @@ static void nfsd_shutdown_net(struct net *net)
 
        if (!nn->nfsd_net_up)
                return;
+
+       percpu_ref_kill_and_confirm(&nn->nfsd_serv_ref, nfsd_serv_done);
+       wait_for_completion(&nn->nfsd_serv_confirm_done);
+
        nfsd_export_flush(net);
        nfs4_state_shutdown_net(net);
        nfsd_reply_cache_shutdown(nn);
@@ -444,7 +448,10 @@ static void nfsd_shutdown_net(struct net *net)
                lockd_down(net);
                nn->lockd_up = false;
        }
+
+       wait_for_completion(&nn->nfsd_serv_free_done);
        percpu_ref_exit(&nn->nfsd_serv_ref);
+
        nn->nfsd_net_up = false;
        nfsd_shutdown_generic();
 }
@@ -526,11 +533,6 @@ void nfsd_destroy_serv(struct net *net)
 
        lockdep_assert_held(&nfsd_mutex);
 
-       percpu_ref_kill_and_confirm(&nn->nfsd_serv_ref, nfsd_serv_done);
-       wait_for_completion(&nn->nfsd_serv_confirm_done);
-       wait_for_completion(&nn->nfsd_serv_free_done);
-       /* percpu_ref_exit is called in nfsd_shutdown_net */
-
        spin_lock(&nfsd_notifier_lock);
        nn->nfsd_serv = NULL;
        spin_unlock(&nfsd_notifier_lock);