diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index c413ed0810b9..8351ccaae59c 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1588,10 +1588,9 @@ static bool nfsd4_copy_on_sb(const struct nfsd4_copy *copy, * @net: net namespace containing the copy operations * @sb: targeted superblock * - * Context: Caller must hold nfsd_mutex with nn->nfsd_serv confirmed - * non-NULL. nfs4_state_destroy_net() frees conf_id_hashtbl - * at server shutdown without clearing the pointer, so a - * walk without these guarantees iterates freed slab memory. + * Context: Caller must hold nfsd_mutex with NFSD_NET_UP set. Outside + * that window nn->conf_id_hashtbl is unallocated or freed, + * so the walk would dereference a NULL or dangling pointer. */ void nfsd4_cancel_copy_by_sb(struct net *net, struct super_block *sb) { diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 4ae5d65c056a..a4398dc861a5 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1946,10 +1946,9 @@ static void revoke_one_stid(struct nfsd_net *nn, struct nfs4_client *clp, * The clients which own the states will subsequently be notified that the * states have been "admin-revoked". * - * Context: Caller must hold nfsd_mutex with nn->nfsd_serv confirmed - * non-NULL. nfs4_state_destroy_net() frees conf_id_hashtbl - * at server shutdown without clearing the pointer, so a - * walk without these guarantees iterates freed slab memory. + * Context: Caller must hold nfsd_mutex with NFSD_NET_UP set. Outside + * that window nn->conf_id_hashtbl is unallocated or freed, + * so the walk would dereference a NULL or dangling pointer. */ void nfsd4_revoke_states(struct nfsd_net *nn, struct super_block *sb) { @@ -2024,10 +2023,9 @@ static struct nfs4_stid *find_one_export_stid(struct nfs4_client *clp, * Userspace (exportfs -u) sends this after removing the last client * for a path, enabling the underlying filesystem to be unmounted. * - * Context: Caller must hold nfsd_mutex with nn->nfsd_serv confirmed - * non-NULL. nfs4_state_destroy_net() frees conf_id_hashtbl - * at server shutdown without clearing the pointer, so a - * walk without these guarantees iterates freed slab memory. + * Context: Caller must hold nfsd_mutex with NFSD_NET_UP set. Outside + * that window nn->conf_id_hashtbl is unallocated or freed, + * so the walk would dereference a NULL or dangling pointer. */ void nfsd4_revoke_export_states(struct nfsd_net *nn, const struct path *path) { diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index caf59421f8f4..bc16fc7ca24f 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -299,7 +299,7 @@ static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size) error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb); mutex_lock(&nfsd_mutex); nn = net_generic(netns(file), nfsd_net_id); - if (nn->nfsd_serv) { + if (test_bit(NFSD_NET_UP, &nn->flags)) { nfsd4_cancel_copy_by_sb(netns(file), path.dentry->d_sb); nfsd4_revoke_states(nn, path.dentry->d_sb); } else { @@ -2424,7 +2424,7 @@ int nfsd_nl_unlock_filesystem_doit(struct sk_buff *skb, error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb); mutex_lock(&nfsd_mutex); - if (nn->nfsd_serv) { + if (test_bit(NFSD_NET_UP, &nn->flags)) { nfsd4_cancel_copy_by_sb(net, path.dentry->d_sb); nfsd4_revoke_states(nn, path.dentry->d_sb); } else { @@ -2471,7 +2471,7 @@ int nfsd_nl_unlock_export_doit(struct sk_buff *skb, struct genl_info *info) return error; mutex_lock(&nfsd_mutex); - if (nn->nfsd_serv) { + if (test_bit(NFSD_NET_UP, &nn->flags)) { nfsd_file_close_export(net, &path); nfsd4_revoke_export_states(nn, &path); } else