Browse Source

nfs41: use rpc prepare call state for session reset

[nfs41: change nfs4_restart_rpc argument]
[nfs41: check for session not minorversion]
[nfs41: trigger the state manager for session reset]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[always define nfs4_restart_rpc]
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Andy Adamson 16 years ago
parent
commit
eedc020e71
5 changed files with 41 additions and 25 deletions
  1. 27 12
      fs/nfs/internal.h
  2. 8 7
      fs/nfs/nfs4proc.c
  3. 1 1
      fs/nfs/read.c
  4. 1 1
      fs/nfs/unlink.c
  5. 4 4
      fs/nfs/write.c

+ 27 - 12
fs/nfs/internal.h

@@ -2,6 +2,7 @@
  * NFS internal definitions
  * NFS internal definitions
  */
  */
 
 
+#include "nfs4_fs.h"
 #include <linux/mount.h>
 #include <linux/mount.h>
 #include <linux/security.h>
 #include <linux/security.h>
 
 
@@ -17,6 +18,18 @@ struct nfs_string;
  */
  */
 #define NFS_MAX_READAHEAD	(RPC_DEF_SLOT_TABLE - 1)
 #define NFS_MAX_READAHEAD	(RPC_DEF_SLOT_TABLE - 1)
 
 
+/*
+ * Determine if sessions are in use.
+ */
+static inline int nfs4_has_session(const struct nfs_client *clp)
+{
+#ifdef CONFIG_NFS_V4_1
+	if (clp->cl_session)
+		return 1;
+#endif /* CONFIG_NFS_V4_1 */
+	return 0;
+}
+
 struct nfs_clone_mount {
 struct nfs_clone_mount {
 	const struct super_block *sb;
 	const struct super_block *sb;
 	const struct dentry *dentry;
 	const struct dentry *dentry;
@@ -148,6 +161,20 @@ extern __be32 * nfs_decode_dirent(__be32 *, struct nfs_entry *, int);
 extern struct rpc_procinfo nfs3_procedures[];
 extern struct rpc_procinfo nfs3_procedures[];
 extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int);
 extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int);
 
 
+/* nfs4proc.c */
+static inline void nfs4_restart_rpc(struct rpc_task *task,
+				    const struct nfs_client *clp)
+{
+#ifdef CONFIG_NFS_V4_1
+	if (nfs4_has_session(clp) &&
+	    test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) {
+		rpc_restart_call_prepare(task);
+		return;
+	}
+#endif /* CONFIG_NFS_V4_1 */
+	rpc_restart_call(task);
+}
+
 /* nfs4xdr.c */
 /* nfs4xdr.c */
 #ifdef CONFIG_NFS_V4
 #ifdef CONFIG_NFS_V4
 extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
 extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
@@ -225,18 +252,6 @@ extern int _nfs4_call_sync_session(struct nfs_server *server,
 				   struct nfs4_sequence_res *res,
 				   struct nfs4_sequence_res *res,
 				   int cache_reply);
 				   int cache_reply);
 
 
-/*
- * Determine if sessions are in use.
- */
-static inline int nfs4_has_session(const struct nfs_client *clp)
-{
-#ifdef CONFIG_NFS_V4_1
-	if (clp->cl_session)
-		return 1;
-#endif /* CONFIG_NFS_V4_1 */
-	return 0;
-}
-
 #ifdef CONFIG_NFS_V4_1
 #ifdef CONFIG_NFS_V4_1
 extern void nfs41_sequence_free_slot(const struct nfs_client *,
 extern void nfs41_sequence_free_slot(const struct nfs_client *,
 				     struct nfs4_sequence_res *res);
 				     struct nfs4_sequence_res *res);

+ 8 - 7
fs/nfs/nfs4proc.c

@@ -1661,7 +1661,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
 				break;
 				break;
 		default:
 		default:
 			if (nfs4_async_handle_error(task, server, state) == -EAGAIN) {
 			if (nfs4_async_handle_error(task, server, state) == -EAGAIN) {
-				rpc_restart_call(task);
+				nfs4_restart_rpc(task, server->nfs_client);
 				return;
 				return;
 			}
 			}
 	}
 	}
@@ -2874,7 +2874,7 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
 	nfs4_sequence_done(server, &data->res.seq_res, task->tk_status);
 	nfs4_sequence_done(server, &data->res.seq_res, task->tk_status);
 
 
 	if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
 	if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
-		rpc_restart_call(task);
+		nfs4_restart_rpc(task, server->nfs_client);
 		return -EAGAIN;
 		return -EAGAIN;
 	}
 	}
 
 
@@ -2899,7 +2899,7 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
 			   task->tk_status);
 			   task->tk_status);
 
 
 	if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
 	if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
-		rpc_restart_call(task);
+		nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
 		return -EAGAIN;
 		return -EAGAIN;
 	}
 	}
 	if (task->tk_status >= 0) {
 	if (task->tk_status >= 0) {
@@ -2927,7 +2927,7 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
 	nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
 	nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
 			   task->tk_status);
 			   task->tk_status);
 	if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
 	if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
-		rpc_restart_call(task);
+		nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
 		return -EAGAIN;
 		return -EAGAIN;
 	}
 	}
 	nfs4_sequence_free_slot(NFS_SERVER(inode)->nfs_client,
 	nfs4_sequence_free_slot(NFS_SERVER(inode)->nfs_client,
@@ -3628,7 +3628,8 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
 			break;
 			break;
 		default:
 		default:
 			if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
 			if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
-				rpc_restart_call(task);
+				nfs4_restart_rpc(task,
+						calldata->server->nfs_client);
 	}
 	}
 	nfs4_sequence_free_slot(calldata->server->nfs_client,
 	nfs4_sequence_free_slot(calldata->server->nfs_client,
 				&calldata->res.seq_res);
 				&calldata->res.seq_res);
@@ -4237,7 +4238,7 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
 		dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
 		dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
 		rpc_delay(task, NFS4_POLL_RETRY_MIN);
 		rpc_delay(task, NFS4_POLL_RETRY_MIN);
 		task->tk_status = 0;
 		task->tk_status = 0;
-		rpc_restart_call(task);
+		nfs4_restart_rpc(task, data->clp);
 		return;
 		return;
 	}
 	}
 	nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res);
 	nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res);
@@ -4647,7 +4648,7 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
 
 
 		if (_nfs4_async_handle_error(task, NULL, clp, NULL)
 		if (_nfs4_async_handle_error(task, NULL, clp, NULL)
 								== -EAGAIN) {
 								== -EAGAIN) {
-			rpc_restart_call(task);
+			nfs4_restart_rpc(task, clp);
 			return;
 			return;
 		}
 		}
 	}
 	}

+ 1 - 1
fs/nfs/read.c

@@ -371,7 +371,7 @@ static void nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data
 	argp->offset += resp->count;
 	argp->offset += resp->count;
 	argp->pgbase += resp->count;
 	argp->pgbase += resp->count;
 	argp->count -= resp->count;
 	argp->count -= resp->count;
-	rpc_restart_call(task);
+	nfs4_restart_rpc(task, NFS_SERVER(data->inode)->nfs_client);
 	return;
 	return;
 out:
 out:
 	nfs4_sequence_free_slot(NFS_SERVER(data->inode)->nfs_client,
 	nfs4_sequence_free_slot(NFS_SERVER(data->inode)->nfs_client,

+ 1 - 1
fs/nfs/unlink.c

@@ -83,7 +83,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
 	struct inode *dir = data->dir;
 	struct inode *dir = data->dir;
 
 
 	if (!NFS_PROTO(dir)->unlink_done(task, dir))
 	if (!NFS_PROTO(dir)->unlink_done(task, dir))
-		rpc_restart_call(task);
+		nfs4_restart_rpc(task, NFS_SERVER(dir)->nfs_client);
 }
 }
 
 
 /**
 /**

+ 4 - 4
fs/nfs/write.c

@@ -1145,6 +1145,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
 {
 {
 	struct nfs_writeargs	*argp = &data->args;
 	struct nfs_writeargs	*argp = &data->args;
 	struct nfs_writeres	*resp = &data->res;
 	struct nfs_writeres	*resp = &data->res;
+	struct nfs_server	*server = NFS_SERVER(data->inode);
 	int status;
 	int status;
 
 
 	dprintk("NFS: %5u nfs_writeback_done (status %d)\n",
 	dprintk("NFS: %5u nfs_writeback_done (status %d)\n",
@@ -1177,7 +1178,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
 		if (time_before(complain, jiffies)) {
 		if (time_before(complain, jiffies)) {
 			dprintk("NFS:       faulty NFS server %s:"
 			dprintk("NFS:       faulty NFS server %s:"
 				" (committed = %d) != (stable = %d)\n",
 				" (committed = %d) != (stable = %d)\n",
-				NFS_SERVER(data->inode)->nfs_client->cl_hostname,
+				server->nfs_client->cl_hostname,
 				resp->verf->committed, argp->stable);
 				resp->verf->committed, argp->stable);
 			complain = jiffies + 300 * HZ;
 			complain = jiffies + 300 * HZ;
 		}
 		}
@@ -1203,7 +1204,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
 				 */
 				 */
 				argp->stable = NFS_FILE_SYNC;
 				argp->stable = NFS_FILE_SYNC;
 			}
 			}
-			rpc_restart_call(task);
+			nfs4_restart_rpc(task, server->nfs_client);
 			return -EAGAIN;
 			return -EAGAIN;
 		}
 		}
 		if (time_before(complain, jiffies)) {
 		if (time_before(complain, jiffies)) {
@@ -1215,8 +1216,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
 		/* Can't do anything about it except throw an error. */
 		/* Can't do anything about it except throw an error. */
 		task->tk_status = -EIO;
 		task->tk_status = -EIO;
 	}
 	}
-	nfs4_sequence_free_slot(NFS_SERVER(data->inode)->nfs_client,
-				&data->res.seq_res);
+	nfs4_sequence_free_slot(server->nfs_client, &data->res.seq_res);
 	return 0;
 	return 0;
 }
 }