mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-17 18:56:24 +00:00
NFS: fix disabling of swap
[ Upstream commit 5bab56fff53ce161ed859d9559a10361d4f79578 ] 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 <aglo@umich.edu> Fixes: 4dc73c679114 ("NFSv4: keep state manager thread active if swap is enabled") Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
242df51a82
commit
ac3a513d4f
@ -10400,7 +10400,9 @@ static void nfs4_disable_swap(struct inode *inode)
|
||||
/* The state manager thread will now exit once it is
|
||||
* woken.
|
||||
*/
|
||||
wake_up_var(&NFS_SERVER(inode)->nfs_client->cl_state);
|
||||
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
|
||||
|
||||
nfs4_schedule_state_manager(clp);
|
||||
}
|
||||
|
||||
static const struct inode_operations nfs4_dir_inode_operations = {
|
||||
|
@ -3047,6 +3047,8 @@ rpc_clnt_swap_deactivate_callback(struct rpc_clnt *clnt,
|
||||
void
|
||||
rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
|
||||
{
|
||||
while (clnt != clnt->cl_parent)
|
||||
clnt = clnt->cl_parent;
|
||||
if (atomic_dec_if_positive(&clnt->cl_swapper) == 0)
|
||||
rpc_clnt_iterate_for_each_xprt(clnt,
|
||||
rpc_clnt_swap_deactivate_callback, NULL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user