Skip to content

Commit 5bab56f

Browse files
neilbrownamschuma-ntap
authored andcommitted
NFS: fix disabling of swap
When swap is activated to a file on an NFSv4 mount we arrange that the state manager thread is always present as starting a new thread requires memory allocations that might block waiting for swap. Unfortunately the code for allowing the state manager thread to exit when swap is disabled was not tested properly and does not work. This can be seen by examining /proc/fs/nfsfs/servers after disabling swap and unmounting the filesystem. The servers file will still list one entry. Also a "ps" listing will show the state manager thread is still present. There are two problems. 1/ rpc_clnt_swap_deactivate() doesn't walk up the ->cl_parent list to find the primary client on which the state manager runs. 2/ The thread is not woken up properly and it immediately goes back to sleep without checking whether it is really needed. Using nfs4_schedule_state_manager() ensures a proper wake-up. Reported-by: Olga Kornievskaia <[email protected]> Fixes: 4dc73c6 ("NFSv4: keep state manager thread active if swap is enabled") Signed-off-by: NeilBrown <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent d67307b commit 5bab56f

File tree

2 files changed

+5
-1
lines changed

2 files changed

+5
-1
lines changed

fs/nfs/nfs4proc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10604,7 +10604,9 @@ static void nfs4_disable_swap(struct inode *inode)
1060410604
/* The state manager thread will now exit once it is
1060510605
* woken.
1060610606
*/
10607-
wake_up_var(&NFS_SERVER(inode)->nfs_client->cl_state);
10607+
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
10608+
10609+
nfs4_schedule_state_manager(clp);
1060810610
}
1060910611

1061010612
static const struct inode_operations nfs4_dir_inode_operations = {

net/sunrpc/clnt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3350,6 +3350,8 @@ rpc_clnt_swap_deactivate_callback(struct rpc_clnt *clnt,
33503350
void
33513351
rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
33523352
{
3353+
while (clnt != clnt->cl_parent)
3354+
clnt = clnt->cl_parent;
33533355
if (atomic_dec_if_positive(&clnt->cl_swapper) == 0)
33543356
rpc_clnt_iterate_for_each_xprt(clnt,
33553357
rpc_clnt_swap_deactivate_callback, NULL);

0 commit comments

Comments
 (0)