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

Commit 433fbe4c authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4: State recovery cleanup



 Use wait_on_bit() when waiting for state recovery to complete.

 Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 26e976a8
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ struct idmap;
 ((err) != NFSERR_NOFILEHANDLE))

enum nfs4_client_state {
	NFS4CLNT_OK  = 0,
	NFS4CLNT_STATE_RECOVER  = 0,
};

/*
@@ -76,7 +76,6 @@ struct nfs4_client {
	struct work_struct	cl_renewd;
	struct work_struct	cl_recoverd;

	wait_queue_head_t	cl_waitq;
	struct rpc_wait_queue	cl_rpcwaitq;

	/* used for the setclientid verifier */
+14 −13
Original line number Diff line number Diff line
@@ -2736,7 +2736,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
		case -NFS4ERR_EXPIRED:
			rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL);
			nfs4_schedule_state_recovery(clp);
			if (test_bit(NFS4CLNT_OK, &clp->cl_state))
			if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
				rpc_wake_up_task(task);
			task->tk_status = 0;
			return -EAGAIN;
@@ -2753,25 +2753,25 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
	return 0;
}

static int nfs4_wait_bit_interruptible(void *word)
{
	if (signal_pending(current))
		return -ERESTARTSYS;
	schedule();
	return 0;
}

static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp)
{
	DEFINE_WAIT(wait);
	sigset_t oldset;
	int interruptible, res = 0;
	int res;

	might_sleep();

	rpc_clnt_sigmask(clnt, &oldset);
	interruptible = TASK_UNINTERRUPTIBLE;
	if (clnt->cl_intr)
		interruptible = TASK_INTERRUPTIBLE;
	prepare_to_wait(&clp->cl_waitq, &wait, interruptible);
	nfs4_schedule_state_recovery(clp);
	if (clnt->cl_intr && signalled())
		res = -ERESTARTSYS;
	else if (!test_bit(NFS4CLNT_OK, &clp->cl_state))
		schedule();
	finish_wait(&clp->cl_waitq, &wait);
	res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER,
			nfs4_wait_bit_interruptible,
			TASK_INTERRUPTIBLE);
	rpc_clnt_sigunmask(clnt, &oldset);
	return res;
}
@@ -2814,6 +2814,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct
		case -NFS4ERR_STALE_CLIENTID:
		case -NFS4ERR_STALE_STATEID:
		case -NFS4ERR_EXPIRED:
			nfs4_schedule_state_recovery(clp);
			ret = nfs4_wait_clnt_recover(server->client, clp);
			if (ret == 0)
				exception->retry = 1;
+13 −10
Original line number Diff line number Diff line
@@ -106,11 +106,10 @@ nfs4_alloc_client(struct in_addr *addr)
	INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp);
	INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
	INIT_LIST_HEAD(&clp->cl_superblocks);
	init_waitqueue_head(&clp->cl_waitq);
	rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
	clp->cl_rpcclient = ERR_PTR(-EINVAL);
	clp->cl_boot_time = CURRENT_TIME;
	clp->cl_state = 1 << NFS4CLNT_OK;
	clp->cl_state = 0;
	return clp;
}

@@ -193,7 +192,6 @@ nfs4_put_client(struct nfs4_client *clp)
	list_del(&clp->cl_servers);
	spin_unlock(&state_spinlock);
	BUG_ON(!list_empty(&clp->cl_superblocks));
	wake_up_all(&clp->cl_waitq);
	rpc_wake_up(&clp->cl_rpcwaitq);
	nfs4_kill_renewd(clp);
	nfs4_free_client(clp);
@@ -741,6 +739,15 @@ struct reclaimer_args {
	struct completion complete;
};

static inline void nfs4_clear_recover_bit(struct nfs4_client *clp)
{
	smp_mb__before_clear_bit();
	clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state);
	smp_mb__after_clear_bit();
	wake_up_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER);
	rpc_wake_up(&clp->cl_rpcwaitq);
}

/*
 * State recovery routine
 */
@@ -760,9 +767,7 @@ nfs4_recover_state(void *data)
	wait_for_completion(&args.complete);
	return;
out_failed_clear:
	set_bit(NFS4CLNT_OK, &clp->cl_state);
	wake_up_all(&clp->cl_waitq);
	rpc_wake_up(&clp->cl_rpcwaitq);
	nfs4_clear_recover_bit(clp);
}

/*
@@ -773,7 +778,7 @@ nfs4_schedule_state_recovery(struct nfs4_client *clp)
{
	if (!clp)
		return;
	if (test_and_clear_bit(NFS4CLNT_OK, &clp->cl_state))
	if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
		schedule_work(&clp->cl_recoverd);
}

@@ -943,13 +948,11 @@ static int reclaimer(void *ptr)
	}
	nfs_delegation_reap_unclaimed(clp);
out:
	set_bit(NFS4CLNT_OK, &clp->cl_state);
	up_write(&clp->cl_sem);
	unlock_kernel();
	wake_up_all(&clp->cl_waitq);
	rpc_wake_up(&clp->cl_rpcwaitq);
	if (status == -NFS4ERR_CB_PATH_DOWN)
		nfs_handle_cb_pathdown(clp);
	nfs4_clear_recover_bit(clp);
	nfs4_put_client(clp);
	return 0;
out_error: