Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1dd761e9 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4: Ensure the callback daemon flushes signals



If the callback daemon is signalled, but is unable to exit because it still
has users, then we need to flush signals. If not, then svc_recv() can
never sleep, and so we hang.
If we flush signals, then we also have to be prepared to resend them when
we want the thread to exit.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 54281548
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -55,7 +55,12 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)

	complete(&nfs_callback_info.started);

	while (nfs_callback_info.users != 0 || !signalled()) {
	for(;;) {
		if (signalled()) {
			if (nfs_callback_info.users == 0)
				break;
			flush_signals(current);
		}
		/*
		 * Listen for a request on the socket
		 */
@@ -135,11 +140,13 @@ int nfs_callback_down(void)

	lock_kernel();
	down(&nfs_callback_sema);
	if (--nfs_callback_info.users || nfs_callback_info.pid == 0)
		goto out;
	kill_proc(nfs_callback_info.pid, SIGKILL, 1);
	wait_for_completion(&nfs_callback_info.stopped);
out:
	nfs_callback_info.users--;
	do {
		if (nfs_callback_info.users != 0 || nfs_callback_info.pid == 0)
			break;
		if (kill_proc(nfs_callback_info.pid, SIGKILL, 1) < 0)
			break;
	} while (wait_for_completion_timeout(&nfs_callback_info.stopped, 5*HZ) == 0);
	up(&nfs_callback_sema);
	unlock_kernel();
	return ret;