Patchwork [3.5.y.z,extended,stable] Patch "NFS: Add sequence_priviliged_ops for nfs4_proc_sequence()" has been added to staging queue

mail settings
Submitter Herton Ronaldo Krzesinski
Date Jan. 7, 2013, 8:34 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/210151/
State New
Headers show


Herton Ronaldo Krzesinski - Jan. 7, 2013, 8:34 p.m.
This is a note to let you know that I have just added a patch titled

    NFS: Add sequence_priviliged_ops for nfs4_proc_sequence()

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From 5e5195cad4f77a11c34617acb65be18489096e0b Mon Sep 17 00:00:00 2001
From: Bryan Schumaker <>
Date: Mon, 12 Nov 2012 16:55:38 -0500
Subject: [PATCH] NFS: Add sequence_priviliged_ops for nfs4_proc_sequence()

commit 6bdb5f213c4344324f600dde885f25768fbd14db upstream.

If I mount an NFS v4.1 server to a single client multiple times and then
run xfstests over each mountpoint I usually get the client into a state
where recovery deadlocks.  The server informs the client of a
cb_path_down sequence error, the client then does a
bind_connection_to_session and checks the status of the lease.

I found that bind_connection_to_session sets the NFS4_SESSION_DRAINING
flag on the client, but this flag is never unset before
nfs4_check_lease() reaches nfs4_proc_sequence().  This causes the client
to deadlock, halting all NFS activity to the server.  nfs4_proc_sequence()
is only called by the state manager, so I can change it to run in privileged
mode to bypass the NFS4_SESSION_DRAINING check and avoid the deadlock.

Signed-off-by: Bryan Schumaker <>
Signed-off-by: Trond Myklebust <>
Signed-off-by: Herton Ronaldo Krzesinski <>
 fs/nfs/nfs4proc.c |   21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)



diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9b1ac5c..c1bad65 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5937,13 +5937,26 @@  static void nfs41_sequence_prepare(struct rpc_task *task, void *data)

+static void nfs41_sequence_prepare_privileged(struct rpc_task *task, void *data)
+	rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
+	nfs41_sequence_prepare(task, data);
 static const struct rpc_call_ops nfs41_sequence_ops = {
 	.rpc_call_done = nfs41_sequence_call_done,
 	.rpc_call_prepare = nfs41_sequence_prepare,
 	.rpc_release = nfs41_sequence_release,

-static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
+static const struct rpc_call_ops nfs41_sequence_privileged_ops = {
+	.rpc_call_done = nfs41_sequence_call_done,
+	.rpc_call_prepare = nfs41_sequence_prepare_privileged,
+	.rpc_release = nfs41_sequence_release,
+static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred,
+					     const struct rpc_call_ops *seq_ops)
 	struct nfs4_sequence_data *calldata;
 	struct rpc_message msg = {
@@ -5953,7 +5966,7 @@  static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_
 	struct rpc_task_setup task_setup_data = {
 		.rpc_client = clp->cl_rpcclient,
 		.rpc_message = &msg,
-		.callback_ops = &nfs41_sequence_ops,
+		.callback_ops = seq_ops,

@@ -5980,7 +5993,7 @@  static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr

 	if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0)
 		return 0;
-	task = _nfs41_proc_sequence(clp, cred);
+	task = _nfs41_proc_sequence(clp, cred, &nfs41_sequence_ops);
 	if (IS_ERR(task))
 		ret = PTR_ERR(task);
@@ -5994,7 +6007,7 @@  static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
 	struct rpc_task *task;
 	int ret;

-	task = _nfs41_proc_sequence(clp, cred);
+	task = _nfs41_proc_sequence(clp, cred, &nfs41_sequence_privileged_ops);
 	if (IS_ERR(task)) {
 		ret = PTR_ERR(task);
 		goto out;