summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs4proc.c6
-rw-r--r--fs/nfsd/nfs4state.c16
2 files changed, 21 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index eb8a2a16839f..3e4de45aa360 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1587,6 +1587,11 @@ static bool nfsd4_copy_on_sb(const struct nfsd4_copy *copy,
* nfsd4_cancel_copy_by_sb - cancel async copy operations on @sb
* @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.
*/
void nfsd4_cancel_copy_by_sb(struct net *net, struct super_block *sb)
{
@@ -1596,6 +1601,7 @@ void nfsd4_cancel_copy_by_sb(struct net *net, struct super_block *sb)
unsigned int idhashval;
LIST_HEAD(to_cancel);
+ lockdep_assert_held(&nfsd_mutex);
spin_lock(&nn->client_lock);
for (idhashval = 0; idhashval < CLIENT_HASH_SIZE; idhashval++) {
struct list_head *head = &nn->conf_id_hashtbl[idhashval];
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index bef0ec9be459..2a6a0c9ef65f 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1873,14 +1873,21 @@ static void revoke_one_stid(struct nfsd_net *nn, struct nfs4_client *clp,
* being released. Thus nfsd will no longer prevent the filesystem from being
* unmounted.
*
- * The clients which own the states will subsequently being notified that the
+ * 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.
*/
void nfsd4_revoke_states(struct nfsd_net *nn, struct super_block *sb)
{
unsigned int idhashval;
unsigned int sc_types;
+ lockdep_assert_held(&nfsd_mutex);
+
sc_types = SC_TYPE_OPEN | SC_TYPE_LOCK | SC_TYPE_DELEG | SC_TYPE_LAYOUT;
spin_lock(&nn->client_lock);
@@ -1946,12 +1953,19 @@ 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.
*/
void nfsd4_revoke_export_states(struct nfsd_net *nn, const struct path *path)
{
unsigned int idhashval;
unsigned int sc_types;
+ lockdep_assert_held(&nfsd_mutex);
+
sc_types = SC_TYPE_OPEN | SC_TYPE_LOCK | SC_TYPE_DELEG | SC_TYPE_LAYOUT;
spin_lock(&nn->client_lock);