aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/Kconfig2
-rw-r--r--fs/nfs/callback.c13
-rw-r--r--fs/nfs/callback.h16
-rw-r--r--fs/nfs/callback_proc.c64
-rw-r--r--fs/nfs/callback_xdr.c34
-rw-r--r--fs/nfs/client.c14
-rw-r--r--fs/nfs/delegation.c77
-rw-r--r--fs/nfs/delegation.h7
-rw-r--r--fs/nfs/dir.c69
-rw-r--r--fs/nfs/direct.c1
-rw-r--r--fs/nfs/dns_resolve.c4
-rw-r--r--fs/nfs/file.c4
-rw-r--r--fs/nfs/fscache.c10
-rw-r--r--fs/nfs/internal.h54
-rw-r--r--fs/nfs/iostat.h24
-rw-r--r--fs/nfs/nfs4_fs.h17
-rw-r--r--fs/nfs/nfs4proc.c650
-rw-r--r--fs/nfs/nfs4state.c241
-rw-r--r--fs/nfs/nfs4xdr.c136
-rw-r--r--fs/nfs/read.c12
-rw-r--r--fs/nfs/super.c104
-rw-r--r--fs/nfs/sysctl.c22
-rw-r--r--fs/nfs/unlink.c2
-rw-r--r--fs/nfs/write.c12
24 files changed, 1087 insertions, 502 deletions
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 2a77bc25d5af..59e5673b4597 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -90,7 +90,7 @@ config ROOT_NFS
90 If you want your system to mount its root file system via NFS, 90 If you want your system to mount its root file system via NFS,
91 choose Y here. This is common practice for managing systems 91 choose Y here. This is common practice for managing systems
92 without local permanent storage. For details, read 92 without local permanent storage. For details, read
93 <file:Documentation/filesystems/nfsroot.txt>. 93 <file:Documentation/filesystems/nfs/nfsroot.txt>.
94 94
95 Most people say N here. 95 Most people say N here.
96 96
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 293fa0528a6e..73ab220354df 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -78,11 +78,6 @@ nfs4_callback_svc(void *vrqstp)
78 78
79 set_freezable(); 79 set_freezable();
80 80
81 /*
82 * FIXME: do we really need to run this under the BKL? If so, please
83 * add a comment about what it's intended to protect.
84 */
85 lock_kernel();
86 while (!kthread_should_stop()) { 81 while (!kthread_should_stop()) {
87 /* 82 /*
88 * Listen for a request on the socket 83 * Listen for a request on the socket
@@ -104,7 +99,6 @@ nfs4_callback_svc(void *vrqstp)
104 preverr = err; 99 preverr = err;
105 svc_process(rqstp); 100 svc_process(rqstp);
106 } 101 }
107 unlock_kernel();
108 return 0; 102 return 0;
109} 103}
110 104
@@ -160,11 +154,6 @@ nfs41_callback_svc(void *vrqstp)
160 154
161 set_freezable(); 155 set_freezable();
162 156
163 /*
164 * FIXME: do we really need to run this under the BKL? If so, please
165 * add a comment about what it's intended to protect.
166 */
167 lock_kernel();
168 while (!kthread_should_stop()) { 157 while (!kthread_should_stop()) {
169 prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE); 158 prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
170 spin_lock_bh(&serv->sv_cb_lock); 159 spin_lock_bh(&serv->sv_cb_lock);
@@ -183,7 +172,6 @@ nfs41_callback_svc(void *vrqstp)
183 } 172 }
184 finish_wait(&serv->sv_cb_waitq, &wq); 173 finish_wait(&serv->sv_cb_waitq, &wq);
185 } 174 }
186 unlock_kernel();
187 return 0; 175 return 0;
188} 176}
189 177
@@ -397,6 +385,7 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp)
397 */ 385 */
398static struct svc_version *nfs4_callback_version[] = { 386static struct svc_version *nfs4_callback_version[] = {
399 [1] = &nfs4_callback_version1, 387 [1] = &nfs4_callback_version1,
388 [4] = &nfs4_callback_version4,
400}; 389};
401 390
402static struct svc_stat nfs4_callback_stats; 391static struct svc_stat nfs4_callback_stats;
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index 07baa8254ca1..d4036be0b589 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -106,6 +106,19 @@ struct cb_sequenceres {
106extern unsigned nfs4_callback_sequence(struct cb_sequenceargs *args, 106extern unsigned nfs4_callback_sequence(struct cb_sequenceargs *args,
107 struct cb_sequenceres *res); 107 struct cb_sequenceres *res);
108 108
109extern int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation,
110 const nfs4_stateid *stateid);
111
112#define RCA4_TYPE_MASK_RDATA_DLG 0
113#define RCA4_TYPE_MASK_WDATA_DLG 1
114
115struct cb_recallanyargs {
116 struct sockaddr *craa_addr;
117 uint32_t craa_objs_to_keep;
118 uint32_t craa_type_mask;
119};
120
121extern unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy);
109#endif /* CONFIG_NFS_V4_1 */ 122#endif /* CONFIG_NFS_V4_1 */
110 123
111extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res); 124extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res);
@@ -114,8 +127,9 @@ extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
114#ifdef CONFIG_NFS_V4 127#ifdef CONFIG_NFS_V4
115extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt); 128extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
116extern void nfs_callback_down(int minorversion); 129extern void nfs_callback_down(int minorversion);
130extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation,
131 const nfs4_stateid *stateid);
117#endif /* CONFIG_NFS_V4 */ 132#endif /* CONFIG_NFS_V4 */
118
119/* 133/*
120 * nfs41: Callbacks are expected to not cause substantial latency, 134 * nfs41: Callbacks are expected to not cause substantial latency,
121 * so we limit their concurrency to 1 by setting up the maximum number 135 * so we limit their concurrency to 1 by setting up the maximum number
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index b7da1f54da68..defa9b4c470e 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -61,6 +61,16 @@ out:
61 return res->status; 61 return res->status;
62} 62}
63 63
64static int (*nfs_validate_delegation_stateid(struct nfs_client *clp))(struct nfs_delegation *, const nfs4_stateid *)
65{
66#if defined(CONFIG_NFS_V4_1)
67 if (clp->cl_minorversion > 0)
68 return nfs41_validate_delegation_stateid;
69#endif
70 return nfs4_validate_delegation_stateid;
71}
72
73
64__be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy) 74__be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
65{ 75{
66 struct nfs_client *clp; 76 struct nfs_client *clp;
@@ -81,7 +91,8 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
81 inode = nfs_delegation_find_inode(clp, &args->fh); 91 inode = nfs_delegation_find_inode(clp, &args->fh);
82 if (inode != NULL) { 92 if (inode != NULL) {
83 /* Set up a helper thread to actually return the delegation */ 93 /* Set up a helper thread to actually return the delegation */
84 switch(nfs_async_inode_return_delegation(inode, &args->stateid)) { 94 switch (nfs_async_inode_return_delegation(inode, &args->stateid,
95 nfs_validate_delegation_stateid(clp))) {
85 case 0: 96 case 0:
86 res = 0; 97 res = 0;
87 break; 98 break;
@@ -102,8 +113,31 @@ out:
102 return res; 113 return res;
103} 114}
104 115
116int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid)
117{
118 if (delegation == NULL || memcmp(delegation->stateid.data, stateid->data,
119 sizeof(delegation->stateid.data)) != 0)
120 return 0;
121 return 1;
122}
123
105#if defined(CONFIG_NFS_V4_1) 124#if defined(CONFIG_NFS_V4_1)
106 125
126int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid)
127{
128 if (delegation == NULL)
129 return 0;
130
131 /* seqid is 4-bytes long */
132 if (((u32 *) &stateid->data)[0] != 0)
133 return 0;
134 if (memcmp(&delegation->stateid.data[4], &stateid->data[4],
135 sizeof(stateid->data)-4))
136 return 0;
137
138 return 1;
139}
140
107/* 141/*
108 * Validate the sequenceID sent by the server. 142 * Validate the sequenceID sent by the server.
109 * Return success if the sequenceID is one more than what we last saw on 143 * Return success if the sequenceID is one more than what we last saw on
@@ -227,4 +261,32 @@ out:
227 return res->csr_status; 261 return res->csr_status;
228} 262}
229 263
264unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy)
265{
266 struct nfs_client *clp;
267 int status;
268 fmode_t flags = 0;
269
270 status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
271 clp = nfs_find_client(args->craa_addr, 4);
272 if (clp == NULL)
273 goto out;
274
275 dprintk("NFS: RECALL_ANY callback request from %s\n",
276 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR));
277
278 if (test_bit(RCA4_TYPE_MASK_RDATA_DLG, (const unsigned long *)
279 &args->craa_type_mask))
280 flags = FMODE_READ;
281 if (test_bit(RCA4_TYPE_MASK_WDATA_DLG, (const unsigned long *)
282 &args->craa_type_mask))
283 flags |= FMODE_WRITE;
284
285 if (flags)
286 nfs_expire_all_delegation_types(clp, flags);
287 status = htonl(NFS4_OK);
288out:
289 dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
290 return status;
291}
230#endif /* CONFIG_NFS_V4_1 */ 292#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 76b0aa0f73bf..8e1a2511c8be 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -23,6 +23,7 @@
23#if defined(CONFIG_NFS_V4_1) 23#if defined(CONFIG_NFS_V4_1)
24#define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ 24#define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
25 4 + 1 + 3) 25 4 + 1 + 3)
26#define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
26#endif /* CONFIG_NFS_V4_1 */ 27#endif /* CONFIG_NFS_V4_1 */
27 28
28#define NFSDBG_FACILITY NFSDBG_CALLBACK 29#define NFSDBG_FACILITY NFSDBG_CALLBACK
@@ -326,6 +327,25 @@ out_free:
326 goto out; 327 goto out;
327} 328}
328 329
330static unsigned decode_recallany_args(struct svc_rqst *rqstp,
331 struct xdr_stream *xdr,
332 struct cb_recallanyargs *args)
333{
334 uint32_t *p;
335
336 args->craa_addr = svc_addr(rqstp);
337 p = read_buf(xdr, 4);
338 if (unlikely(p == NULL))
339 return htonl(NFS4ERR_BADXDR);
340 args->craa_objs_to_keep = ntohl(*p++);
341 p = read_buf(xdr, 4);
342 if (unlikely(p == NULL))
343 return htonl(NFS4ERR_BADXDR);
344 args->craa_type_mask = ntohl(*p);
345
346 return 0;
347}
348
329#endif /* CONFIG_NFS_V4_1 */ 349#endif /* CONFIG_NFS_V4_1 */
330 350
331static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) 351static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
@@ -533,6 +553,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
533 case OP_CB_GETATTR: 553 case OP_CB_GETATTR:
534 case OP_CB_RECALL: 554 case OP_CB_RECALL:
535 case OP_CB_SEQUENCE: 555 case OP_CB_SEQUENCE:
556 case OP_CB_RECALL_ANY:
536 *op = &callback_ops[op_nr]; 557 *op = &callback_ops[op_nr];
537 break; 558 break;
538 559
@@ -540,7 +561,6 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
540 case OP_CB_NOTIFY_DEVICEID: 561 case OP_CB_NOTIFY_DEVICEID:
541 case OP_CB_NOTIFY: 562 case OP_CB_NOTIFY:
542 case OP_CB_PUSH_DELEG: 563 case OP_CB_PUSH_DELEG:
543 case OP_CB_RECALL_ANY:
544 case OP_CB_RECALLABLE_OBJ_AVAIL: 564 case OP_CB_RECALLABLE_OBJ_AVAIL:
545 case OP_CB_RECALL_SLOT: 565 case OP_CB_RECALL_SLOT:
546 case OP_CB_WANTS_CANCELLED: 566 case OP_CB_WANTS_CANCELLED:
@@ -688,6 +708,11 @@ static struct callback_op callback_ops[] = {
688 .encode_res = (callback_encode_res_t)encode_cb_sequence_res, 708 .encode_res = (callback_encode_res_t)encode_cb_sequence_res,
689 .res_maxsize = CB_OP_SEQUENCE_RES_MAXSZ, 709 .res_maxsize = CB_OP_SEQUENCE_RES_MAXSZ,
690 }, 710 },
711 [OP_CB_RECALL_ANY] = {
712 .process_op = (callback_process_op_t)nfs4_callback_recallany,
713 .decode_args = (callback_decode_arg_t)decode_recallany_args,
714 .res_maxsize = CB_OP_RECALLANY_RES_MAXSZ,
715 },
691#endif /* CONFIG_NFS_V4_1 */ 716#endif /* CONFIG_NFS_V4_1 */
692}; 717};
693 718
@@ -718,3 +743,10 @@ struct svc_version nfs4_callback_version1 = {
718 .vs_dispatch = NULL, 743 .vs_dispatch = NULL,
719}; 744};
720 745
746struct svc_version nfs4_callback_version4 = {
747 .vs_vers = 4,
748 .vs_nproc = ARRAY_SIZE(nfs4_callback_procedures1),
749 .vs_proc = nfs4_callback_procedures1,
750 .vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
751 .vs_dispatch = NULL,
752};
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 99ea196f071f..ee77713ce68b 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1260,10 +1260,20 @@ error:
1260static void nfs4_session_set_rwsize(struct nfs_server *server) 1260static void nfs4_session_set_rwsize(struct nfs_server *server)
1261{ 1261{
1262#ifdef CONFIG_NFS_V4_1 1262#ifdef CONFIG_NFS_V4_1
1263 struct nfs4_session *sess;
1264 u32 server_resp_sz;
1265 u32 server_rqst_sz;
1266
1263 if (!nfs4_has_session(server->nfs_client)) 1267 if (!nfs4_has_session(server->nfs_client))
1264 return; 1268 return;
1265 server->rsize = server->nfs_client->cl_session->fc_attrs.max_resp_sz; 1269 sess = server->nfs_client->cl_session;
1266 server->wsize = server->nfs_client->cl_session->fc_attrs.max_rqst_sz; 1270 server_resp_sz = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
1271 server_rqst_sz = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;
1272
1273 if (server->rsize > server_resp_sz)
1274 server->rsize = server_resp_sz;
1275 if (server->wsize > server_rqst_sz)
1276 server->wsize = server_rqst_sz;
1267#endif /* CONFIG_NFS_V4_1 */ 1277#endif /* CONFIG_NFS_V4_1 */
1268} 1278}
1269 1279
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 6dd48a4405b4..2563bebc4c67 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -92,7 +92,7 @@ out:
92 return status; 92 return status;
93} 93}
94 94
95static void nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid) 95static int nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid)
96{ 96{
97 struct nfs_inode *nfsi = NFS_I(inode); 97 struct nfs_inode *nfsi = NFS_I(inode);
98 struct nfs_open_context *ctx; 98 struct nfs_open_context *ctx;
@@ -116,10 +116,11 @@ again:
116 err = nfs_delegation_claim_locks(ctx, state); 116 err = nfs_delegation_claim_locks(ctx, state);
117 put_nfs_open_context(ctx); 117 put_nfs_open_context(ctx);
118 if (err != 0) 118 if (err != 0)
119 return; 119 return err;
120 goto again; 120 goto again;
121 } 121 }
122 spin_unlock(&inode->i_lock); 122 spin_unlock(&inode->i_lock);
123 return 0;
123} 124}
124 125
125/* 126/*
@@ -261,30 +262,34 @@ static void nfs_msync_inode(struct inode *inode)
261/* 262/*
262 * Basic procedure for returning a delegation to the server 263 * Basic procedure for returning a delegation to the server
263 */ 264 */
264static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation) 265static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
265{ 266{
266 struct nfs_inode *nfsi = NFS_I(inode); 267 struct nfs_inode *nfsi = NFS_I(inode);
268 int err;
267 269
268 nfs_msync_inode(inode);
269 /* 270 /*
270 * Guard against new delegated open/lock/unlock calls and against 271 * Guard against new delegated open/lock/unlock calls and against
271 * state recovery 272 * state recovery
272 */ 273 */
273 down_write(&nfsi->rwsem); 274 down_write(&nfsi->rwsem);
274 nfs_delegation_claim_opens(inode, &delegation->stateid); 275 err = nfs_delegation_claim_opens(inode, &delegation->stateid);
275 up_write(&nfsi->rwsem); 276 up_write(&nfsi->rwsem);
276 nfs_msync_inode(inode); 277 if (err)
278 goto out;
277 279
278 return nfs_do_return_delegation(inode, delegation, 1); 280 err = nfs_do_return_delegation(inode, delegation, issync);
281out:
282 return err;
279} 283}
280 284
281/* 285/*
282 * Return all delegations that have been marked for return 286 * Return all delegations that have been marked for return
283 */ 287 */
284void nfs_client_return_marked_delegations(struct nfs_client *clp) 288int nfs_client_return_marked_delegations(struct nfs_client *clp)
285{ 289{
286 struct nfs_delegation *delegation; 290 struct nfs_delegation *delegation;
287 struct inode *inode; 291 struct inode *inode;
292 int err = 0;
288 293
289restart: 294restart:
290 rcu_read_lock(); 295 rcu_read_lock();
@@ -298,12 +303,18 @@ restart:
298 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); 303 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
299 spin_unlock(&clp->cl_lock); 304 spin_unlock(&clp->cl_lock);
300 rcu_read_unlock(); 305 rcu_read_unlock();
301 if (delegation != NULL) 306 if (delegation != NULL) {
302 __nfs_inode_return_delegation(inode, delegation); 307 filemap_flush(inode->i_mapping);
308 err = __nfs_inode_return_delegation(inode, delegation, 0);
309 }
303 iput(inode); 310 iput(inode);
304 goto restart; 311 if (!err)
312 goto restart;
313 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
314 return err;
305 } 315 }
306 rcu_read_unlock(); 316 rcu_read_unlock();
317 return 0;
307} 318}
308 319
309/* 320/*
@@ -338,8 +349,10 @@ int nfs_inode_return_delegation(struct inode *inode)
338 spin_lock(&clp->cl_lock); 349 spin_lock(&clp->cl_lock);
339 delegation = nfs_detach_delegation_locked(nfsi, NULL); 350 delegation = nfs_detach_delegation_locked(nfsi, NULL);
340 spin_unlock(&clp->cl_lock); 351 spin_unlock(&clp->cl_lock);
341 if (delegation != NULL) 352 if (delegation != NULL) {
342 err = __nfs_inode_return_delegation(inode, delegation); 353 nfs_msync_inode(inode);
354 err = __nfs_inode_return_delegation(inode, delegation, 1);
355 }
343 } 356 }
344 return err; 357 return err;
345} 358}
@@ -368,33 +381,47 @@ void nfs_super_return_all_delegations(struct super_block *sb)
368 spin_unlock(&delegation->lock); 381 spin_unlock(&delegation->lock);
369 } 382 }
370 rcu_read_unlock(); 383 rcu_read_unlock();
371 nfs_client_return_marked_delegations(clp); 384 if (nfs_client_return_marked_delegations(clp) != 0)
385 nfs4_schedule_state_manager(clp);
372} 386}
373 387
374static void nfs_client_mark_return_all_delegations(struct nfs_client *clp) 388static
389void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp, fmode_t flags)
375{ 390{
376 struct nfs_delegation *delegation; 391 struct nfs_delegation *delegation;
377 392
378 rcu_read_lock(); 393 rcu_read_lock();
379 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 394 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
380 set_bit(NFS_DELEGATION_RETURN, &delegation->flags); 395 if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
381 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state); 396 continue;
397 if (delegation->type & flags)
398 nfs_mark_return_delegation(clp, delegation);
382 } 399 }
383 rcu_read_unlock(); 400 rcu_read_unlock();
384} 401}
385 402
403static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
404{
405 nfs_client_mark_return_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
406}
407
386static void nfs_delegation_run_state_manager(struct nfs_client *clp) 408static void nfs_delegation_run_state_manager(struct nfs_client *clp)
387{ 409{
388 if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) 410 if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
389 nfs4_schedule_state_manager(clp); 411 nfs4_schedule_state_manager(clp);
390} 412}
391 413
392void nfs_expire_all_delegations(struct nfs_client *clp) 414void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags)
393{ 415{
394 nfs_client_mark_return_all_delegations(clp); 416 nfs_client_mark_return_all_delegation_types(clp, flags);
395 nfs_delegation_run_state_manager(clp); 417 nfs_delegation_run_state_manager(clp);
396} 418}
397 419
420void nfs_expire_all_delegations(struct nfs_client *clp)
421{
422 nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
423}
424
398/* 425/*
399 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error. 426 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
400 */ 427 */
@@ -413,8 +440,7 @@ static void nfs_client_mark_return_unreferenced_delegations(struct nfs_client *c
413 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 440 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
414 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags)) 441 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
415 continue; 442 continue;
416 set_bit(NFS_DELEGATION_RETURN, &delegation->flags); 443 nfs_mark_return_delegation(clp, delegation);
417 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
418 } 444 }
419 rcu_read_unlock(); 445 rcu_read_unlock();
420} 446}
@@ -428,18 +454,21 @@ void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
428/* 454/*
429 * Asynchronous delegation recall! 455 * Asynchronous delegation recall!
430 */ 456 */
431int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid) 457int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid,
458 int (*validate_stateid)(struct nfs_delegation *delegation,
459 const nfs4_stateid *stateid))
432{ 460{
433 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 461 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
434 struct nfs_delegation *delegation; 462 struct nfs_delegation *delegation;
435 463
436 rcu_read_lock(); 464 rcu_read_lock();
437 delegation = rcu_dereference(NFS_I(inode)->delegation); 465 delegation = rcu_dereference(NFS_I(inode)->delegation);
438 if (delegation == NULL || memcmp(delegation->stateid.data, stateid->data, 466
439 sizeof(delegation->stateid.data)) != 0) { 467 if (!validate_stateid(delegation, stateid)) {
440 rcu_read_unlock(); 468 rcu_read_unlock();
441 return -ENOENT; 469 return -ENOENT;
442 } 470 }
471
443 nfs_mark_return_delegation(clp, delegation); 472 nfs_mark_return_delegation(clp, delegation);
444 rcu_read_unlock(); 473 rcu_read_unlock();
445 nfs_delegation_run_state_manager(clp); 474 nfs_delegation_run_state_manager(clp);
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 09f383795174..944b627ec6e1 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -34,15 +34,18 @@ enum {
34int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); 34int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
35void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); 35void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
36int nfs_inode_return_delegation(struct inode *inode); 36int nfs_inode_return_delegation(struct inode *inode);
37int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid); 37int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid,
38 int (*validate_stateid)(struct nfs_delegation *delegation,
39 const nfs4_stateid *stateid));
38void nfs_inode_return_delegation_noreclaim(struct inode *inode); 40void nfs_inode_return_delegation_noreclaim(struct inode *inode);
39 41
40struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle); 42struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
41void nfs_super_return_all_delegations(struct super_block *sb); 43void nfs_super_return_all_delegations(struct super_block *sb);
42void nfs_expire_all_delegations(struct nfs_client *clp); 44void nfs_expire_all_delegations(struct nfs_client *clp);
45void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags);
43void nfs_expire_unreferenced_delegations(struct nfs_client *clp); 46void nfs_expire_unreferenced_delegations(struct nfs_client *clp);
44void nfs_handle_cb_pathdown(struct nfs_client *clp); 47void nfs_handle_cb_pathdown(struct nfs_client *clp);
45void nfs_client_return_marked_delegations(struct nfs_client *clp); 48int nfs_client_return_marked_delegations(struct nfs_client *clp);
46 49
47void nfs_delegation_mark_reclaim(struct nfs_client *clp); 50void nfs_delegation_mark_reclaim(struct nfs_client *clp);
48void nfs_delegation_reap_unclaimed(struct nfs_client *clp); 51void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 32062c33c859..2c5ace4f00a7 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1536,6 +1536,8 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
1536 old_dentry->d_parent->d_name.name, old_dentry->d_name.name, 1536 old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
1537 dentry->d_parent->d_name.name, dentry->d_name.name); 1537 dentry->d_parent->d_name.name, dentry->d_name.name);
1538 1538
1539 nfs_inode_return_delegation(inode);
1540
1539 d_drop(dentry); 1541 d_drop(dentry);
1540 error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); 1542 error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
1541 if (error == 0) { 1543 if (error == 0) {
@@ -1577,55 +1579,46 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1577 struct dentry *dentry = NULL, *rehash = NULL; 1579 struct dentry *dentry = NULL, *rehash = NULL;
1578 int error = -EBUSY; 1580 int error = -EBUSY;
1579 1581
1580 /*
1581 * To prevent any new references to the target during the rename,
1582 * we unhash the dentry and free the inode in advance.
1583 */
1584 if (!d_unhashed(new_dentry)) {
1585 d_drop(new_dentry);
1586 rehash = new_dentry;
1587 }
1588
1589 dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n", 1582 dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n",
1590 old_dentry->d_parent->d_name.name, old_dentry->d_name.name, 1583 old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
1591 new_dentry->d_parent->d_name.name, new_dentry->d_name.name, 1584 new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
1592 atomic_read(&new_dentry->d_count)); 1585 atomic_read(&new_dentry->d_count));
1593 1586
1594 /* 1587 /*
1595 * First check whether the target is busy ... we can't 1588 * For non-directories, check whether the target is busy and if so,
1596 * safely do _any_ rename if the target is in use. 1589 * make a copy of the dentry and then do a silly-rename. If the
1597 * 1590 * silly-rename succeeds, the copied dentry is hashed and becomes
1598 * For files, make a copy of the dentry and then do a 1591 * the new target.
1599 * silly-rename. If the silly-rename succeeds, the
1600 * copied dentry is hashed and becomes the new target.
1601 */ 1592 */
1602 if (!new_inode) 1593 if (new_inode && !S_ISDIR(new_inode->i_mode)) {
1603 goto go_ahead; 1594 /*
1604 if (S_ISDIR(new_inode->i_mode)) { 1595 * To prevent any new references to the target during the
1605 error = -EISDIR; 1596 * rename, we unhash the dentry in advance.
1606 if (!S_ISDIR(old_inode->i_mode)) 1597 */
1607 goto out; 1598 if (!d_unhashed(new_dentry)) {
1608 } else if (atomic_read(&new_dentry->d_count) > 2) { 1599 d_drop(new_dentry);
1609 int err; 1600 rehash = new_dentry;
1610 /* copy the target dentry's name */ 1601 }
1611 dentry = d_alloc(new_dentry->d_parent, 1602
1612 &new_dentry->d_name); 1603 if (atomic_read(&new_dentry->d_count) > 2) {
1613 if (!dentry) 1604 int err;
1614 goto out; 1605
1606 /* copy the target dentry's name */
1607 dentry = d_alloc(new_dentry->d_parent,
1608 &new_dentry->d_name);
1609 if (!dentry)
1610 goto out;
1615 1611
1616 /* silly-rename the existing target ... */ 1612 /* silly-rename the existing target ... */
1617 err = nfs_sillyrename(new_dir, new_dentry); 1613 err = nfs_sillyrename(new_dir, new_dentry);
1618 if (!err) { 1614 if (err)
1619 new_dentry = rehash = dentry; 1615 goto out;
1616
1617 new_dentry = dentry;
1620 new_inode = NULL; 1618 new_inode = NULL;
1621 /* instantiate the replacement target */ 1619 }
1622 d_instantiate(new_dentry, NULL);
1623 } else if (atomic_read(&new_dentry->d_count) > 1)
1624 /* dentry still busy? */
1625 goto out;
1626 } 1620 }
1627 1621
1628go_ahead:
1629 /* 1622 /*
1630 * ... prune child dentries and writebacks if needed. 1623 * ... prune child dentries and writebacks if needed.
1631 */ 1624 */
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 6c3210099d51..e1d415e97849 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -457,6 +457,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
457 }; 457 };
458 struct rpc_task_setup task_setup_data = { 458 struct rpc_task_setup task_setup_data = {
459 .rpc_client = NFS_CLIENT(inode), 459 .rpc_client = NFS_CLIENT(inode),
460 .rpc_message = &msg,
460 .callback_ops = &nfs_write_direct_ops, 461 .callback_ops = &nfs_write_direct_ops,
461 .workqueue = nfsiod_workqueue, 462 .workqueue = nfsiod_workqueue,
462 .flags = RPC_TASK_ASYNC, 463 .flags = RPC_TASK_ASYNC,
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index f4d54ba97cc6..95e1ca765d47 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -146,7 +146,7 @@ static int nfs_dns_show(struct seq_file *m, struct cache_detail *cd,
146 return 0; 146 return 0;
147} 147}
148 148
149struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd, 149static struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd,
150 struct nfs_dns_ent *key) 150 struct nfs_dns_ent *key)
151{ 151{
152 struct cache_head *ch; 152 struct cache_head *ch;
@@ -159,7 +159,7 @@ struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd,
159 return container_of(ch, struct nfs_dns_ent, h); 159 return container_of(ch, struct nfs_dns_ent, h);
160} 160}
161 161
162struct nfs_dns_ent *nfs_dns_update(struct cache_detail *cd, 162static struct nfs_dns_ent *nfs_dns_update(struct cache_detail *cd,
163 struct nfs_dns_ent *new, 163 struct nfs_dns_ent *new,
164 struct nfs_dns_ent *key) 164 struct nfs_dns_ent *key)
165{ 165{
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index f5fdd39e037a..6b891328f332 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -581,7 +581,7 @@ static int nfs_need_sync_write(struct file *filp, struct inode *inode)
581{ 581{
582 struct nfs_open_context *ctx; 582 struct nfs_open_context *ctx;
583 583
584 if (IS_SYNC(inode) || (filp->f_flags & O_SYNC)) 584 if (IS_SYNC(inode) || (filp->f_flags & O_DSYNC))
585 return 1; 585 return 1;
586 ctx = nfs_file_open_context(filp); 586 ctx = nfs_file_open_context(filp);
587 if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) 587 if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags))
@@ -622,7 +622,7 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
622 622
623 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); 623 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
624 result = generic_file_aio_write(iocb, iov, nr_segs, pos); 624 result = generic_file_aio_write(iocb, iov, nr_segs, pos);
625 /* Return error values for O_SYNC and IS_SYNC() */ 625 /* Return error values for O_DSYNC and IS_SYNC() */
626 if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) { 626 if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
627 int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode); 627 int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode);
628 if (err < 0) 628 if (err < 0)
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
index 70fad69eb959..fa588006588d 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -359,17 +359,13 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp)
359 359
360 BUG_ON(!cookie); 360 BUG_ON(!cookie);
361 361
362 if (fscache_check_page_write(cookie, page)) {
363 if (!(gfp & __GFP_WAIT))
364 return 0;
365 fscache_wait_on_page_write(cookie, page);
366 }
367
368 if (PageFsCache(page)) { 362 if (PageFsCache(page)) {
369 dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", 363 dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
370 cookie, page, nfsi); 364 cookie, page, nfsi);
371 365
372 fscache_uncache_page(cookie, page); 366 if (!fscache_maybe_release_page(cookie, page, gfp))
367 return 0;
368
373 nfs_add_fscache_stats(page->mapping->host, 369 nfs_add_fscache_stats(page->mapping->host,
374 NFSIOS_FSCACHE_PAGES_UNCACHED, 1); 370 NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
375 } 371 }
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index e21b1bb9972f..29e464d23b32 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -30,6 +30,15 @@ static inline int nfs4_has_session(const struct nfs_client *clp)
30 return 0; 30 return 0;
31} 31}
32 32
33static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
34{
35#ifdef CONFIG_NFS_V4_1
36 if (nfs4_has_session(clp))
37 return (clp->cl_session->flags & SESSION4_PERSIST);
38#endif /* CONFIG_NFS_V4_1 */
39 return 0;
40}
41
33struct nfs_clone_mount { 42struct nfs_clone_mount {
34 const struct super_block *sb; 43 const struct super_block *sb;
35 const struct dentry *dentry; 44 const struct dentry *dentry;
@@ -156,6 +165,7 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr
156 165
157/* callback_xdr.c */ 166/* callback_xdr.c */
158extern struct svc_version nfs4_callback_version1; 167extern struct svc_version nfs4_callback_version1;
168extern struct svc_version nfs4_callback_version4;
159 169
160/* pagelist.c */ 170/* pagelist.c */
161extern int __init nfs_init_nfspagecache(void); 171extern int __init nfs_init_nfspagecache(void);
@@ -177,24 +187,14 @@ extern __be32 * nfs_decode_dirent(__be32 *, struct nfs_entry *, int);
177extern struct rpc_procinfo nfs3_procedures[]; 187extern struct rpc_procinfo nfs3_procedures[];
178extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int); 188extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int);
179 189
180/* nfs4proc.c */
181static inline void nfs4_restart_rpc(struct rpc_task *task,
182 const struct nfs_client *clp)
183{
184#ifdef CONFIG_NFS_V4_1
185 if (nfs4_has_session(clp) &&
186 test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) {
187 rpc_restart_call_prepare(task);
188 return;
189 }
190#endif /* CONFIG_NFS_V4_1 */
191 rpc_restart_call(task);
192}
193
194/* nfs4xdr.c */ 190/* nfs4xdr.c */
195#ifdef CONFIG_NFS_V4 191#ifdef CONFIG_NFS_V4
196extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus); 192extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
197#endif 193#endif
194#ifdef CONFIG_NFS_V4_1
195extern const u32 nfs41_maxread_overhead;
196extern const u32 nfs41_maxwrite_overhead;
197#endif
198 198
199/* nfs4proc.c */ 199/* nfs4proc.c */
200#ifdef CONFIG_NFS_V4 200#ifdef CONFIG_NFS_V4
@@ -273,20 +273,6 @@ extern int _nfs4_call_sync_session(struct nfs_server *server,
273 struct nfs4_sequence_res *res, 273 struct nfs4_sequence_res *res,
274 int cache_reply); 274 int cache_reply);
275 275
276#ifdef CONFIG_NFS_V4_1
277extern void nfs41_sequence_free_slot(const struct nfs_client *,
278 struct nfs4_sequence_res *res);
279#endif /* CONFIG_NFS_V4_1 */
280
281static inline void nfs4_sequence_free_slot(const struct nfs_client *clp,
282 struct nfs4_sequence_res *res)
283{
284#ifdef CONFIG_NFS_V4_1
285 if (nfs4_has_session(clp))
286 nfs41_sequence_free_slot(clp, res);
287#endif /* CONFIG_NFS_V4_1 */
288}
289
290/* 276/*
291 * Determine the device name as a string 277 * Determine the device name as a string
292 */ 278 */
@@ -380,3 +366,15 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len)
380 return ((unsigned long)len + (unsigned long)base + 366 return ((unsigned long)len + (unsigned long)base +
381 PAGE_SIZE - 1) >> PAGE_SHIFT; 367 PAGE_SIZE - 1) >> PAGE_SHIFT;
382} 368}
369
370/*
371 * Helper for restarting RPC calls in the possible presence of NFSv4.1
372 * sessions.
373 */
374static inline void nfs_restart_rpc(struct rpc_task *task, const struct nfs_client *clp)
375{
376 if (nfs4_has_session(clp))
377 rpc_restart_call_prepare(task);
378 else
379 rpc_restart_call(task);
380}
diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h
index ceda50aad73c..46d779abafd3 100644
--- a/fs/nfs/iostat.h
+++ b/fs/nfs/iostat.h
@@ -25,13 +25,7 @@ struct nfs_iostats {
25static inline void nfs_inc_server_stats(const struct nfs_server *server, 25static inline void nfs_inc_server_stats(const struct nfs_server *server,
26 enum nfs_stat_eventcounters stat) 26 enum nfs_stat_eventcounters stat)
27{ 27{
28 struct nfs_iostats *iostats; 28 this_cpu_inc(server->io_stats->events[stat]);
29 int cpu;
30
31 cpu = get_cpu();
32 iostats = per_cpu_ptr(server->io_stats, cpu);
33 iostats->events[stat]++;
34 put_cpu();
35} 29}
36 30
37static inline void nfs_inc_stats(const struct inode *inode, 31static inline void nfs_inc_stats(const struct inode *inode,
@@ -44,13 +38,7 @@ static inline void nfs_add_server_stats(const struct nfs_server *server,
44 enum nfs_stat_bytecounters stat, 38 enum nfs_stat_bytecounters stat,
45 unsigned long addend) 39 unsigned long addend)
46{ 40{
47 struct nfs_iostats *iostats; 41 this_cpu_add(server->io_stats->bytes[stat], addend);
48 int cpu;
49
50 cpu = get_cpu();
51 iostats = per_cpu_ptr(server->io_stats, cpu);
52 iostats->bytes[stat] += addend;
53 put_cpu();
54} 42}
55 43
56static inline void nfs_add_stats(const struct inode *inode, 44static inline void nfs_add_stats(const struct inode *inode,
@@ -65,13 +53,7 @@ static inline void nfs_add_fscache_stats(struct inode *inode,
65 enum nfs_stat_fscachecounters stat, 53 enum nfs_stat_fscachecounters stat,
66 unsigned long addend) 54 unsigned long addend)
67{ 55{
68 struct nfs_iostats *iostats; 56 this_cpu_add(NFS_SERVER(inode)->io_stats->fscache[stat], addend);
69 int cpu;
70
71 cpu = get_cpu();
72 iostats = per_cpu_ptr(NFS_SERVER(inode)->io_stats, cpu);
73 iostats->fscache[stat] += addend;
74 put_cpu();
75} 57}
76#endif 58#endif
77 59
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 6ea07a3c75d4..865265bdca03 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -44,7 +44,8 @@ enum nfs4_client_state {
44 NFS4CLNT_RECLAIM_REBOOT, 44 NFS4CLNT_RECLAIM_REBOOT,
45 NFS4CLNT_RECLAIM_NOGRACE, 45 NFS4CLNT_RECLAIM_NOGRACE,
46 NFS4CLNT_DELEGRETURN, 46 NFS4CLNT_DELEGRETURN,
47 NFS4CLNT_SESSION_SETUP, 47 NFS4CLNT_SESSION_RESET,
48 NFS4CLNT_SESSION_DRAINING,
48}; 49};
49 50
50/* 51/*
@@ -107,6 +108,10 @@ enum {
107 NFS_OWNER_RECLAIM_NOGRACE 108 NFS_OWNER_RECLAIM_NOGRACE
108}; 109};
109 110
111#define NFS_LOCK_NEW 0
112#define NFS_LOCK_RECLAIM 1
113#define NFS_LOCK_EXPIRED 2
114
110/* 115/*
111 * struct nfs4_state maintains the client-side state for a given 116 * struct nfs4_state maintains the client-side state for a given
112 * (state_owner,inode) tuple (OPEN) or state_owner (LOCK). 117 * (state_owner,inode) tuple (OPEN) or state_owner (LOCK).
@@ -180,6 +185,7 @@ struct nfs4_state_recovery_ops {
180 int (*recover_lock)(struct nfs4_state *, struct file_lock *); 185 int (*recover_lock)(struct nfs4_state *, struct file_lock *);
181 int (*establish_clid)(struct nfs_client *, struct rpc_cred *); 186 int (*establish_clid)(struct nfs_client *, struct rpc_cred *);
182 struct rpc_cred * (*get_clid_cred)(struct nfs_client *); 187 struct rpc_cred * (*get_clid_cred)(struct nfs_client *);
188 int (*reclaim_complete)(struct nfs_client *);
183}; 189};
184 190
185struct nfs4_state_maintenance_ops { 191struct nfs4_state_maintenance_ops {
@@ -200,9 +206,11 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
200/* nfs4proc.c */ 206/* nfs4proc.c */
201extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *); 207extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *);
202extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); 208extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
209extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
203extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); 210extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
204extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); 211extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
205extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *); 212extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
213extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
206extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait); 214extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait);
207extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); 215extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
208extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); 216extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
@@ -218,9 +226,11 @@ extern int nfs4_setup_sequence(struct nfs_client *clp,
218 int cache_reply, struct rpc_task *task); 226 int cache_reply, struct rpc_task *task);
219extern void nfs4_destroy_session(struct nfs4_session *session); 227extern void nfs4_destroy_session(struct nfs4_session *session);
220extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp); 228extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
221extern int nfs4_proc_create_session(struct nfs_client *, int reset); 229extern int nfs4_proc_create_session(struct nfs_client *);
222extern int nfs4_proc_destroy_session(struct nfs4_session *); 230extern int nfs4_proc_destroy_session(struct nfs4_session *);
223extern int nfs4_init_session(struct nfs_server *server); 231extern int nfs4_init_session(struct nfs_server *server);
232extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
233 struct nfs_fsinfo *fsinfo);
224#else /* CONFIG_NFS_v4_1 */ 234#else /* CONFIG_NFS_v4_1 */
225static inline int nfs4_setup_sequence(struct nfs_client *clp, 235static inline int nfs4_setup_sequence(struct nfs_client *clp,
226 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, 236 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
@@ -267,6 +277,7 @@ extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
267extern void nfs4_schedule_state_recovery(struct nfs_client *); 277extern void nfs4_schedule_state_recovery(struct nfs_client *);
268extern void nfs4_schedule_state_manager(struct nfs_client *); 278extern void nfs4_schedule_state_manager(struct nfs_client *);
269extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state); 279extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state);
280extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
270extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); 281extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
271extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); 282extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
272extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); 283extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
@@ -275,6 +286,7 @@ extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter);
275extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task); 286extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
276extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid); 287extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
277extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid); 288extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
289extern void nfs_release_seqid(struct nfs_seqid *seqid);
278extern void nfs_free_seqid(struct nfs_seqid *seqid); 290extern void nfs_free_seqid(struct nfs_seqid *seqid);
279 291
280extern const nfs4_stateid zero_stateid; 292extern const nfs4_stateid zero_stateid;
@@ -287,6 +299,7 @@ struct nfs4_mount_data;
287 299
288/* callback_xdr.c */ 300/* callback_xdr.c */
289extern struct svc_version nfs4_callback_version1; 301extern struct svc_version nfs4_callback_version1;
302extern struct svc_version nfs4_callback_version4;
290 303
291#else 304#else
292 305
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ed7c269e2514..198d51d17c13 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -64,6 +64,7 @@
64 64
65struct nfs4_opendata; 65struct nfs4_opendata;
66static int _nfs4_proc_open(struct nfs4_opendata *data); 66static int _nfs4_proc_open(struct nfs4_opendata *data);
67static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
67static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 68static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
68static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); 69static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
69static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 70static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
@@ -72,12 +73,17 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
72/* Prevent leaks of NFSv4 errors into userland */ 73/* Prevent leaks of NFSv4 errors into userland */
73static int nfs4_map_errors(int err) 74static int nfs4_map_errors(int err)
74{ 75{
75 if (err < -1000) { 76 if (err >= -1000)
77 return err;
78 switch (err) {
79 case -NFS4ERR_RESOURCE:
80 return -EREMOTEIO;
81 default:
76 dprintk("%s could not handle NFSv4 error %d\n", 82 dprintk("%s could not handle NFSv4 error %d\n",
77 __func__, -err); 83 __func__, -err);
78 return -EIO; 84 break;
79 } 85 }
80 return err; 86 return -EIO;
81} 87}
82 88
83/* 89/*
@@ -265,11 +271,18 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
265 case -NFS4ERR_SEQ_MISORDERED: 271 case -NFS4ERR_SEQ_MISORDERED:
266 dprintk("%s ERROR: %d Reset session\n", __func__, 272 dprintk("%s ERROR: %d Reset session\n", __func__,
267 errorcode); 273 errorcode);
268 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); 274 nfs4_schedule_state_recovery(clp);
269 exception->retry = 1; 275 exception->retry = 1;
270 /* FALLTHROUGH */ 276 break;
271#endif /* !defined(CONFIG_NFS_V4_1) */ 277#endif /* !defined(CONFIG_NFS_V4_1) */
272 case -NFS4ERR_FILE_OPEN: 278 case -NFS4ERR_FILE_OPEN:
279 if (exception->timeout > HZ) {
280 /* We have retried a decent amount, time to
281 * fail
282 */
283 ret = -EBUSY;
284 break;
285 }
273 case -NFS4ERR_GRACE: 286 case -NFS4ERR_GRACE:
274 case -NFS4ERR_DELAY: 287 case -NFS4ERR_DELAY:
275 ret = nfs4_delay(server->client, &exception->timeout); 288 ret = nfs4_delay(server->client, &exception->timeout);
@@ -306,48 +319,67 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
306 * so we need to scan down from highest_used_slotid to 0 looking for the now 319 * so we need to scan down from highest_used_slotid to 0 looking for the now
307 * highest slotid in use. 320 * highest slotid in use.
308 * If none found, highest_used_slotid is set to -1. 321 * If none found, highest_used_slotid is set to -1.
322 *
323 * Must be called while holding tbl->slot_tbl_lock
309 */ 324 */
310static void 325static void
311nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) 326nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
312{ 327{
313 int slotid = free_slotid; 328 int slotid = free_slotid;
314 329
315 spin_lock(&tbl->slot_tbl_lock);
316 /* clear used bit in bitmap */ 330 /* clear used bit in bitmap */
317 __clear_bit(slotid, tbl->used_slots); 331 __clear_bit(slotid, tbl->used_slots);
318 332
319 /* update highest_used_slotid when it is freed */ 333 /* update highest_used_slotid when it is freed */
320 if (slotid == tbl->highest_used_slotid) { 334 if (slotid == tbl->highest_used_slotid) {
321 slotid = find_last_bit(tbl->used_slots, tbl->max_slots); 335 slotid = find_last_bit(tbl->used_slots, tbl->max_slots);
322 if (slotid >= 0 && slotid < tbl->max_slots) 336 if (slotid < tbl->max_slots)
323 tbl->highest_used_slotid = slotid; 337 tbl->highest_used_slotid = slotid;
324 else 338 else
325 tbl->highest_used_slotid = -1; 339 tbl->highest_used_slotid = -1;
326 } 340 }
327 rpc_wake_up_next(&tbl->slot_tbl_waitq);
328 spin_unlock(&tbl->slot_tbl_lock);
329 dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__, 341 dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__,
330 free_slotid, tbl->highest_used_slotid); 342 free_slotid, tbl->highest_used_slotid);
331} 343}
332 344
333void nfs41_sequence_free_slot(const struct nfs_client *clp, 345/*
334 struct nfs4_sequence_res *res) 346 * Signal state manager thread if session is drained
347 */
348static void nfs41_check_drain_session_complete(struct nfs4_session *ses)
335{ 349{
336 struct nfs4_slot_table *tbl; 350 struct rpc_task *task;
337 351
338 if (!nfs4_has_session(clp)) { 352 if (!test_bit(NFS4CLNT_SESSION_DRAINING, &ses->clp->cl_state)) {
339 dprintk("%s: No session\n", __func__); 353 task = rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq);
354 if (task)
355 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
340 return; 356 return;
341 } 357 }
358
359 if (ses->fc_slot_table.highest_used_slotid != -1)
360 return;
361
362 dprintk("%s COMPLETE: Session Drained\n", __func__);
363 complete(&ses->complete);
364}
365
366static void nfs41_sequence_free_slot(const struct nfs_client *clp,
367 struct nfs4_sequence_res *res)
368{
369 struct nfs4_slot_table *tbl;
370
342 tbl = &clp->cl_session->fc_slot_table; 371 tbl = &clp->cl_session->fc_slot_table;
343 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) { 372 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) {
344 dprintk("%s: No slot\n", __func__);
345 /* just wake up the next guy waiting since 373 /* just wake up the next guy waiting since
346 * we may have not consumed a slot after all */ 374 * we may have not consumed a slot after all */
347 rpc_wake_up_next(&tbl->slot_tbl_waitq); 375 dprintk("%s: No slot\n", __func__);
348 return; 376 return;
349 } 377 }
378
379 spin_lock(&tbl->slot_tbl_lock);
350 nfs4_free_slot(tbl, res->sr_slotid); 380 nfs4_free_slot(tbl, res->sr_slotid);
381 nfs41_check_drain_session_complete(clp->cl_session);
382 spin_unlock(&tbl->slot_tbl_lock);
351 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 383 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
352} 384}
353 385
@@ -372,10 +404,10 @@ static void nfs41_sequence_done(struct nfs_client *clp,
372 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) 404 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE)
373 goto out; 405 goto out;
374 406
375 tbl = &clp->cl_session->fc_slot_table; 407 /* Check the SEQUENCE operation status */
376 slot = tbl->slots + res->sr_slotid;
377
378 if (res->sr_status == 0) { 408 if (res->sr_status == 0) {
409 tbl = &clp->cl_session->fc_slot_table;
410 slot = tbl->slots + res->sr_slotid;
379 /* Update the slot's sequence and clientid lease timer */ 411 /* Update the slot's sequence and clientid lease timer */
380 ++slot->seq_nr; 412 ++slot->seq_nr;
381 timestamp = res->sr_renewal_time; 413 timestamp = res->sr_renewal_time;
@@ -383,7 +415,8 @@ static void nfs41_sequence_done(struct nfs_client *clp,
383 if (time_before(clp->cl_last_renewal, timestamp)) 415 if (time_before(clp->cl_last_renewal, timestamp))
384 clp->cl_last_renewal = timestamp; 416 clp->cl_last_renewal = timestamp;
385 spin_unlock(&clp->cl_lock); 417 spin_unlock(&clp->cl_lock);
386 return; 418 /* Check sequence flags */
419 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags);
387 } 420 }
388out: 421out:
389 /* The session may be reset by one of the error handlers. */ 422 /* The session may be reset by one of the error handlers. */
@@ -402,7 +435,7 @@ out:
402 * Note: must be called with under the slot_tbl_lock. 435 * Note: must be called with under the slot_tbl_lock.
403 */ 436 */
404static u8 437static u8
405nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task) 438nfs4_find_slot(struct nfs4_slot_table *tbl)
406{ 439{
407 int slotid; 440 int slotid;
408 u8 ret_id = NFS4_MAX_SLOT_TABLE; 441 u8 ret_id = NFS4_MAX_SLOT_TABLE;
@@ -424,24 +457,6 @@ out:
424 return ret_id; 457 return ret_id;
425} 458}
426 459
427static int nfs4_recover_session(struct nfs4_session *session)
428{
429 struct nfs_client *clp = session->clp;
430 unsigned int loop;
431 int ret;
432
433 for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
434 ret = nfs4_wait_clnt_recover(clp);
435 if (ret != 0)
436 break;
437 if (!test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
438 break;
439 nfs4_schedule_state_manager(clp);
440 ret = -EIO;
441 }
442 return ret;
443}
444
445static int nfs41_setup_sequence(struct nfs4_session *session, 460static int nfs41_setup_sequence(struct nfs4_session *session,
446 struct nfs4_sequence_args *args, 461 struct nfs4_sequence_args *args,
447 struct nfs4_sequence_res *res, 462 struct nfs4_sequence_res *res,
@@ -450,7 +465,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
450{ 465{
451 struct nfs4_slot *slot; 466 struct nfs4_slot *slot;
452 struct nfs4_slot_table *tbl; 467 struct nfs4_slot_table *tbl;
453 int status = 0;
454 u8 slotid; 468 u8 slotid;
455 469
456 dprintk("--> %s\n", __func__); 470 dprintk("--> %s\n", __func__);
@@ -463,24 +477,27 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
463 tbl = &session->fc_slot_table; 477 tbl = &session->fc_slot_table;
464 478
465 spin_lock(&tbl->slot_tbl_lock); 479 spin_lock(&tbl->slot_tbl_lock);
466 if (test_bit(NFS4CLNT_SESSION_SETUP, &session->clp->cl_state)) { 480 if (test_bit(NFS4CLNT_SESSION_DRAINING, &session->clp->cl_state) &&
467 if (tbl->highest_used_slotid != -1) { 481 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
468 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 482 /*
469 spin_unlock(&tbl->slot_tbl_lock); 483 * The state manager will wait until the slot table is empty.
470 dprintk("<-- %s: Session reset: draining\n", __func__); 484 * Schedule the reset thread
471 return -EAGAIN; 485 */
472 } 486 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
487 spin_unlock(&tbl->slot_tbl_lock);
488 dprintk("%s Schedule Session Reset\n", __func__);
489 return -EAGAIN;
490 }
473 491
474 /* The slot table is empty; start the reset thread */ 492 if (!rpc_queue_empty(&tbl->slot_tbl_waitq) &&
475 dprintk("%s Session Reset\n", __func__); 493 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
494 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
476 spin_unlock(&tbl->slot_tbl_lock); 495 spin_unlock(&tbl->slot_tbl_lock);
477 status = nfs4_recover_session(session); 496 dprintk("%s enforce FIFO order\n", __func__);
478 if (status) 497 return -EAGAIN;
479 return status;
480 spin_lock(&tbl->slot_tbl_lock);
481 } 498 }
482 499
483 slotid = nfs4_find_slot(tbl, task); 500 slotid = nfs4_find_slot(tbl);
484 if (slotid == NFS4_MAX_SLOT_TABLE) { 501 if (slotid == NFS4_MAX_SLOT_TABLE) {
485 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 502 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
486 spin_unlock(&tbl->slot_tbl_lock); 503 spin_unlock(&tbl->slot_tbl_lock);
@@ -489,6 +506,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
489 } 506 }
490 spin_unlock(&tbl->slot_tbl_lock); 507 spin_unlock(&tbl->slot_tbl_lock);
491 508
509 rpc_task_set_priority(task, RPC_PRIORITY_NORMAL);
492 slot = tbl->slots + slotid; 510 slot = tbl->slots + slotid;
493 args->sa_session = session; 511 args->sa_session = session;
494 args->sa_slotid = slotid; 512 args->sa_slotid = slotid;
@@ -522,7 +540,7 @@ int nfs4_setup_sequence(struct nfs_client *clp,
522 goto out; 540 goto out;
523 ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply, 541 ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply,
524 task); 542 task);
525 if (ret != -EAGAIN) { 543 if (ret && ret != -EAGAIN) {
526 /* terminate rpc task */ 544 /* terminate rpc task */
527 task->tk_status = ret; 545 task->tk_status = ret;
528 task->tk_action = NULL; 546 task->tk_action = NULL;
@@ -551,12 +569,17 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
551 rpc_call_start(task); 569 rpc_call_start(task);
552} 570}
553 571
572static void nfs41_call_priv_sync_prepare(struct rpc_task *task, void *calldata)
573{
574 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
575 nfs41_call_sync_prepare(task, calldata);
576}
577
554static void nfs41_call_sync_done(struct rpc_task *task, void *calldata) 578static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
555{ 579{
556 struct nfs41_call_sync_data *data = calldata; 580 struct nfs41_call_sync_data *data = calldata;
557 581
558 nfs41_sequence_done(data->clp, data->seq_res, task->tk_status); 582 nfs41_sequence_done(data->clp, data->seq_res, task->tk_status);
559 nfs41_sequence_free_slot(data->clp, data->seq_res);
560} 583}
561 584
562struct rpc_call_ops nfs41_call_sync_ops = { 585struct rpc_call_ops nfs41_call_sync_ops = {
@@ -564,12 +587,18 @@ struct rpc_call_ops nfs41_call_sync_ops = {
564 .rpc_call_done = nfs41_call_sync_done, 587 .rpc_call_done = nfs41_call_sync_done,
565}; 588};
566 589
590struct rpc_call_ops nfs41_call_priv_sync_ops = {
591 .rpc_call_prepare = nfs41_call_priv_sync_prepare,
592 .rpc_call_done = nfs41_call_sync_done,
593};
594
567static int nfs4_call_sync_sequence(struct nfs_client *clp, 595static int nfs4_call_sync_sequence(struct nfs_client *clp,
568 struct rpc_clnt *clnt, 596 struct rpc_clnt *clnt,
569 struct rpc_message *msg, 597 struct rpc_message *msg,
570 struct nfs4_sequence_args *args, 598 struct nfs4_sequence_args *args,
571 struct nfs4_sequence_res *res, 599 struct nfs4_sequence_res *res,
572 int cache_reply) 600 int cache_reply,
601 int privileged)
573{ 602{
574 int ret; 603 int ret;
575 struct rpc_task *task; 604 struct rpc_task *task;
@@ -587,6 +616,8 @@ static int nfs4_call_sync_sequence(struct nfs_client *clp,
587 }; 616 };
588 617
589 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 618 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
619 if (privileged)
620 task_setup.callback_ops = &nfs41_call_priv_sync_ops;
590 task = rpc_run_task(&task_setup); 621 task = rpc_run_task(&task_setup);
591 if (IS_ERR(task)) 622 if (IS_ERR(task))
592 ret = PTR_ERR(task); 623 ret = PTR_ERR(task);
@@ -604,7 +635,7 @@ int _nfs4_call_sync_session(struct nfs_server *server,
604 int cache_reply) 635 int cache_reply)
605{ 636{
606 return nfs4_call_sync_sequence(server->nfs_client, server->client, 637 return nfs4_call_sync_sequence(server->nfs_client, server->client,
607 msg, args, res, cache_reply); 638 msg, args, res, cache_reply, 0);
608} 639}
609 640
610#endif /* CONFIG_NFS_V4_1 */ 641#endif /* CONFIG_NFS_V4_1 */
@@ -632,15 +663,6 @@ static void nfs4_sequence_done(const struct nfs_server *server,
632#endif /* CONFIG_NFS_V4_1 */ 663#endif /* CONFIG_NFS_V4_1 */
633} 664}
634 665
635/* no restart, therefore free slot here */
636static void nfs4_sequence_done_free_slot(const struct nfs_server *server,
637 struct nfs4_sequence_res *res,
638 int rpc_status)
639{
640 nfs4_sequence_done(server, res, rpc_status);
641 nfs4_sequence_free_slot(server->nfs_client, res);
642}
643
644static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) 666static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
645{ 667{
646 struct nfs_inode *nfsi = NFS_I(dir); 668 struct nfs_inode *nfsi = NFS_I(dir);
@@ -715,9 +737,15 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
715 p->o_arg.bitmask = server->attr_bitmask; 737 p->o_arg.bitmask = server->attr_bitmask;
716 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 738 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
717 if (flags & O_EXCL) { 739 if (flags & O_EXCL) {
718 u32 *s = (u32 *) p->o_arg.u.verifier.data; 740 if (nfs4_has_persistent_session(server->nfs_client)) {
719 s[0] = jiffies; 741 /* GUARDED */
720 s[1] = current->pid; 742 p->o_arg.u.attrs = &p->attrs;
743 memcpy(&p->attrs, attrs, sizeof(p->attrs));
744 } else { /* EXCLUSIVE4_1 */
745 u32 *s = (u32 *) p->o_arg.u.verifier.data;
746 s[0] = jiffies;
747 s[1] = current->pid;
748 }
721 } else if (flags & O_CREAT) { 749 } else if (flags & O_CREAT) {
722 p->o_arg.u.attrs = &p->attrs; 750 p->o_arg.u.attrs = &p->attrs;
723 memcpy(&p->attrs, attrs, sizeof(p->attrs)); 751 memcpy(&p->attrs, attrs, sizeof(p->attrs));
@@ -771,13 +799,16 @@ static int can_open_cached(struct nfs4_state *state, fmode_t mode, int open_mode
771 goto out; 799 goto out;
772 switch (mode & (FMODE_READ|FMODE_WRITE)) { 800 switch (mode & (FMODE_READ|FMODE_WRITE)) {
773 case FMODE_READ: 801 case FMODE_READ:
774 ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0; 802 ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0
803 && state->n_rdonly != 0;
775 break; 804 break;
776 case FMODE_WRITE: 805 case FMODE_WRITE:
777 ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0; 806 ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0
807 && state->n_wronly != 0;
778 break; 808 break;
779 case FMODE_READ|FMODE_WRITE: 809 case FMODE_READ|FMODE_WRITE:
780 ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0; 810 ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0
811 && state->n_rdwr != 0;
781 } 812 }
782out: 813out:
783 return ret; 814 return ret;
@@ -1042,7 +1073,7 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, fmode_t fmod
1042 memset(&opendata->o_res, 0, sizeof(opendata->o_res)); 1073 memset(&opendata->o_res, 0, sizeof(opendata->o_res));
1043 memset(&opendata->c_res, 0, sizeof(opendata->c_res)); 1074 memset(&opendata->c_res, 0, sizeof(opendata->c_res));
1044 nfs4_init_opendata_res(opendata); 1075 nfs4_init_opendata_res(opendata);
1045 ret = _nfs4_proc_open(opendata); 1076 ret = _nfs4_recover_proc_open(opendata);
1046 if (ret != 0) 1077 if (ret != 0)
1047 return ret; 1078 return ret;
1048 newstate = nfs4_opendata_to_nfs4_state(opendata); 1079 newstate = nfs4_opendata_to_nfs4_state(opendata);
@@ -1178,6 +1209,14 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1178 case -ENOENT: 1209 case -ENOENT:
1179 case -ESTALE: 1210 case -ESTALE:
1180 goto out; 1211 goto out;
1212 case -NFS4ERR_BADSESSION:
1213 case -NFS4ERR_BADSLOT:
1214 case -NFS4ERR_BAD_HIGH_SLOT:
1215 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1216 case -NFS4ERR_DEADSESSION:
1217 nfs4_schedule_state_recovery(
1218 server->nfs_client);
1219 goto out;
1181 case -NFS4ERR_STALE_CLIENTID: 1220 case -NFS4ERR_STALE_CLIENTID:
1182 case -NFS4ERR_STALE_STATEID: 1221 case -NFS4ERR_STALE_STATEID:
1183 case -NFS4ERR_EXPIRED: 1222 case -NFS4ERR_EXPIRED:
@@ -1325,14 +1364,20 @@ out_no_action:
1325 1364
1326} 1365}
1327 1366
1367static void nfs4_recover_open_prepare(struct rpc_task *task, void *calldata)
1368{
1369 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
1370 nfs4_open_prepare(task, calldata);
1371}
1372
1328static void nfs4_open_done(struct rpc_task *task, void *calldata) 1373static void nfs4_open_done(struct rpc_task *task, void *calldata)
1329{ 1374{
1330 struct nfs4_opendata *data = calldata; 1375 struct nfs4_opendata *data = calldata;
1331 1376
1332 data->rpc_status = task->tk_status; 1377 data->rpc_status = task->tk_status;
1333 1378
1334 nfs4_sequence_done_free_slot(data->o_arg.server, &data->o_res.seq_res, 1379 nfs4_sequence_done(data->o_arg.server, &data->o_res.seq_res,
1335 task->tk_status); 1380 task->tk_status);
1336 1381
1337 if (RPC_ASSASSINATED(task)) 1382 if (RPC_ASSASSINATED(task))
1338 return; 1383 return;
@@ -1383,10 +1428,13 @@ static const struct rpc_call_ops nfs4_open_ops = {
1383 .rpc_release = nfs4_open_release, 1428 .rpc_release = nfs4_open_release,
1384}; 1429};
1385 1430
1386/* 1431static const struct rpc_call_ops nfs4_recover_open_ops = {
1387 * Note: On error, nfs4_proc_open will free the struct nfs4_opendata 1432 .rpc_call_prepare = nfs4_recover_open_prepare,
1388 */ 1433 .rpc_call_done = nfs4_open_done,
1389static int _nfs4_proc_open(struct nfs4_opendata *data) 1434 .rpc_release = nfs4_open_release,
1435};
1436
1437static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
1390{ 1438{
1391 struct inode *dir = data->dir->d_inode; 1439 struct inode *dir = data->dir->d_inode;
1392 struct nfs_server *server = NFS_SERVER(dir); 1440 struct nfs_server *server = NFS_SERVER(dir);
@@ -1413,21 +1461,57 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1413 data->rpc_done = 0; 1461 data->rpc_done = 0;
1414 data->rpc_status = 0; 1462 data->rpc_status = 0;
1415 data->cancelled = 0; 1463 data->cancelled = 0;
1464 if (isrecover)
1465 task_setup_data.callback_ops = &nfs4_recover_open_ops;
1416 task = rpc_run_task(&task_setup_data); 1466 task = rpc_run_task(&task_setup_data);
1417 if (IS_ERR(task)) 1467 if (IS_ERR(task))
1418 return PTR_ERR(task); 1468 return PTR_ERR(task);
1419 status = nfs4_wait_for_completion_rpc_task(task); 1469 status = nfs4_wait_for_completion_rpc_task(task);
1420 if (status != 0) { 1470 if (status != 0) {
1421 data->cancelled = 1; 1471 data->cancelled = 1;
1422 smp_wmb(); 1472 smp_wmb();
1423 } else 1473 } else
1424 status = data->rpc_status; 1474 status = data->rpc_status;
1425 rpc_put_task(task); 1475 rpc_put_task(task);
1476
1477 return status;
1478}
1479
1480static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
1481{
1482 struct inode *dir = data->dir->d_inode;
1483 struct nfs_openres *o_res = &data->o_res;
1484 int status;
1485
1486 status = nfs4_run_open_task(data, 1);
1426 if (status != 0 || !data->rpc_done) 1487 if (status != 0 || !data->rpc_done)
1427 return status; 1488 return status;
1428 1489
1429 if (o_res->fh.size == 0) 1490 nfs_refresh_inode(dir, o_res->dir_attr);
1430 _nfs4_proc_lookup(dir, o_arg->name, &o_res->fh, o_res->f_attr); 1491
1492 if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
1493 status = _nfs4_proc_open_confirm(data);
1494 if (status != 0)
1495 return status;
1496 }
1497
1498 return status;
1499}
1500
1501/*
1502 * Note: On error, nfs4_proc_open will free the struct nfs4_opendata
1503 */
1504static int _nfs4_proc_open(struct nfs4_opendata *data)
1505{
1506 struct inode *dir = data->dir->d_inode;
1507 struct nfs_server *server = NFS_SERVER(dir);
1508 struct nfs_openargs *o_arg = &data->o_arg;
1509 struct nfs_openres *o_res = &data->o_res;
1510 int status;
1511
1512 status = nfs4_run_open_task(data, 0);
1513 if (status != 0 || !data->rpc_done)
1514 return status;
1431 1515
1432 if (o_arg->open_flags & O_CREAT) { 1516 if (o_arg->open_flags & O_CREAT) {
1433 update_changeattr(dir, &o_res->cinfo); 1517 update_changeattr(dir, &o_res->cinfo);
@@ -1483,7 +1567,7 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
1483 return ret; 1567 return ret;
1484} 1568}
1485 1569
1486static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) 1570static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
1487{ 1571{
1488 struct nfs_server *server = NFS_SERVER(state->inode); 1572 struct nfs_server *server = NFS_SERVER(state->inode);
1489 struct nfs4_exception exception = { }; 1573 struct nfs4_exception exception = { };
@@ -1491,10 +1575,16 @@ static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4
1491 1575
1492 do { 1576 do {
1493 err = _nfs4_open_expired(ctx, state); 1577 err = _nfs4_open_expired(ctx, state);
1494 if (err != -NFS4ERR_DELAY) 1578 switch (err) {
1495 break; 1579 default:
1496 nfs4_handle_exception(server, err, &exception); 1580 goto out;
1581 case -NFS4ERR_GRACE:
1582 case -NFS4ERR_DELAY:
1583 nfs4_handle_exception(server, err, &exception);
1584 err = 0;
1585 }
1497 } while (exception.retry); 1586 } while (exception.retry);
1587out:
1498 return err; 1588 return err;
1499} 1589}
1500 1590
@@ -1707,6 +1797,18 @@ static void nfs4_free_closedata(void *data)
1707 kfree(calldata); 1797 kfree(calldata);
1708} 1798}
1709 1799
1800static void nfs4_close_clear_stateid_flags(struct nfs4_state *state,
1801 fmode_t fmode)
1802{
1803 spin_lock(&state->owner->so_lock);
1804 if (!(fmode & FMODE_READ))
1805 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
1806 if (!(fmode & FMODE_WRITE))
1807 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
1808 clear_bit(NFS_O_RDWR_STATE, &state->flags);
1809 spin_unlock(&state->owner->so_lock);
1810}
1811
1710static void nfs4_close_done(struct rpc_task *task, void *data) 1812static void nfs4_close_done(struct rpc_task *task, void *data)
1711{ 1813{
1712 struct nfs4_closedata *calldata = data; 1814 struct nfs4_closedata *calldata = data;
@@ -1723,6 +1825,8 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1723 case 0: 1825 case 0:
1724 nfs_set_open_stateid(state, &calldata->res.stateid, 0); 1826 nfs_set_open_stateid(state, &calldata->res.stateid, 0);
1725 renew_lease(server, calldata->timestamp); 1827 renew_lease(server, calldata->timestamp);
1828 nfs4_close_clear_stateid_flags(state,
1829 calldata->arg.fmode);
1726 break; 1830 break;
1727 case -NFS4ERR_STALE_STATEID: 1831 case -NFS4ERR_STALE_STATEID:
1728 case -NFS4ERR_OLD_STATEID: 1832 case -NFS4ERR_OLD_STATEID:
@@ -1731,12 +1835,10 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1731 if (calldata->arg.fmode == 0) 1835 if (calldata->arg.fmode == 0)
1732 break; 1836 break;
1733 default: 1837 default:
1734 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) { 1838 if (nfs4_async_handle_error(task, server, state) == -EAGAIN)
1735 nfs4_restart_rpc(task, server->nfs_client); 1839 rpc_restart_call_prepare(task);
1736 return;
1737 }
1738 } 1840 }
1739 nfs4_sequence_free_slot(server->nfs_client, &calldata->res.seq_res); 1841 nfs_release_seqid(calldata->arg.seqid);
1740 nfs_refresh_inode(calldata->inode, calldata->res.fattr); 1842 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
1741} 1843}
1742 1844
@@ -1744,38 +1846,39 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
1744{ 1846{
1745 struct nfs4_closedata *calldata = data; 1847 struct nfs4_closedata *calldata = data;
1746 struct nfs4_state *state = calldata->state; 1848 struct nfs4_state *state = calldata->state;
1747 int clear_rd, clear_wr, clear_rdwr; 1849 int call_close = 0;
1748 1850
1749 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) 1851 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
1750 return; 1852 return;
1751 1853
1752 clear_rd = clear_wr = clear_rdwr = 0; 1854 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1855 calldata->arg.fmode = FMODE_READ|FMODE_WRITE;
1753 spin_lock(&state->owner->so_lock); 1856 spin_lock(&state->owner->so_lock);
1754 /* Calculate the change in open mode */ 1857 /* Calculate the change in open mode */
1755 if (state->n_rdwr == 0) { 1858 if (state->n_rdwr == 0) {
1756 if (state->n_rdonly == 0) { 1859 if (state->n_rdonly == 0) {
1757 clear_rd |= test_and_clear_bit(NFS_O_RDONLY_STATE, &state->flags); 1860 call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags);
1758 clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); 1861 call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
1862 calldata->arg.fmode &= ~FMODE_READ;
1759 } 1863 }
1760 if (state->n_wronly == 0) { 1864 if (state->n_wronly == 0) {
1761 clear_wr |= test_and_clear_bit(NFS_O_WRONLY_STATE, &state->flags); 1865 call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags);
1762 clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); 1866 call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
1867 calldata->arg.fmode &= ~FMODE_WRITE;
1763 } 1868 }
1764 } 1869 }
1765 spin_unlock(&state->owner->so_lock); 1870 spin_unlock(&state->owner->so_lock);
1766 if (!clear_rd && !clear_wr && !clear_rdwr) { 1871
1872 if (!call_close) {
1767 /* Note: exit _without_ calling nfs4_close_done */ 1873 /* Note: exit _without_ calling nfs4_close_done */
1768 task->tk_action = NULL; 1874 task->tk_action = NULL;
1769 return; 1875 return;
1770 } 1876 }
1877
1878 if (calldata->arg.fmode == 0)
1879 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
1880
1771 nfs_fattr_init(calldata->res.fattr); 1881 nfs_fattr_init(calldata->res.fattr);
1772 if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0) {
1773 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1774 calldata->arg.fmode = FMODE_READ;
1775 } else if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0) {
1776 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1777 calldata->arg.fmode = FMODE_WRITE;
1778 }
1779 calldata->timestamp = jiffies; 1882 calldata->timestamp = jiffies;
1780 if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client, 1883 if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client,
1781 &calldata->arg.seq_args, &calldata->res.seq_res, 1884 &calldata->arg.seq_args, &calldata->res.seq_res,
@@ -1827,8 +1930,6 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1827 calldata->state = state; 1930 calldata->state = state;
1828 calldata->arg.fh = NFS_FH(state->inode); 1931 calldata->arg.fh = NFS_FH(state->inode);
1829 calldata->arg.stateid = &state->open_stateid; 1932 calldata->arg.stateid = &state->open_stateid;
1830 if (nfs4_has_session(server->nfs_client))
1831 memset(calldata->arg.stateid->data, 0, 4); /* clear seqid */
1832 /* Serialization for the sequence id */ 1933 /* Serialization for the sequence id */
1833 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); 1934 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
1834 if (calldata->arg.seqid == NULL) 1935 if (calldata->arg.seqid == NULL)
@@ -1976,7 +2077,7 @@ out_drop:
1976 return 0; 2077 return 0;
1977} 2078}
1978 2079
1979void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) 2080static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
1980{ 2081{
1981 if (ctx->state == NULL) 2082 if (ctx->state == NULL)
1982 return; 2083 return;
@@ -2527,7 +2628,6 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
2527 nfs4_sequence_done(res->server, &res->seq_res, task->tk_status); 2628 nfs4_sequence_done(res->server, &res->seq_res, task->tk_status);
2528 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) 2629 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
2529 return 0; 2630 return 0;
2530 nfs4_sequence_free_slot(res->server->nfs_client, &res->seq_res);
2531 update_changeattr(dir, &res->cinfo); 2631 update_changeattr(dir, &res->cinfo);
2532 nfs_post_op_update_inode(dir, &res->dir_attr); 2632 nfs_post_op_update_inode(dir, &res->dir_attr);
2533 return 1; 2633 return 1;
@@ -2762,7 +2862,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
2762 .pages = &page, 2862 .pages = &page,
2763 .pgbase = 0, 2863 .pgbase = 0,
2764 .count = count, 2864 .count = count,
2765 .bitmask = NFS_SERVER(dentry->d_inode)->cache_consistency_bitmask, 2865 .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask,
2766 }; 2866 };
2767 struct nfs4_readdir_res res; 2867 struct nfs4_readdir_res res;
2768 struct rpc_message msg = { 2868 struct rpc_message msg = {
@@ -2966,11 +3066,10 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
2966 3066
2967 dprintk("--> %s\n", __func__); 3067 dprintk("--> %s\n", __func__);
2968 3068
2969 /* nfs4_sequence_free_slot called in the read rpc_call_done */
2970 nfs4_sequence_done(server, &data->res.seq_res, task->tk_status); 3069 nfs4_sequence_done(server, &data->res.seq_res, task->tk_status);
2971 3070
2972 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 3071 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
2973 nfs4_restart_rpc(task, server->nfs_client); 3072 nfs_restart_rpc(task, server->nfs_client);
2974 return -EAGAIN; 3073 return -EAGAIN;
2975 } 3074 }
2976 3075
@@ -2990,12 +3089,11 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
2990{ 3089{
2991 struct inode *inode = data->inode; 3090 struct inode *inode = data->inode;
2992 3091
2993 /* slot is freed in nfs_writeback_done */
2994 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, 3092 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
2995 task->tk_status); 3093 task->tk_status);
2996 3094
2997 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 3095 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
2998 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3096 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
2999 return -EAGAIN; 3097 return -EAGAIN;
3000 } 3098 }
3001 if (task->tk_status >= 0) { 3099 if (task->tk_status >= 0) {
@@ -3023,11 +3121,9 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
3023 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, 3121 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
3024 task->tk_status); 3122 task->tk_status);
3025 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 3123 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
3026 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3124 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
3027 return -EAGAIN; 3125 return -EAGAIN;
3028 } 3126 }
3029 nfs4_sequence_free_slot(NFS_SERVER(inode)->nfs_client,
3030 &data->res.seq_res);
3031 nfs_refresh_inode(inode, data->res.fattr); 3127 nfs_refresh_inode(inode, data->res.fattr);
3032 return 0; 3128 return 0;
3033} 3129}
@@ -3060,9 +3156,6 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
3060 if (time_before(clp->cl_last_renewal,timestamp)) 3156 if (time_before(clp->cl_last_renewal,timestamp))
3061 clp->cl_last_renewal = timestamp; 3157 clp->cl_last_renewal = timestamp;
3062 spin_unlock(&clp->cl_lock); 3158 spin_unlock(&clp->cl_lock);
3063 dprintk("%s calling put_rpccred on rpc_cred %p\n", __func__,
3064 task->tk_msg.rpc_cred);
3065 put_rpccred(task->tk_msg.rpc_cred);
3066} 3159}
3067 3160
3068static const struct rpc_call_ops nfs4_renew_ops = { 3161static const struct rpc_call_ops nfs4_renew_ops = {
@@ -3348,7 +3441,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3348 case -NFS4ERR_SEQ_MISORDERED: 3441 case -NFS4ERR_SEQ_MISORDERED:
3349 dprintk("%s ERROR %d, Reset session\n", __func__, 3442 dprintk("%s ERROR %d, Reset session\n", __func__,
3350 task->tk_status); 3443 task->tk_status);
3351 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); 3444 nfs4_schedule_state_recovery(clp);
3352 task->tk_status = 0; 3445 task->tk_status = 0;
3353 return -EAGAIN; 3446 return -EAGAIN;
3354#endif /* CONFIG_NFS_V4_1 */ 3447#endif /* CONFIG_NFS_V4_1 */
@@ -3481,12 +3574,23 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
3481{ 3574{
3482 struct nfs4_delegreturndata *data = calldata; 3575 struct nfs4_delegreturndata *data = calldata;
3483 3576
3484 nfs4_sequence_done_free_slot(data->res.server, &data->res.seq_res, 3577 nfs4_sequence_done(data->res.server, &data->res.seq_res,
3485 task->tk_status); 3578 task->tk_status);
3486 3579
3487 data->rpc_status = task->tk_status; 3580 switch (task->tk_status) {
3488 if (data->rpc_status == 0) 3581 case -NFS4ERR_STALE_STATEID:
3582 case -NFS4ERR_EXPIRED:
3583 case 0:
3489 renew_lease(data->res.server, data->timestamp); 3584 renew_lease(data->res.server, data->timestamp);
3585 break;
3586 default:
3587 if (nfs4_async_handle_error(task, data->res.server, NULL) ==
3588 -EAGAIN) {
3589 nfs_restart_rpc(task, data->res.server->nfs_client);
3590 return;
3591 }
3592 }
3593 data->rpc_status = task->tk_status;
3490} 3594}
3491 3595
3492static void nfs4_delegreturn_release(void *calldata) 3596static void nfs4_delegreturn_release(void *calldata)
@@ -3739,11 +3843,9 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3739 break; 3843 break;
3740 default: 3844 default:
3741 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) 3845 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
3742 nfs4_restart_rpc(task, 3846 nfs_restart_rpc(task,
3743 calldata->server->nfs_client); 3847 calldata->server->nfs_client);
3744 } 3848 }
3745 nfs4_sequence_free_slot(calldata->server->nfs_client,
3746 &calldata->res.seq_res);
3747} 3849}
3748 3850
3749static void nfs4_locku_prepare(struct rpc_task *task, void *data) 3851static void nfs4_locku_prepare(struct rpc_task *task, void *data)
@@ -3919,14 +4021,20 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
3919 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); 4021 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
3920} 4022}
3921 4023
4024static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
4025{
4026 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4027 nfs4_lock_prepare(task, calldata);
4028}
4029
3922static void nfs4_lock_done(struct rpc_task *task, void *calldata) 4030static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3923{ 4031{
3924 struct nfs4_lockdata *data = calldata; 4032 struct nfs4_lockdata *data = calldata;
3925 4033
3926 dprintk("%s: begin!\n", __func__); 4034 dprintk("%s: begin!\n", __func__);
3927 4035
3928 nfs4_sequence_done_free_slot(data->server, &data->res.seq_res, 4036 nfs4_sequence_done(data->server, &data->res.seq_res,
3929 task->tk_status); 4037 task->tk_status);
3930 4038
3931 data->rpc_status = task->tk_status; 4039 data->rpc_status = task->tk_status;
3932 if (RPC_ASSASSINATED(task)) 4040 if (RPC_ASSASSINATED(task))
@@ -3974,7 +4082,13 @@ static const struct rpc_call_ops nfs4_lock_ops = {
3974 .rpc_release = nfs4_lock_release, 4082 .rpc_release = nfs4_lock_release,
3975}; 4083};
3976 4084
3977static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int reclaim) 4085static const struct rpc_call_ops nfs4_recover_lock_ops = {
4086 .rpc_call_prepare = nfs4_recover_lock_prepare,
4087 .rpc_call_done = nfs4_lock_done,
4088 .rpc_release = nfs4_lock_release,
4089};
4090
4091static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type)
3978{ 4092{
3979 struct nfs4_lockdata *data; 4093 struct nfs4_lockdata *data;
3980 struct rpc_task *task; 4094 struct rpc_task *task;
@@ -3998,8 +4112,11 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
3998 return -ENOMEM; 4112 return -ENOMEM;
3999 if (IS_SETLKW(cmd)) 4113 if (IS_SETLKW(cmd))
4000 data->arg.block = 1; 4114 data->arg.block = 1;
4001 if (reclaim != 0) 4115 if (recovery_type > NFS_LOCK_NEW) {
4002 data->arg.reclaim = 1; 4116 if (recovery_type == NFS_LOCK_RECLAIM)
4117 data->arg.reclaim = NFS_LOCK_RECLAIM;
4118 task_setup_data.callback_ops = &nfs4_recover_lock_ops;
4119 }
4003 msg.rpc_argp = &data->arg, 4120 msg.rpc_argp = &data->arg,
4004 msg.rpc_resp = &data->res, 4121 msg.rpc_resp = &data->res,
4005 task_setup_data.callback_data = data; 4122 task_setup_data.callback_data = data;
@@ -4026,7 +4143,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
4026 /* Cache the lock if possible... */ 4143 /* Cache the lock if possible... */
4027 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4144 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4028 return 0; 4145 return 0;
4029 err = _nfs4_do_setlk(state, F_SETLK, request, 1); 4146 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM);
4030 if (err != -NFS4ERR_DELAY) 4147 if (err != -NFS4ERR_DELAY)
4031 break; 4148 break;
4032 nfs4_handle_exception(server, err, &exception); 4149 nfs4_handle_exception(server, err, &exception);
@@ -4046,11 +4163,17 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
4046 do { 4163 do {
4047 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4164 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4048 return 0; 4165 return 0;
4049 err = _nfs4_do_setlk(state, F_SETLK, request, 0); 4166 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_EXPIRED);
4050 if (err != -NFS4ERR_DELAY) 4167 switch (err) {
4051 break; 4168 default:
4052 nfs4_handle_exception(server, err, &exception); 4169 goto out;
4170 case -NFS4ERR_GRACE:
4171 case -NFS4ERR_DELAY:
4172 nfs4_handle_exception(server, err, &exception);
4173 err = 0;
4174 }
4053 } while (exception.retry); 4175 } while (exception.retry);
4176out:
4054 return err; 4177 return err;
4055} 4178}
4056 4179
@@ -4076,7 +4199,7 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
4076 status = do_vfs_lock(request->fl_file, request); 4199 status = do_vfs_lock(request->fl_file, request);
4077 goto out_unlock; 4200 goto out_unlock;
4078 } 4201 }
4079 status = _nfs4_do_setlk(state, cmd, request, 0); 4202 status = _nfs4_do_setlk(state, cmd, request, NFS_LOCK_NEW);
4080 if (status != 0) 4203 if (status != 0)
4081 goto out_unlock; 4204 goto out_unlock;
4082 /* Note: we always want to sleep here! */ 4205 /* Note: we always want to sleep here! */
@@ -4159,7 +4282,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4159 if (err != 0) 4282 if (err != 0)
4160 goto out; 4283 goto out;
4161 do { 4284 do {
4162 err = _nfs4_do_setlk(state, F_SETLK, fl, 0); 4285 err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW);
4163 switch (err) { 4286 switch (err) {
4164 default: 4287 default:
4165 printk(KERN_ERR "%s: unhandled error %d.\n", 4288 printk(KERN_ERR "%s: unhandled error %d.\n",
@@ -4170,6 +4293,11 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4170 case -NFS4ERR_EXPIRED: 4293 case -NFS4ERR_EXPIRED:
4171 case -NFS4ERR_STALE_CLIENTID: 4294 case -NFS4ERR_STALE_CLIENTID:
4172 case -NFS4ERR_STALE_STATEID: 4295 case -NFS4ERR_STALE_STATEID:
4296 case -NFS4ERR_BADSESSION:
4297 case -NFS4ERR_BADSLOT:
4298 case -NFS4ERR_BAD_HIGH_SLOT:
4299 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
4300 case -NFS4ERR_DEADSESSION:
4173 nfs4_schedule_state_recovery(server->nfs_client); 4301 nfs4_schedule_state_recovery(server->nfs_client);
4174 goto out; 4302 goto out;
4175 case -ERESTARTSYS: 4303 case -ERESTARTSYS:
@@ -4294,7 +4422,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4294 * NFS4ERR_BADSESSION in the sequence operation, and will therefore 4422 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
4295 * be in some phase of session reset. 4423 * be in some phase of session reset.
4296 */ 4424 */
4297static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) 4425int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4298{ 4426{
4299 nfs4_verifier verifier; 4427 nfs4_verifier verifier;
4300 struct nfs41_exchange_id_args args = { 4428 struct nfs41_exchange_id_args args = {
@@ -4316,6 +4444,9 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4316 dprintk("--> %s\n", __func__); 4444 dprintk("--> %s\n", __func__);
4317 BUG_ON(clp == NULL); 4445 BUG_ON(clp == NULL);
4318 4446
4447 /* Remove server-only flags */
4448 args.flags &= ~EXCHGID4_FLAG_CONFIRMED_R;
4449
4319 p = (u32 *)verifier.data; 4450 p = (u32 *)verifier.data;
4320 *p++ = htonl((u32)clp->cl_boot_time.tv_sec); 4451 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
4321 *p = htonl((u32)clp->cl_boot_time.tv_nsec); 4452 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
@@ -4359,11 +4490,12 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,
4359 (struct nfs4_get_lease_time_data *)calldata; 4490 (struct nfs4_get_lease_time_data *)calldata;
4360 4491
4361 dprintk("--> %s\n", __func__); 4492 dprintk("--> %s\n", __func__);
4493 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4362 /* just setup sequence, do not trigger session recovery 4494 /* just setup sequence, do not trigger session recovery
4363 since we're invoked within one */ 4495 since we're invoked within one */
4364 ret = nfs41_setup_sequence(data->clp->cl_session, 4496 ret = nfs41_setup_sequence(data->clp->cl_session,
4365 &data->args->la_seq_args, 4497 &data->args->la_seq_args,
4366 &data->res->lr_seq_res, 0, task); 4498 &data->res->lr_seq_res, 0, task);
4367 4499
4368 BUG_ON(ret == -EAGAIN); 4500 BUG_ON(ret == -EAGAIN);
4369 rpc_call_start(task); 4501 rpc_call_start(task);
@@ -4387,10 +4519,9 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
4387 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); 4519 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
4388 rpc_delay(task, NFS4_POLL_RETRY_MIN); 4520 rpc_delay(task, NFS4_POLL_RETRY_MIN);
4389 task->tk_status = 0; 4521 task->tk_status = 0;
4390 nfs4_restart_rpc(task, data->clp); 4522 nfs_restart_rpc(task, data->clp);
4391 return; 4523 return;
4392 } 4524 }
4393 nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res);
4394 dprintk("<-- %s\n", __func__); 4525 dprintk("<-- %s\n", __func__);
4395} 4526}
4396 4527
@@ -4463,7 +4594,6 @@ static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, int max_slots,
4463 spin_lock(&tbl->slot_tbl_lock); 4594 spin_lock(&tbl->slot_tbl_lock);
4464 for (i = 0; i < max_slots; ++i) 4595 for (i = 0; i < max_slots; ++i)
4465 tbl->slots[i].seq_nr = ivalue; 4596 tbl->slots[i].seq_nr = ivalue;
4466 tbl->highest_used_slotid = -1;
4467 spin_unlock(&tbl->slot_tbl_lock); 4597 spin_unlock(&tbl->slot_tbl_lock);
4468 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, 4598 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
4469 tbl, tbl->slots, tbl->max_slots); 4599 tbl, tbl->slots, tbl->max_slots);
@@ -4513,7 +4643,6 @@ static void nfs4_destroy_slot_tables(struct nfs4_session *session)
4513static int nfs4_init_slot_table(struct nfs4_slot_table *tbl, 4643static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4514 int max_slots, int ivalue) 4644 int max_slots, int ivalue)
4515{ 4645{
4516 int i;
4517 struct nfs4_slot *slot; 4646 struct nfs4_slot *slot;
4518 int ret = -ENOMEM; 4647 int ret = -ENOMEM;
4519 4648
@@ -4524,18 +4653,9 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4524 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL); 4653 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL);
4525 if (!slot) 4654 if (!slot)
4526 goto out; 4655 goto out;
4527 for (i = 0; i < max_slots; ++i)
4528 slot[i].seq_nr = ivalue;
4529 ret = 0; 4656 ret = 0;
4530 4657
4531 spin_lock(&tbl->slot_tbl_lock); 4658 spin_lock(&tbl->slot_tbl_lock);
4532 if (tbl->slots != NULL) {
4533 spin_unlock(&tbl->slot_tbl_lock);
4534 dprintk("%s: slot table already initialized. tbl=%p slots=%p\n",
4535 __func__, tbl, tbl->slots);
4536 WARN_ON(1);
4537 goto out_free;
4538 }
4539 tbl->max_slots = max_slots; 4659 tbl->max_slots = max_slots;
4540 tbl->slots = slot; 4660 tbl->slots = slot;
4541 tbl->highest_used_slotid = -1; /* no slot is currently used */ 4661 tbl->highest_used_slotid = -1; /* no slot is currently used */
@@ -4545,10 +4665,6 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4545out: 4665out:
4546 dprintk("<-- %s: return %d\n", __func__, ret); 4666 dprintk("<-- %s: return %d\n", __func__, ret);
4547 return ret; 4667 return ret;
4548
4549out_free:
4550 kfree(slot);
4551 goto out;
4552} 4668}
4553 4669
4554/* 4670/*
@@ -4556,17 +4672,24 @@ out_free:
4556 */ 4672 */
4557static int nfs4_init_slot_tables(struct nfs4_session *session) 4673static int nfs4_init_slot_tables(struct nfs4_session *session)
4558{ 4674{
4559 int status; 4675 struct nfs4_slot_table *tbl;
4676 int status = 0;
4560 4677
4561 status = nfs4_init_slot_table(&session->fc_slot_table, 4678 tbl = &session->fc_slot_table;
4562 session->fc_attrs.max_reqs, 1); 4679 if (tbl->slots == NULL) {
4563 if (status) 4680 status = nfs4_init_slot_table(tbl,
4564 return status; 4681 session->fc_attrs.max_reqs, 1);
4682 if (status)
4683 return status;
4684 }
4565 4685
4566 status = nfs4_init_slot_table(&session->bc_slot_table, 4686 tbl = &session->bc_slot_table;
4567 session->bc_attrs.max_reqs, 0); 4687 if (tbl->slots == NULL) {
4568 if (status) 4688 status = nfs4_init_slot_table(tbl,
4569 nfs4_destroy_slot_tables(session); 4689 session->bc_attrs.max_reqs, 0);
4690 if (status)
4691 nfs4_destroy_slot_tables(session);
4692 }
4570 4693
4571 return status; 4694 return status;
4572} 4695}
@@ -4580,7 +4703,6 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4580 if (!session) 4703 if (!session)
4581 return NULL; 4704 return NULL;
4582 4705
4583 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
4584 /* 4706 /*
4585 * The create session reply races with the server back 4707 * The create session reply races with the server back
4586 * channel probe. Mark the client NFS_CS_SESSION_INITING 4708 * channel probe. Mark the client NFS_CS_SESSION_INITING
@@ -4588,12 +4710,15 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4588 * nfs_client struct 4710 * nfs_client struct
4589 */ 4711 */
4590 clp->cl_cons_state = NFS_CS_SESSION_INITING; 4712 clp->cl_cons_state = NFS_CS_SESSION_INITING;
4713 init_completion(&session->complete);
4591 4714
4592 tbl = &session->fc_slot_table; 4715 tbl = &session->fc_slot_table;
4716 tbl->highest_used_slotid = -1;
4593 spin_lock_init(&tbl->slot_tbl_lock); 4717 spin_lock_init(&tbl->slot_tbl_lock);
4594 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); 4718 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
4595 4719
4596 tbl = &session->bc_slot_table; 4720 tbl = &session->bc_slot_table;
4721 tbl->highest_used_slotid = -1;
4597 spin_lock_init(&tbl->slot_tbl_lock); 4722 spin_lock_init(&tbl->slot_tbl_lock);
4598 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table"); 4723 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
4599 4724
@@ -4745,11 +4870,10 @@ static int _nfs4_proc_create_session(struct nfs_client *clp)
4745 * It is the responsibility of the caller to verify the session is 4870 * It is the responsibility of the caller to verify the session is
4746 * expired before calling this routine. 4871 * expired before calling this routine.
4747 */ 4872 */
4748int nfs4_proc_create_session(struct nfs_client *clp, int reset) 4873int nfs4_proc_create_session(struct nfs_client *clp)
4749{ 4874{
4750 int status; 4875 int status;
4751 unsigned *ptr; 4876 unsigned *ptr;
4752 struct nfs_fsinfo fsinfo;
4753 struct nfs4_session *session = clp->cl_session; 4877 struct nfs4_session *session = clp->cl_session;
4754 4878
4755 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); 4879 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
@@ -4758,35 +4882,19 @@ int nfs4_proc_create_session(struct nfs_client *clp, int reset)
4758 if (status) 4882 if (status)
4759 goto out; 4883 goto out;
4760 4884
4761 /* Init or reset the fore channel */ 4885 /* Init and reset the fore channel */
4762 if (reset) 4886 status = nfs4_init_slot_tables(session);
4763 status = nfs4_reset_slot_tables(session); 4887 dprintk("slot table initialization returned %d\n", status);
4764 else 4888 if (status)
4765 status = nfs4_init_slot_tables(session); 4889 goto out;
4766 dprintk("fore channel slot table initialization returned %d\n", status); 4890 status = nfs4_reset_slot_tables(session);
4891 dprintk("slot table reset returned %d\n", status);
4767 if (status) 4892 if (status)
4768 goto out; 4893 goto out;
4769 4894
4770 ptr = (unsigned *)&session->sess_id.data[0]; 4895 ptr = (unsigned *)&session->sess_id.data[0];
4771 dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__, 4896 dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__,
4772 clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]); 4897 clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]);
4773
4774 if (reset)
4775 /* Lease time is aleady set */
4776 goto out;
4777
4778 /* Get the lease time */
4779 status = nfs4_proc_get_lease_time(clp, &fsinfo);
4780 if (status == 0) {
4781 /* Update lease time and schedule renewal */
4782 spin_lock(&clp->cl_lock);
4783 clp->cl_lease_time = fsinfo.lease_time * HZ;
4784 clp->cl_last_renewal = jiffies;
4785 clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
4786 spin_unlock(&clp->cl_lock);
4787
4788 nfs4_schedule_state_renewal(clp);
4789 }
4790out: 4898out:
4791 dprintk("<-- %s\n", __func__); 4899 dprintk("<-- %s\n", __func__);
4792 return status; 4900 return status;
@@ -4825,13 +4933,24 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
4825int nfs4_init_session(struct nfs_server *server) 4933int nfs4_init_session(struct nfs_server *server)
4826{ 4934{
4827 struct nfs_client *clp = server->nfs_client; 4935 struct nfs_client *clp = server->nfs_client;
4936 struct nfs4_session *session;
4937 unsigned int rsize, wsize;
4828 int ret; 4938 int ret;
4829 4939
4830 if (!nfs4_has_session(clp)) 4940 if (!nfs4_has_session(clp))
4831 return 0; 4941 return 0;
4832 4942
4833 clp->cl_session->fc_attrs.max_rqst_sz = server->wsize; 4943 rsize = server->rsize;
4834 clp->cl_session->fc_attrs.max_resp_sz = server->rsize; 4944 if (rsize == 0)
4945 rsize = NFS_MAX_FILE_IO_SIZE;
4946 wsize = server->wsize;
4947 if (wsize == 0)
4948 wsize = NFS_MAX_FILE_IO_SIZE;
4949
4950 session = clp->cl_session;
4951 session->fc_attrs.max_rqst_sz = wsize + nfs41_maxwrite_overhead;
4952 session->fc_attrs.max_resp_sz = rsize + nfs41_maxread_overhead;
4953
4835 ret = nfs4_recover_expired_lease(server); 4954 ret = nfs4_recover_expired_lease(server);
4836 if (!ret) 4955 if (!ret)
4837 ret = nfs4_check_client_ready(clp); 4956 ret = nfs4_check_client_ready(clp);
@@ -4856,7 +4975,7 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
4856 args.sa_cache_this = 0; 4975 args.sa_cache_this = 0;
4857 4976
4858 return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args, 4977 return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args,
4859 &res, 0); 4978 &res, args.sa_cache_this, 1);
4860} 4979}
4861 4980
4862void nfs41_sequence_call_done(struct rpc_task *task, void *data) 4981void nfs41_sequence_call_done(struct rpc_task *task, void *data)
@@ -4870,14 +4989,12 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
4870 4989
4871 if (_nfs4_async_handle_error(task, NULL, clp, NULL) 4990 if (_nfs4_async_handle_error(task, NULL, clp, NULL)
4872 == -EAGAIN) { 4991 == -EAGAIN) {
4873 nfs4_restart_rpc(task, clp); 4992 nfs_restart_rpc(task, clp);
4874 return; 4993 return;
4875 } 4994 }
4876 } 4995 }
4877 nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp);
4878 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); 4996 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
4879 4997
4880 put_rpccred(task->tk_msg.rpc_cred);
4881 kfree(task->tk_msg.rpc_argp); 4998 kfree(task->tk_msg.rpc_argp);
4882 kfree(task->tk_msg.rpc_resp); 4999 kfree(task->tk_msg.rpc_resp);
4883 5000
@@ -4930,6 +5047,110 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
4930 &nfs41_sequence_ops, (void *)clp); 5047 &nfs41_sequence_ops, (void *)clp);
4931} 5048}
4932 5049
5050struct nfs4_reclaim_complete_data {
5051 struct nfs_client *clp;
5052 struct nfs41_reclaim_complete_args arg;
5053 struct nfs41_reclaim_complete_res res;
5054};
5055
5056static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
5057{
5058 struct nfs4_reclaim_complete_data *calldata = data;
5059
5060 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
5061 if (nfs4_setup_sequence(calldata->clp, &calldata->arg.seq_args,
5062 &calldata->res.seq_res, 0, task))
5063 return;
5064
5065 rpc_call_start(task);
5066}
5067
5068static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
5069{
5070 struct nfs4_reclaim_complete_data *calldata = data;
5071 struct nfs_client *clp = calldata->clp;
5072 struct nfs4_sequence_res *res = &calldata->res.seq_res;
5073
5074 dprintk("--> %s\n", __func__);
5075 nfs41_sequence_done(clp, res, task->tk_status);
5076 switch (task->tk_status) {
5077 case 0:
5078 case -NFS4ERR_COMPLETE_ALREADY:
5079 break;
5080 case -NFS4ERR_BADSESSION:
5081 case -NFS4ERR_DEADSESSION:
5082 /*
5083 * Handle the session error, but do not retry the operation, as
5084 * we have no way of telling whether the clientid had to be
5085 * reset before we got our reply. If reset, a new wave of
5086 * reclaim operations will follow, containing their own reclaim
5087 * complete. We don't want our retry to get on the way of
5088 * recovery by incorrectly indicating to the server that we're
5089 * done reclaiming state since the process had to be restarted.
5090 */
5091 _nfs4_async_handle_error(task, NULL, clp, NULL);
5092 break;
5093 default:
5094 if (_nfs4_async_handle_error(
5095 task, NULL, clp, NULL) == -EAGAIN) {
5096 rpc_restart_call_prepare(task);
5097 return;
5098 }
5099 }
5100
5101 dprintk("<-- %s\n", __func__);
5102}
5103
5104static void nfs4_free_reclaim_complete_data(void *data)
5105{
5106 struct nfs4_reclaim_complete_data *calldata = data;
5107
5108 kfree(calldata);
5109}
5110
5111static const struct rpc_call_ops nfs4_reclaim_complete_call_ops = {
5112 .rpc_call_prepare = nfs4_reclaim_complete_prepare,
5113 .rpc_call_done = nfs4_reclaim_complete_done,
5114 .rpc_release = nfs4_free_reclaim_complete_data,
5115};
5116
5117/*
5118 * Issue a global reclaim complete.
5119 */
5120static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
5121{
5122 struct nfs4_reclaim_complete_data *calldata;
5123 struct rpc_task *task;
5124 struct rpc_message msg = {
5125 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RECLAIM_COMPLETE],
5126 };
5127 struct rpc_task_setup task_setup_data = {
5128 .rpc_client = clp->cl_rpcclient,
5129 .rpc_message = &msg,
5130 .callback_ops = &nfs4_reclaim_complete_call_ops,
5131 .flags = RPC_TASK_ASYNC,
5132 };
5133 int status = -ENOMEM;
5134
5135 dprintk("--> %s\n", __func__);
5136 calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
5137 if (calldata == NULL)
5138 goto out;
5139 calldata->clp = clp;
5140 calldata->arg.one_fs = 0;
5141 calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
5142
5143 msg.rpc_argp = &calldata->arg;
5144 msg.rpc_resp = &calldata->res;
5145 task_setup_data.callback_data = calldata;
5146 task = rpc_run_task(&task_setup_data);
5147 if (IS_ERR(task))
5148 status = PTR_ERR(task);
5149 rpc_put_task(task);
5150out:
5151 dprintk("<-- %s status=%d\n", __func__, status);
5152 return status;
5153}
4933#endif /* CONFIG_NFS_V4_1 */ 5154#endif /* CONFIG_NFS_V4_1 */
4934 5155
4935struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = { 5156struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
@@ -4947,8 +5168,9 @@ struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
4947 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, 5168 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
4948 .recover_open = nfs4_open_reclaim, 5169 .recover_open = nfs4_open_reclaim,
4949 .recover_lock = nfs4_lock_reclaim, 5170 .recover_lock = nfs4_lock_reclaim,
4950 .establish_clid = nfs4_proc_exchange_id, 5171 .establish_clid = nfs41_init_clientid,
4951 .get_clid_cred = nfs4_get_exchange_id_cred, 5172 .get_clid_cred = nfs4_get_exchange_id_cred,
5173 .reclaim_complete = nfs41_proc_reclaim_complete,
4952}; 5174};
4953#endif /* CONFIG_NFS_V4_1 */ 5175#endif /* CONFIG_NFS_V4_1 */
4954 5176
@@ -4967,7 +5189,7 @@ struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
4967 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, 5189 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
4968 .recover_open = nfs4_open_expired, 5190 .recover_open = nfs4_open_expired,
4969 .recover_lock = nfs4_lock_expired, 5191 .recover_lock = nfs4_lock_expired,
4970 .establish_clid = nfs4_proc_exchange_id, 5192 .establish_clid = nfs41_init_clientid,
4971 .get_clid_cred = nfs4_get_exchange_id_cred, 5193 .get_clid_cred = nfs4_get_exchange_id_cred,
4972}; 5194};
4973#endif /* CONFIG_NFS_V4_1 */ 5195#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 2ef4fecf3984..6d263ed79e92 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -116,6 +116,79 @@ struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
116 116
117#if defined(CONFIG_NFS_V4_1) 117#if defined(CONFIG_NFS_V4_1)
118 118
119static int nfs41_setup_state_renewal(struct nfs_client *clp)
120{
121 int status;
122 struct nfs_fsinfo fsinfo;
123
124 status = nfs4_proc_get_lease_time(clp, &fsinfo);
125 if (status == 0) {
126 /* Update lease time and schedule renewal */
127 spin_lock(&clp->cl_lock);
128 clp->cl_lease_time = fsinfo.lease_time * HZ;
129 clp->cl_last_renewal = jiffies;
130 spin_unlock(&clp->cl_lock);
131
132 nfs4_schedule_state_renewal(clp);
133 }
134
135 return status;
136}
137
138static void nfs4_end_drain_session(struct nfs_client *clp)
139{
140 struct nfs4_session *ses = clp->cl_session;
141 int max_slots;
142
143 if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) {
144 spin_lock(&ses->fc_slot_table.slot_tbl_lock);
145 max_slots = ses->fc_slot_table.max_slots;
146 while (max_slots--) {
147 struct rpc_task *task;
148
149 task = rpc_wake_up_next(&ses->fc_slot_table.
150 slot_tbl_waitq);
151 if (!task)
152 break;
153 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
154 }
155 spin_unlock(&ses->fc_slot_table.slot_tbl_lock);
156 }
157}
158
159static int nfs4_begin_drain_session(struct nfs_client *clp)
160{
161 struct nfs4_session *ses = clp->cl_session;
162 struct nfs4_slot_table *tbl = &ses->fc_slot_table;
163
164 spin_lock(&tbl->slot_tbl_lock);
165 set_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state);
166 if (tbl->highest_used_slotid != -1) {
167 INIT_COMPLETION(ses->complete);
168 spin_unlock(&tbl->slot_tbl_lock);
169 return wait_for_completion_interruptible(&ses->complete);
170 }
171 spin_unlock(&tbl->slot_tbl_lock);
172 return 0;
173}
174
175int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
176{
177 int status;
178
179 nfs4_begin_drain_session(clp);
180 status = nfs4_proc_exchange_id(clp, cred);
181 if (status != 0)
182 goto out;
183 status = nfs4_proc_create_session(clp);
184 if (status != 0)
185 goto out;
186 nfs41_setup_state_renewal(clp);
187 nfs_mark_client_ready(clp, NFS_CS_READY);
188out:
189 return status;
190}
191
119struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp) 192struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
120{ 193{
121 struct rpc_cred *cred; 194 struct rpc_cred *cred;
@@ -693,16 +766,21 @@ struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
693 return new; 766 return new;
694} 767}
695 768
696void nfs_free_seqid(struct nfs_seqid *seqid) 769void nfs_release_seqid(struct nfs_seqid *seqid)
697{ 770{
698 if (!list_empty(&seqid->list)) { 771 if (!list_empty(&seqid->list)) {
699 struct rpc_sequence *sequence = seqid->sequence->sequence; 772 struct rpc_sequence *sequence = seqid->sequence->sequence;
700 773
701 spin_lock(&sequence->lock); 774 spin_lock(&sequence->lock);
702 list_del(&seqid->list); 775 list_del_init(&seqid->list);
703 spin_unlock(&sequence->lock); 776 spin_unlock(&sequence->lock);
704 rpc_wake_up(&sequence->wait); 777 rpc_wake_up(&sequence->wait);
705 } 778 }
779}
780
781void nfs_free_seqid(struct nfs_seqid *seqid)
782{
783 nfs_release_seqid(seqid);
706 kfree(seqid); 784 kfree(seqid);
707} 785}
708 786
@@ -877,6 +955,10 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
877 case -NFS4ERR_EXPIRED: 955 case -NFS4ERR_EXPIRED:
878 case -NFS4ERR_NO_GRACE: 956 case -NFS4ERR_NO_GRACE:
879 case -NFS4ERR_STALE_CLIENTID: 957 case -NFS4ERR_STALE_CLIENTID:
958 case -NFS4ERR_BADSESSION:
959 case -NFS4ERR_BADSLOT:
960 case -NFS4ERR_BAD_HIGH_SLOT:
961 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
880 goto out; 962 goto out;
881 default: 963 default:
882 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n", 964 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
@@ -959,6 +1041,10 @@ restart:
959 case -NFS4ERR_NO_GRACE: 1041 case -NFS4ERR_NO_GRACE:
960 nfs4_state_mark_reclaim_nograce(sp->so_client, state); 1042 nfs4_state_mark_reclaim_nograce(sp->so_client, state);
961 case -NFS4ERR_STALE_CLIENTID: 1043 case -NFS4ERR_STALE_CLIENTID:
1044 case -NFS4ERR_BADSESSION:
1045 case -NFS4ERR_BADSLOT:
1046 case -NFS4ERR_BAD_HIGH_SLOT:
1047 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
962 goto out_err; 1048 goto out_err;
963 } 1049 }
964 nfs4_put_open_state(state); 1050 nfs4_put_open_state(state);
@@ -1011,6 +1097,14 @@ static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
1011 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot); 1097 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot);
1012} 1098}
1013 1099
1100static void nfs4_reclaim_complete(struct nfs_client *clp,
1101 const struct nfs4_state_recovery_ops *ops)
1102{
1103 /* Notify the server we're done reclaiming our state */
1104 if (ops->reclaim_complete)
1105 (void)ops->reclaim_complete(clp);
1106}
1107
1014static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp) 1108static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
1015{ 1109{
1016 struct nfs4_state_owner *sp; 1110 struct nfs4_state_owner *sp;
@@ -1020,6 +1114,9 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
1020 if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) 1114 if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
1021 return; 1115 return;
1022 1116
1117 nfs4_reclaim_complete(clp,
1118 nfs4_reboot_recovery_ops[clp->cl_minorversion]);
1119
1023 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 1120 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
1024 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 1121 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
1025 spin_lock(&sp->so_lock); 1122 spin_lock(&sp->so_lock);
@@ -1046,25 +1143,25 @@ static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp)
1046 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); 1143 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce);
1047} 1144}
1048 1145
1049static void nfs4_state_end_reclaim_nograce(struct nfs_client *clp) 1146static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1050{
1051 clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
1052}
1053
1054static void nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1055{ 1147{
1056 switch (error) { 1148 switch (error) {
1057 case -NFS4ERR_CB_PATH_DOWN: 1149 case -NFS4ERR_CB_PATH_DOWN:
1058 nfs_handle_cb_pathdown(clp); 1150 nfs_handle_cb_pathdown(clp);
1059 break; 1151 return 0;
1152 case -NFS4ERR_NO_GRACE:
1153 nfs4_state_end_reclaim_reboot(clp);
1154 return 0;
1060 case -NFS4ERR_STALE_CLIENTID: 1155 case -NFS4ERR_STALE_CLIENTID:
1061 case -NFS4ERR_LEASE_MOVED: 1156 case -NFS4ERR_LEASE_MOVED:
1062 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1157 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1158 nfs4_state_end_reclaim_reboot(clp);
1063 nfs4_state_start_reclaim_reboot(clp); 1159 nfs4_state_start_reclaim_reboot(clp);
1064 break; 1160 break;
1065 case -NFS4ERR_EXPIRED: 1161 case -NFS4ERR_EXPIRED:
1066 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1162 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1067 nfs4_state_start_reclaim_nograce(clp); 1163 nfs4_state_start_reclaim_nograce(clp);
1164 break;
1068 case -NFS4ERR_BADSESSION: 1165 case -NFS4ERR_BADSESSION:
1069 case -NFS4ERR_BADSLOT: 1166 case -NFS4ERR_BADSLOT:
1070 case -NFS4ERR_BAD_HIGH_SLOT: 1167 case -NFS4ERR_BAD_HIGH_SLOT:
@@ -1072,8 +1169,11 @@ static void nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1072 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: 1169 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1073 case -NFS4ERR_SEQ_FALSE_RETRY: 1170 case -NFS4ERR_SEQ_FALSE_RETRY:
1074 case -NFS4ERR_SEQ_MISORDERED: 1171 case -NFS4ERR_SEQ_MISORDERED:
1075 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); 1172 set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
1173 /* Zero session reset errors */
1174 return 0;
1076 } 1175 }
1176 return error;
1077} 1177}
1078 1178
1079static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops) 1179static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops)
@@ -1093,8 +1193,7 @@ restart:
1093 if (status < 0) { 1193 if (status < 0) {
1094 set_bit(ops->owner_flag_bit, &sp->so_flags); 1194 set_bit(ops->owner_flag_bit, &sp->so_flags);
1095 nfs4_put_state_owner(sp); 1195 nfs4_put_state_owner(sp);
1096 nfs4_recovery_handle_error(clp, status); 1196 return nfs4_recovery_handle_error(clp, status);
1097 return status;
1098 } 1197 }
1099 nfs4_put_state_owner(sp); 1198 nfs4_put_state_owner(sp);
1100 goto restart; 1199 goto restart;
@@ -1124,8 +1223,7 @@ static int nfs4_check_lease(struct nfs_client *clp)
1124 status = ops->renew_lease(clp, cred); 1223 status = ops->renew_lease(clp, cred);
1125 put_rpccred(cred); 1224 put_rpccred(cred);
1126out: 1225out:
1127 nfs4_recovery_handle_error(clp, status); 1226 return nfs4_recovery_handle_error(clp, status);
1128 return status;
1129} 1227}
1130 1228
1131static int nfs4_reclaim_lease(struct nfs_client *clp) 1229static int nfs4_reclaim_lease(struct nfs_client *clp)
@@ -1151,55 +1249,59 @@ static int nfs4_reclaim_lease(struct nfs_client *clp)
1151} 1249}
1152 1250
1153#ifdef CONFIG_NFS_V4_1 1251#ifdef CONFIG_NFS_V4_1
1154static void nfs4_session_recovery_handle_error(struct nfs_client *clp, int err) 1252void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
1155{ 1253{
1156 switch (err) { 1254 if (!flags)
1157 case -NFS4ERR_STALE_CLIENTID: 1255 return;
1256 else if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) {
1158 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1257 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1159 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); 1258 nfs4_state_start_reclaim_reboot(clp);
1160 } 1259 nfs4_schedule_state_recovery(clp);
1260 } else if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
1261 SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED |
1262 SEQ4_STATUS_ADMIN_STATE_REVOKED |
1263 SEQ4_STATUS_RECALLABLE_STATE_REVOKED |
1264 SEQ4_STATUS_LEASE_MOVED)) {
1265 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1266 nfs4_state_start_reclaim_nograce(clp);
1267 nfs4_schedule_state_recovery(clp);
1268 } else if (flags & (SEQ4_STATUS_CB_PATH_DOWN |
1269 SEQ4_STATUS_BACKCHANNEL_FAULT |
1270 SEQ4_STATUS_CB_PATH_DOWN_SESSION))
1271 nfs_expire_all_delegations(clp);
1161} 1272}
1162 1273
1163static int nfs4_reset_session(struct nfs_client *clp) 1274static int nfs4_reset_session(struct nfs_client *clp)
1164{ 1275{
1165 int status; 1276 int status;
1166 1277
1278 nfs4_begin_drain_session(clp);
1167 status = nfs4_proc_destroy_session(clp->cl_session); 1279 status = nfs4_proc_destroy_session(clp->cl_session);
1168 if (status && status != -NFS4ERR_BADSESSION && 1280 if (status && status != -NFS4ERR_BADSESSION &&
1169 status != -NFS4ERR_DEADSESSION) { 1281 status != -NFS4ERR_DEADSESSION) {
1170 nfs4_session_recovery_handle_error(clp, status); 1282 status = nfs4_recovery_handle_error(clp, status);
1171 goto out; 1283 goto out;
1172 } 1284 }
1173 1285
1174 memset(clp->cl_session->sess_id.data, 0, NFS4_MAX_SESSIONID_LEN); 1286 memset(clp->cl_session->sess_id.data, 0, NFS4_MAX_SESSIONID_LEN);
1175 status = nfs4_proc_create_session(clp, 1); 1287 status = nfs4_proc_create_session(clp);
1176 if (status) 1288 if (status)
1177 nfs4_session_recovery_handle_error(clp, status); 1289 status = nfs4_recovery_handle_error(clp, status);
1178 /* fall through*/
1179out:
1180 /* Wake up the next rpc task even on error */
1181 rpc_wake_up_next(&clp->cl_session->fc_slot_table.slot_tbl_waitq);
1182 return status;
1183}
1184 1290
1185static int nfs4_initialize_session(struct nfs_client *clp) 1291out:
1186{ 1292 /*
1187 int status; 1293 * Let the state manager reestablish state
1294 */
1295 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
1296 status == 0)
1297 nfs41_setup_state_renewal(clp);
1188 1298
1189 status = nfs4_proc_create_session(clp, 0);
1190 if (!status) {
1191 nfs_mark_client_ready(clp, NFS_CS_READY);
1192 } else if (status == -NFS4ERR_STALE_CLIENTID) {
1193 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1194 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
1195 } else {
1196 nfs_mark_client_ready(clp, status);
1197 }
1198 return status; 1299 return status;
1199} 1300}
1301
1200#else /* CONFIG_NFS_V4_1 */ 1302#else /* CONFIG_NFS_V4_1 */
1201static int nfs4_reset_session(struct nfs_client *clp) { return 0; } 1303static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
1202static int nfs4_initialize_session(struct nfs_client *clp) { return 0; } 1304static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; }
1203#endif /* CONFIG_NFS_V4_1 */ 1305#endif /* CONFIG_NFS_V4_1 */
1204 1306
1205/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors 1307/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
@@ -1234,7 +1336,8 @@ static void nfs4_state_manager(struct nfs_client *clp)
1234 status = nfs4_reclaim_lease(clp); 1336 status = nfs4_reclaim_lease(clp);
1235 if (status) { 1337 if (status) {
1236 nfs4_set_lease_expired(clp, status); 1338 nfs4_set_lease_expired(clp, status);
1237 if (status == -EAGAIN) 1339 if (test_bit(NFS4CLNT_LEASE_EXPIRED,
1340 &clp->cl_state))
1238 continue; 1341 continue;
1239 if (clp->cl_cons_state == 1342 if (clp->cl_cons_state ==
1240 NFS_CS_SESSION_INITING) 1343 NFS_CS_SESSION_INITING)
@@ -1242,57 +1345,54 @@ static void nfs4_state_manager(struct nfs_client *clp)
1242 goto out_error; 1345 goto out_error;
1243 } 1346 }
1244 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); 1347 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
1348 set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
1245 } 1349 }
1246 1350
1247 if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) { 1351 if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) {
1248 status = nfs4_check_lease(clp); 1352 status = nfs4_check_lease(clp);
1249 if (status != 0) 1353 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
1250 continue; 1354 continue;
1355 if (status < 0 && status != -NFS4ERR_CB_PATH_DOWN)
1356 goto out_error;
1251 } 1357 }
1358
1252 /* Initialize or reset the session */ 1359 /* Initialize or reset the session */
1253 if (test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state) 1360 if (test_and_clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)
1254 && nfs4_has_session(clp)) { 1361 && nfs4_has_session(clp)) {
1255 if (clp->cl_cons_state == NFS_CS_SESSION_INITING) 1362 status = nfs4_reset_session(clp);
1256 status = nfs4_initialize_session(clp); 1363 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
1257 else 1364 continue;
1258 status = nfs4_reset_session(clp); 1365 if (status < 0)
1259 if (status) {
1260 if (status == -NFS4ERR_STALE_CLIENTID)
1261 continue;
1262 goto out_error; 1366 goto out_error;
1263 }
1264 } 1367 }
1368
1265 /* First recover reboot state... */ 1369 /* First recover reboot state... */
1266 if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { 1370 if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) {
1267 status = nfs4_do_reclaim(clp, 1371 status = nfs4_do_reclaim(clp,
1268 nfs4_reboot_recovery_ops[clp->cl_minorversion]); 1372 nfs4_reboot_recovery_ops[clp->cl_minorversion]);
1269 if (status == -NFS4ERR_STALE_CLIENTID) 1373 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) ||
1270 continue; 1374 test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
1271 if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
1272 continue; 1375 continue;
1273 nfs4_state_end_reclaim_reboot(clp); 1376 nfs4_state_end_reclaim_reboot(clp);
1274 continue; 1377 if (test_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state))
1378 continue;
1379 if (status < 0)
1380 goto out_error;
1275 } 1381 }
1276 1382
1277 /* Now recover expired state... */ 1383 /* Now recover expired state... */
1278 if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { 1384 if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
1279 status = nfs4_do_reclaim(clp, 1385 status = nfs4_do_reclaim(clp,
1280 nfs4_nograce_recovery_ops[clp->cl_minorversion]); 1386 nfs4_nograce_recovery_ops[clp->cl_minorversion]);
1281 if (status < 0) { 1387 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) ||
1282 set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); 1388 test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) ||
1283 if (status == -NFS4ERR_STALE_CLIENTID) 1389 test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
1284 continue; 1390 continue;
1285 if (status == -NFS4ERR_EXPIRED) 1391 if (status < 0)
1286 continue;
1287 if (test_bit(NFS4CLNT_SESSION_SETUP,
1288 &clp->cl_state))
1289 continue;
1290 goto out_error; 1392 goto out_error;
1291 } else
1292 nfs4_state_end_reclaim_nograce(clp);
1293 continue;
1294 } 1393 }
1295 1394
1395 nfs4_end_drain_session(clp);
1296 if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { 1396 if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) {
1297 nfs_client_return_marked_delegations(clp); 1397 nfs_client_return_marked_delegations(clp);
1298 continue; 1398 continue;
@@ -1309,8 +1409,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
1309out_error: 1409out_error:
1310 printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" 1410 printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s"
1311 " with error %d\n", clp->cl_hostname, -status); 1411 " with error %d\n", clp->cl_hostname, -status);
1312 if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) 1412 nfs4_end_drain_session(clp);
1313 nfs4_state_end_reclaim_reboot(clp);
1314 nfs4_clear_state_manager_bit(clp); 1413 nfs4_clear_state_manager_bit(clp);
1315} 1414}
1316 1415
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 83ad47cbdd8a..e437fd6a819f 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -46,11 +46,13 @@
46#include <linux/proc_fs.h> 46#include <linux/proc_fs.h>
47#include <linux/kdev_t.h> 47#include <linux/kdev_t.h>
48#include <linux/sunrpc/clnt.h> 48#include <linux/sunrpc/clnt.h>
49#include <linux/sunrpc/msg_prot.h>
49#include <linux/nfs.h> 50#include <linux/nfs.h>
50#include <linux/nfs4.h> 51#include <linux/nfs4.h>
51#include <linux/nfs_fs.h> 52#include <linux/nfs_fs.h>
52#include <linux/nfs_idmap.h> 53#include <linux/nfs_idmap.h>
53#include "nfs4_fs.h" 54#include "nfs4_fs.h"
55#include "internal.h"
54 56
55#define NFSDBG_FACILITY NFSDBG_XDR 57#define NFSDBG_FACILITY NFSDBG_XDR
56 58
@@ -134,7 +136,7 @@ static int nfs4_stat_to_errno(int);
134#define decode_lookup_maxsz (op_decode_hdr_maxsz) 136#define decode_lookup_maxsz (op_decode_hdr_maxsz)
135#define encode_share_access_maxsz \ 137#define encode_share_access_maxsz \
136 (2) 138 (2)
137#define encode_createmode_maxsz (1 + encode_attrs_maxsz) 139#define encode_createmode_maxsz (1 + encode_attrs_maxsz + encode_verifier_maxsz)
138#define encode_opentype_maxsz (1 + encode_createmode_maxsz) 140#define encode_opentype_maxsz (1 + encode_createmode_maxsz)
139#define encode_claim_null_maxsz (1 + nfs4_name_maxsz) 141#define encode_claim_null_maxsz (1 + nfs4_name_maxsz)
140#define encode_open_maxsz (op_encode_hdr_maxsz + \ 142#define encode_open_maxsz (op_encode_hdr_maxsz + \
@@ -299,6 +301,8 @@ static int nfs4_stat_to_errno(int);
299 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4) 301 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4)
300#define decode_sequence_maxsz (op_decode_hdr_maxsz + \ 302#define decode_sequence_maxsz (op_decode_hdr_maxsz + \
301 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) 303 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)
304#define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4)
305#define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4)
302#else /* CONFIG_NFS_V4_1 */ 306#else /* CONFIG_NFS_V4_1 */
303#define encode_sequence_maxsz 0 307#define encode_sequence_maxsz 0
304#define decode_sequence_maxsz 0 308#define decode_sequence_maxsz 0
@@ -676,6 +680,25 @@ static int nfs4_stat_to_errno(int);
676 decode_sequence_maxsz + \ 680 decode_sequence_maxsz + \
677 decode_putrootfh_maxsz + \ 681 decode_putrootfh_maxsz + \
678 decode_fsinfo_maxsz) 682 decode_fsinfo_maxsz)
683#define NFS4_enc_reclaim_complete_sz (compound_encode_hdr_maxsz + \
684 encode_sequence_maxsz + \
685 encode_reclaim_complete_maxsz)
686#define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \
687 decode_sequence_maxsz + \
688 decode_reclaim_complete_maxsz)
689
690const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
691 compound_encode_hdr_maxsz +
692 encode_sequence_maxsz +
693 encode_putfh_maxsz +
694 encode_getattr_maxsz) *
695 XDR_UNIT);
696
697const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
698 compound_decode_hdr_maxsz +
699 decode_sequence_maxsz +
700 decode_putfh_maxsz) *
701 XDR_UNIT);
679#endif /* CONFIG_NFS_V4_1 */ 702#endif /* CONFIG_NFS_V4_1 */
680 703
681static const umode_t nfs_type2fmt[] = { 704static const umode_t nfs_type2fmt[] = {
@@ -1140,6 +1163,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
1140static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) 1163static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
1141{ 1164{
1142 __be32 *p; 1165 __be32 *p;
1166 struct nfs_client *clp;
1143 1167
1144 p = reserve_space(xdr, 4); 1168 p = reserve_space(xdr, 4);
1145 switch(arg->open_flags & O_EXCL) { 1169 switch(arg->open_flags & O_EXCL) {
@@ -1148,8 +1172,23 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
1148 encode_attrs(xdr, arg->u.attrs, arg->server); 1172 encode_attrs(xdr, arg->u.attrs, arg->server);
1149 break; 1173 break;
1150 default: 1174 default:
1151 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); 1175 clp = arg->server->nfs_client;
1152 encode_nfs4_verifier(xdr, &arg->u.verifier); 1176 if (clp->cl_minorversion > 0) {
1177 if (nfs4_has_persistent_session(clp)) {
1178 *p = cpu_to_be32(NFS4_CREATE_GUARDED);
1179 encode_attrs(xdr, arg->u.attrs, arg->server);
1180 } else {
1181 struct iattr dummy;
1182
1183 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
1184 encode_nfs4_verifier(xdr, &arg->u.verifier);
1185 dummy.ia_valid = 0;
1186 encode_attrs(xdr, &dummy, arg->server);
1187 }
1188 } else {
1189 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
1190 encode_nfs4_verifier(xdr, &arg->u.verifier);
1191 }
1153 } 1192 }
1154} 1193}
1155 1194
@@ -1592,6 +1631,19 @@ static void encode_destroy_session(struct xdr_stream *xdr,
1592 hdr->nops++; 1631 hdr->nops++;
1593 hdr->replen += decode_destroy_session_maxsz; 1632 hdr->replen += decode_destroy_session_maxsz;
1594} 1633}
1634
1635static void encode_reclaim_complete(struct xdr_stream *xdr,
1636 struct nfs41_reclaim_complete_args *args,
1637 struct compound_hdr *hdr)
1638{
1639 __be32 *p;
1640
1641 p = reserve_space(xdr, 8);
1642 *p++ = cpu_to_be32(OP_RECLAIM_COMPLETE);
1643 *p++ = cpu_to_be32(args->one_fs);
1644 hdr->nops++;
1645 hdr->replen += decode_reclaim_complete_maxsz;
1646}
1595#endif /* CONFIG_NFS_V4_1 */ 1647#endif /* CONFIG_NFS_V4_1 */
1596 1648
1597static void encode_sequence(struct xdr_stream *xdr, 1649static void encode_sequence(struct xdr_stream *xdr,
@@ -2096,7 +2148,7 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
2096 encode_compound_hdr(&xdr, req, &hdr); 2148 encode_compound_hdr(&xdr, req, &hdr);
2097 encode_sequence(&xdr, &args->seq_args, &hdr); 2149 encode_sequence(&xdr, &args->seq_args, &hdr);
2098 encode_putfh(&xdr, args->fh, &hdr); 2150 encode_putfh(&xdr, args->fh, &hdr);
2099 replen = hdr.replen + nfs4_fattr_bitmap_maxsz + 1; 2151 replen = hdr.replen + op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz + 1;
2100 encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr); 2152 encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr);
2101 2153
2102 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, 2154 xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
@@ -2420,6 +2472,26 @@ static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p,
2420 encode_nops(&hdr); 2472 encode_nops(&hdr);
2421 return 0; 2473 return 0;
2422} 2474}
2475
2476/*
2477 * a RECLAIM_COMPLETE request
2478 */
2479static int nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req, uint32_t *p,
2480 struct nfs41_reclaim_complete_args *args)
2481{
2482 struct xdr_stream xdr;
2483 struct compound_hdr hdr = {
2484 .minorversion = nfs4_xdr_minorversion(&args->seq_args)
2485 };
2486
2487 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2488 encode_compound_hdr(&xdr, req, &hdr);
2489 encode_sequence(&xdr, &args->seq_args, &hdr);
2490 encode_reclaim_complete(&xdr, args, &hdr);
2491 encode_nops(&hdr);
2492 return 0;
2493}
2494
2423#endif /* CONFIG_NFS_V4_1 */ 2495#endif /* CONFIG_NFS_V4_1 */
2424 2496
2425static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) 2497static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
@@ -4528,6 +4600,11 @@ static int decode_destroy_session(struct xdr_stream *xdr, void *dummy)
4528{ 4600{
4529 return decode_op_hdr(xdr, OP_DESTROY_SESSION); 4601 return decode_op_hdr(xdr, OP_DESTROY_SESSION);
4530} 4602}
4603
4604static int decode_reclaim_complete(struct xdr_stream *xdr, void *dummy)
4605{
4606 return decode_op_hdr(xdr, OP_RECLAIM_COMPLETE);
4607}
4531#endif /* CONFIG_NFS_V4_1 */ 4608#endif /* CONFIG_NFS_V4_1 */
4532 4609
4533static int decode_sequence(struct xdr_stream *xdr, 4610static int decode_sequence(struct xdr_stream *xdr,
@@ -4583,8 +4660,8 @@ static int decode_sequence(struct xdr_stream *xdr,
4583 dummy = be32_to_cpup(p++); 4660 dummy = be32_to_cpup(p++);
4584 /* target highest slot id - currently not processed */ 4661 /* target highest slot id - currently not processed */
4585 dummy = be32_to_cpup(p++); 4662 dummy = be32_to_cpup(p++);
4586 /* result flags - currently not processed */ 4663 /* result flags */
4587 dummy = be32_to_cpup(p); 4664 res->sr_status_flags = be32_to_cpup(p);
4588 status = 0; 4665 status = 0;
4589out_err: 4666out_err:
4590 res->sr_status = status; 4667 res->sr_status = status;
@@ -5309,7 +5386,7 @@ out:
5309} 5386}
5310 5387
5311/* 5388/*
5312 * FSINFO request 5389 * Decode FSINFO response
5313 */ 5390 */
5314static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, 5391static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p,
5315 struct nfs4_fsinfo_res *res) 5392 struct nfs4_fsinfo_res *res)
@@ -5330,7 +5407,7 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p,
5330} 5407}
5331 5408
5332/* 5409/*
5333 * PATHCONF request 5410 * Decode PATHCONF response
5334 */ 5411 */
5335static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, 5412static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p,
5336 struct nfs4_pathconf_res *res) 5413 struct nfs4_pathconf_res *res)
@@ -5351,7 +5428,7 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p,
5351} 5428}
5352 5429
5353/* 5430/*
5354 * STATFS request 5431 * Decode STATFS response
5355 */ 5432 */
5356static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, 5433static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p,
5357 struct nfs4_statfs_res *res) 5434 struct nfs4_statfs_res *res)
@@ -5372,7 +5449,7 @@ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p,
5372} 5449}
5373 5450
5374/* 5451/*
5375 * GETATTR_BITMAP request 5452 * Decode GETATTR_BITMAP response
5376 */ 5453 */
5377static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4_server_caps_res *res) 5454static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4_server_caps_res *res)
5378{ 5455{
@@ -5411,7 +5488,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy)
5411} 5488}
5412 5489
5413/* 5490/*
5414 * a SETCLIENTID request 5491 * Decode SETCLIENTID response
5415 */ 5492 */
5416static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p, 5493static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
5417 struct nfs_client *clp) 5494 struct nfs_client *clp)
@@ -5428,7 +5505,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
5428} 5505}
5429 5506
5430/* 5507/*
5431 * a SETCLIENTID_CONFIRM request 5508 * Decode SETCLIENTID_CONFIRM response
5432 */ 5509 */
5433static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo) 5510static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo)
5434{ 5511{
@@ -5448,7 +5525,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
5448} 5525}
5449 5526
5450/* 5527/*
5451 * DELEGRETURN request 5528 * Decode DELEGRETURN response
5452 */ 5529 */
5453static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_delegreturnres *res) 5530static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_delegreturnres *res)
5454{ 5531{
@@ -5474,7 +5551,7 @@ out:
5474} 5551}
5475 5552
5476/* 5553/*
5477 * FS_LOCATIONS request 5554 * Decode FS_LOCATIONS response
5478 */ 5555 */
5479static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, 5556static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p,
5480 struct nfs4_fs_locations_res *res) 5557 struct nfs4_fs_locations_res *res)
@@ -5504,7 +5581,7 @@ out:
5504 5581
5505#if defined(CONFIG_NFS_V4_1) 5582#if defined(CONFIG_NFS_V4_1)
5506/* 5583/*
5507 * EXCHANGE_ID request 5584 * Decode EXCHANGE_ID response
5508 */ 5585 */
5509static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, uint32_t *p, 5586static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, uint32_t *p,
5510 void *res) 5587 void *res)
@@ -5521,7 +5598,7 @@ static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, uint32_t *p,
5521} 5598}
5522 5599
5523/* 5600/*
5524 * a CREATE_SESSION request 5601 * Decode CREATE_SESSION response
5525 */ 5602 */
5526static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, uint32_t *p, 5603static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, uint32_t *p,
5527 struct nfs41_create_session_res *res) 5604 struct nfs41_create_session_res *res)
@@ -5538,7 +5615,7 @@ static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, uint32_t *p,
5538} 5615}
5539 5616
5540/* 5617/*
5541 * a DESTROY_SESSION request 5618 * Decode DESTROY_SESSION response
5542 */ 5619 */
5543static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp, uint32_t *p, 5620static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp, uint32_t *p,
5544 void *dummy) 5621 void *dummy)
@@ -5555,7 +5632,7 @@ static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp, uint32_t *p,
5555} 5632}
5556 5633
5557/* 5634/*
5558 * a SEQUENCE request 5635 * Decode SEQUENCE response
5559 */ 5636 */
5560static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, uint32_t *p, 5637static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, uint32_t *p,
5561 struct nfs4_sequence_res *res) 5638 struct nfs4_sequence_res *res)
@@ -5572,7 +5649,7 @@ static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, uint32_t *p,
5572} 5649}
5573 5650
5574/* 5651/*
5575 * a GET_LEASE_TIME request 5652 * Decode GET_LEASE_TIME response
5576 */ 5653 */
5577static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p, 5654static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p,
5578 struct nfs4_get_lease_time_res *res) 5655 struct nfs4_get_lease_time_res *res)
@@ -5591,6 +5668,25 @@ static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p,
5591 status = decode_fsinfo(&xdr, res->lr_fsinfo); 5668 status = decode_fsinfo(&xdr, res->lr_fsinfo);
5592 return status; 5669 return status;
5593} 5670}
5671
5672/*
5673 * Decode RECLAIM_COMPLETE response
5674 */
5675static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, uint32_t *p,
5676 struct nfs41_reclaim_complete_res *res)
5677{
5678 struct xdr_stream xdr;
5679 struct compound_hdr hdr;
5680 int status;
5681
5682 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
5683 status = decode_compound_hdr(&xdr, &hdr);
5684 if (!status)
5685 status = decode_sequence(&xdr, &res->seq_res, rqstp);
5686 if (!status)
5687 status = decode_reclaim_complete(&xdr, (void *)NULL);
5688 return status;
5689}
5594#endif /* CONFIG_NFS_V4_1 */ 5690#endif /* CONFIG_NFS_V4_1 */
5595 5691
5596__be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) 5692__be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
@@ -5681,7 +5777,6 @@ static struct {
5681 { NFS4ERR_SERVERFAULT, -ESERVERFAULT }, 5777 { NFS4ERR_SERVERFAULT, -ESERVERFAULT },
5682 { NFS4ERR_BADTYPE, -EBADTYPE }, 5778 { NFS4ERR_BADTYPE, -EBADTYPE },
5683 { NFS4ERR_LOCKED, -EAGAIN }, 5779 { NFS4ERR_LOCKED, -EAGAIN },
5684 { NFS4ERR_RESOURCE, -EREMOTEIO },
5685 { NFS4ERR_SYMLINK, -ELOOP }, 5780 { NFS4ERR_SYMLINK, -ELOOP },
5686 { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP }, 5781 { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP },
5687 { NFS4ERR_DEADLOCK, -EDEADLK }, 5782 { NFS4ERR_DEADLOCK, -EDEADLK },
@@ -5768,6 +5863,7 @@ struct rpc_procinfo nfs4_procedures[] = {
5768 PROC(DESTROY_SESSION, enc_destroy_session, dec_destroy_session), 5863 PROC(DESTROY_SESSION, enc_destroy_session, dec_destroy_session),
5769 PROC(SEQUENCE, enc_sequence, dec_sequence), 5864 PROC(SEQUENCE, enc_sequence, dec_sequence),
5770 PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time), 5865 PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time),
5866 PROC(RECLAIM_COMPLETE, enc_reclaim_complete, dec_reclaim_complete),
5771#endif /* CONFIG_NFS_V4_1 */ 5867#endif /* CONFIG_NFS_V4_1 */
5772}; 5868};
5773 5869
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 12c9e66d3f1d..db9b360ae19d 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -356,25 +356,19 @@ static void nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data
356 struct nfs_readres *resp = &data->res; 356 struct nfs_readres *resp = &data->res;
357 357
358 if (resp->eof || resp->count == argp->count) 358 if (resp->eof || resp->count == argp->count)
359 goto out; 359 return;
360 360
361 /* This is a short read! */ 361 /* This is a short read! */
362 nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); 362 nfs_inc_stats(data->inode, NFSIOS_SHORTREAD);
363 /* Has the server at least made some progress? */ 363 /* Has the server at least made some progress? */
364 if (resp->count == 0) 364 if (resp->count == 0)
365 goto out; 365 return;
366 366
367 /* Yes, so retry the read at the end of the data */ 367 /* Yes, so retry the read at the end of the data */
368 argp->offset += resp->count; 368 argp->offset += resp->count;
369 argp->pgbase += resp->count; 369 argp->pgbase += resp->count;
370 argp->count -= resp->count; 370 argp->count -= resp->count;
371 nfs4_restart_rpc(task, NFS_SERVER(data->inode)->nfs_client); 371 nfs_restart_rpc(task, NFS_SERVER(data->inode)->nfs_client);
372 return;
373out:
374 nfs4_sequence_free_slot(NFS_SERVER(data->inode)->nfs_client,
375 &data->res.seq_res);
376 return;
377
378} 372}
379 373
380/* 374/*
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 90be551b80c1..ce907efc5508 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -175,14 +175,16 @@ static const match_table_t nfs_mount_option_tokens = {
175}; 175};
176 176
177enum { 177enum {
178 Opt_xprt_udp, Opt_xprt_tcp, Opt_xprt_rdma, 178 Opt_xprt_udp, Opt_xprt_udp6, Opt_xprt_tcp, Opt_xprt_tcp6, Opt_xprt_rdma,
179 179
180 Opt_xprt_err 180 Opt_xprt_err
181}; 181};
182 182
183static const match_table_t nfs_xprt_protocol_tokens = { 183static const match_table_t nfs_xprt_protocol_tokens = {
184 { Opt_xprt_udp, "udp" }, 184 { Opt_xprt_udp, "udp" },
185 { Opt_xprt_udp6, "udp6" },
185 { Opt_xprt_tcp, "tcp" }, 186 { Opt_xprt_tcp, "tcp" },
187 { Opt_xprt_tcp6, "tcp6" },
186 { Opt_xprt_rdma, "rdma" }, 188 { Opt_xprt_rdma, "rdma" },
187 189
188 { Opt_xprt_err, NULL } 190 { Opt_xprt_err, NULL }
@@ -492,6 +494,45 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
492 return sec_flavours[i].str; 494 return sec_flavours[i].str;
493} 495}
494 496
497static void nfs_show_mountd_netid(struct seq_file *m, struct nfs_server *nfss,
498 int showdefaults)
499{
500 struct sockaddr *sap = (struct sockaddr *) &nfss->mountd_address;
501
502 seq_printf(m, ",mountproto=");
503 switch (sap->sa_family) {
504 case AF_INET:
505 switch (nfss->mountd_protocol) {
506 case IPPROTO_UDP:
507 seq_printf(m, RPCBIND_NETID_UDP);
508 break;
509 case IPPROTO_TCP:
510 seq_printf(m, RPCBIND_NETID_TCP);
511 break;
512 default:
513 if (showdefaults)
514 seq_printf(m, "auto");
515 }
516 break;
517 case AF_INET6:
518 switch (nfss->mountd_protocol) {
519 case IPPROTO_UDP:
520 seq_printf(m, RPCBIND_NETID_UDP6);
521 break;
522 case IPPROTO_TCP:
523 seq_printf(m, RPCBIND_NETID_TCP6);
524 break;
525 default:
526 if (showdefaults)
527 seq_printf(m, "auto");
528 }
529 break;
530 default:
531 if (showdefaults)
532 seq_printf(m, "auto");
533 }
534}
535
495static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, 536static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
496 int showdefaults) 537 int showdefaults)
497{ 538{
@@ -505,7 +546,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
505 } 546 }
506 case AF_INET6: { 547 case AF_INET6: {
507 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; 548 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
508 seq_printf(m, ",mountaddr=%pI6", &sin6->sin6_addr); 549 seq_printf(m, ",mountaddr=%pI6c", &sin6->sin6_addr);
509 break; 550 break;
510 } 551 }
511 default: 552 default:
@@ -518,17 +559,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
518 if (nfss->mountd_port || showdefaults) 559 if (nfss->mountd_port || showdefaults)
519 seq_printf(m, ",mountport=%u", nfss->mountd_port); 560 seq_printf(m, ",mountport=%u", nfss->mountd_port);
520 561
521 switch (nfss->mountd_protocol) { 562 nfs_show_mountd_netid(m, nfss, showdefaults);
522 case IPPROTO_UDP:
523 seq_printf(m, ",mountproto=udp");
524 break;
525 case IPPROTO_TCP:
526 seq_printf(m, ",mountproto=tcp");
527 break;
528 default:
529 if (showdefaults)
530 seq_printf(m, ",mountproto=auto");
531 }
532} 563}
533 564
534/* 565/*
@@ -578,7 +609,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
578 seq_puts(m, nfs_infop->nostr); 609 seq_puts(m, nfs_infop->nostr);
579 } 610 }
580 seq_printf(m, ",proto=%s", 611 seq_printf(m, ",proto=%s",
581 rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO)); 612 rpc_peeraddr2str(nfss->client, RPC_DISPLAY_NETID));
582 if (version == 4) { 613 if (version == 4) {
583 if (nfss->port != NFS_PORT) 614 if (nfss->port != NFS_PORT)
584 seq_printf(m, ",port=%u", nfss->port); 615 seq_printf(m, ",port=%u", nfss->port);
@@ -714,8 +745,6 @@ static void nfs_umount_begin(struct super_block *sb)
714 struct nfs_server *server; 745 struct nfs_server *server;
715 struct rpc_clnt *rpc; 746 struct rpc_clnt *rpc;
716 747
717 lock_kernel();
718
719 server = NFS_SB(sb); 748 server = NFS_SB(sb);
720 /* -EIO all pending I/O */ 749 /* -EIO all pending I/O */
721 rpc = server->client_acl; 750 rpc = server->client_acl;
@@ -724,8 +753,6 @@ static void nfs_umount_begin(struct super_block *sb)
724 rpc = server->client; 753 rpc = server->client;
725 if (!IS_ERR(rpc)) 754 if (!IS_ERR(rpc))
726 rpc_killall_tasks(rpc); 755 rpc_killall_tasks(rpc);
727
728 unlock_kernel();
729} 756}
730 757
731static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version) 758static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version)
@@ -734,8 +761,6 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve
734 761
735 data = kzalloc(sizeof(*data), GFP_KERNEL); 762 data = kzalloc(sizeof(*data), GFP_KERNEL);
736 if (data) { 763 if (data) {
737 data->rsize = NFS_MAX_FILE_IO_SIZE;
738 data->wsize = NFS_MAX_FILE_IO_SIZE;
739 data->acregmin = NFS_DEF_ACREGMIN; 764 data->acregmin = NFS_DEF_ACREGMIN;
740 data->acregmax = NFS_DEF_ACREGMAX; 765 data->acregmax = NFS_DEF_ACREGMAX;
741 data->acdirmin = NFS_DEF_ACDIRMIN; 766 data->acdirmin = NFS_DEF_ACDIRMIN;
@@ -887,6 +912,8 @@ static int nfs_parse_mount_options(char *raw,
887{ 912{
888 char *p, *string, *secdata; 913 char *p, *string, *secdata;
889 int rc, sloppy = 0, invalid_option = 0; 914 int rc, sloppy = 0, invalid_option = 0;
915 unsigned short protofamily = AF_UNSPEC;
916 unsigned short mountfamily = AF_UNSPEC;
890 917
891 if (!raw) { 918 if (!raw) {
892 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 919 dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
@@ -1232,12 +1259,17 @@ static int nfs_parse_mount_options(char *raw,
1232 token = match_token(string, 1259 token = match_token(string,
1233 nfs_xprt_protocol_tokens, args); 1260 nfs_xprt_protocol_tokens, args);
1234 1261
1262 protofamily = AF_INET;
1235 switch (token) { 1263 switch (token) {
1264 case Opt_xprt_udp6:
1265 protofamily = AF_INET6;
1236 case Opt_xprt_udp: 1266 case Opt_xprt_udp:
1237 mnt->flags &= ~NFS_MOUNT_TCP; 1267 mnt->flags &= ~NFS_MOUNT_TCP;
1238 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1268 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1239 kfree(string); 1269 kfree(string);
1240 break; 1270 break;
1271 case Opt_xprt_tcp6:
1272 protofamily = AF_INET6;
1241 case Opt_xprt_tcp: 1273 case Opt_xprt_tcp:
1242 mnt->flags |= NFS_MOUNT_TCP; 1274 mnt->flags |= NFS_MOUNT_TCP;
1243 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1275 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
@@ -1265,10 +1297,15 @@ static int nfs_parse_mount_options(char *raw,
1265 nfs_xprt_protocol_tokens, args); 1297 nfs_xprt_protocol_tokens, args);
1266 kfree(string); 1298 kfree(string);
1267 1299
1300 mountfamily = AF_INET;
1268 switch (token) { 1301 switch (token) {
1302 case Opt_xprt_udp6:
1303 mountfamily = AF_INET6;
1269 case Opt_xprt_udp: 1304 case Opt_xprt_udp:
1270 mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; 1305 mnt->mount_server.protocol = XPRT_TRANSPORT_UDP;
1271 break; 1306 break;
1307 case Opt_xprt_tcp6:
1308 mountfamily = AF_INET6;
1272 case Opt_xprt_tcp: 1309 case Opt_xprt_tcp:
1273 mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; 1310 mnt->mount_server.protocol = XPRT_TRANSPORT_TCP;
1274 break; 1311 break;
@@ -1367,8 +1404,33 @@ static int nfs_parse_mount_options(char *raw,
1367 if (!sloppy && invalid_option) 1404 if (!sloppy && invalid_option)
1368 return 0; 1405 return 0;
1369 1406
1407 /*
1408 * verify that any proto=/mountproto= options match the address
1409 * familiies in the addr=/mountaddr= options.
1410 */
1411 if (protofamily != AF_UNSPEC &&
1412 protofamily != mnt->nfs_server.address.ss_family)
1413 goto out_proto_mismatch;
1414
1415 if (mountfamily != AF_UNSPEC) {
1416 if (mnt->mount_server.addrlen) {
1417 if (mountfamily != mnt->mount_server.address.ss_family)
1418 goto out_mountproto_mismatch;
1419 } else {
1420 if (mountfamily != mnt->nfs_server.address.ss_family)
1421 goto out_mountproto_mismatch;
1422 }
1423 }
1424
1370 return 1; 1425 return 1;
1371 1426
1427out_mountproto_mismatch:
1428 printk(KERN_INFO "NFS: mount server address does not match mountproto= "
1429 "option\n");
1430 return 0;
1431out_proto_mismatch:
1432 printk(KERN_INFO "NFS: server address does not match proto= option\n");
1433 return 0;
1372out_invalid_address: 1434out_invalid_address:
1373 printk(KERN_INFO "NFS: bad IP address specified: %s\n", p); 1435 printk(KERN_INFO "NFS: bad IP address specified: %s\n", p);
1374 return 0; 1436 return 0;
@@ -1881,7 +1943,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
1881 if (data == NULL) 1943 if (data == NULL)
1882 return -ENOMEM; 1944 return -ENOMEM;
1883 1945
1884 lock_kernel();
1885 /* fill out struct with values from existing mount */ 1946 /* fill out struct with values from existing mount */
1886 data->flags = nfss->flags; 1947 data->flags = nfss->flags;
1887 data->rsize = nfss->rsize; 1948 data->rsize = nfss->rsize;
@@ -1907,7 +1968,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
1907 error = nfs_compare_remount_data(nfss, data); 1968 error = nfs_compare_remount_data(nfss, data);
1908out: 1969out:
1909 kfree(data); 1970 kfree(data);
1910 unlock_kernel();
1911 return error; 1971 return error;
1912} 1972}
1913 1973
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c
index b62481dabae9..70e1fbbaaeab 100644
--- a/fs/nfs/sysctl.c
+++ b/fs/nfs/sysctl.c
@@ -22,63 +22,55 @@ static struct ctl_table_header *nfs_callback_sysctl_table;
22static ctl_table nfs_cb_sysctls[] = { 22static ctl_table nfs_cb_sysctls[] = {
23#ifdef CONFIG_NFS_V4 23#ifdef CONFIG_NFS_V4
24 { 24 {
25 .ctl_name = CTL_UNNUMBERED,
26 .procname = "nfs_callback_tcpport", 25 .procname = "nfs_callback_tcpport",
27 .data = &nfs_callback_set_tcpport, 26 .data = &nfs_callback_set_tcpport,
28 .maxlen = sizeof(int), 27 .maxlen = sizeof(int),
29 .mode = 0644, 28 .mode = 0644,
30 .proc_handler = &proc_dointvec_minmax, 29 .proc_handler = proc_dointvec_minmax,
31 .extra1 = (int *)&nfs_set_port_min, 30 .extra1 = (int *)&nfs_set_port_min,
32 .extra2 = (int *)&nfs_set_port_max, 31 .extra2 = (int *)&nfs_set_port_max,
33 }, 32 },
34 { 33 {
35 .ctl_name = CTL_UNNUMBERED,
36 .procname = "idmap_cache_timeout", 34 .procname = "idmap_cache_timeout",
37 .data = &nfs_idmap_cache_timeout, 35 .data = &nfs_idmap_cache_timeout,
38 .maxlen = sizeof(int), 36 .maxlen = sizeof(int),
39 .mode = 0644, 37 .mode = 0644,
40 .proc_handler = &proc_dointvec_jiffies, 38 .proc_handler = proc_dointvec_jiffies,
41 .strategy = &sysctl_jiffies,
42 }, 39 },
43#endif 40#endif
44 { 41 {
45 .ctl_name = CTL_UNNUMBERED,
46 .procname = "nfs_mountpoint_timeout", 42 .procname = "nfs_mountpoint_timeout",
47 .data = &nfs_mountpoint_expiry_timeout, 43 .data = &nfs_mountpoint_expiry_timeout,
48 .maxlen = sizeof(nfs_mountpoint_expiry_timeout), 44 .maxlen = sizeof(nfs_mountpoint_expiry_timeout),
49 .mode = 0644, 45 .mode = 0644,
50 .proc_handler = &proc_dointvec_jiffies, 46 .proc_handler = proc_dointvec_jiffies,
51 .strategy = &sysctl_jiffies,
52 }, 47 },
53 { 48 {
54 .ctl_name = CTL_UNNUMBERED,
55 .procname = "nfs_congestion_kb", 49 .procname = "nfs_congestion_kb",
56 .data = &nfs_congestion_kb, 50 .data = &nfs_congestion_kb,
57 .maxlen = sizeof(nfs_congestion_kb), 51 .maxlen = sizeof(nfs_congestion_kb),
58 .mode = 0644, 52 .mode = 0644,
59 .proc_handler = &proc_dointvec, 53 .proc_handler = proc_dointvec,
60 }, 54 },
61 { .ctl_name = 0 } 55 { }
62}; 56};
63 57
64static ctl_table nfs_cb_sysctl_dir[] = { 58static ctl_table nfs_cb_sysctl_dir[] = {
65 { 59 {
66 .ctl_name = CTL_UNNUMBERED,
67 .procname = "nfs", 60 .procname = "nfs",
68 .mode = 0555, 61 .mode = 0555,
69 .child = nfs_cb_sysctls, 62 .child = nfs_cb_sysctls,
70 }, 63 },
71 { .ctl_name = 0 } 64 { }
72}; 65};
73 66
74static ctl_table nfs_cb_sysctl_root[] = { 67static ctl_table nfs_cb_sysctl_root[] = {
75 { 68 {
76 .ctl_name = CTL_FS,
77 .procname = "fs", 69 .procname = "fs",
78 .mode = 0555, 70 .mode = 0555,
79 .child = nfs_cb_sysctl_dir, 71 .child = nfs_cb_sysctl_dir,
80 }, 72 },
81 { .ctl_name = 0 } 73 { }
82}; 74};
83 75
84int nfs_register_sysctl(void) 76int nfs_register_sysctl(void)
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 1064c91ae810..6da3d3ff6edd 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -83,7 +83,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
83 struct inode *dir = data->dir; 83 struct inode *dir = data->dir;
84 84
85 if (!NFS_PROTO(dir)->unlink_done(task, dir)) 85 if (!NFS_PROTO(dir)->unlink_done(task, dir))
86 nfs4_restart_rpc(task, NFS_SERVER(dir)->nfs_client); 86 nfs_restart_rpc(task, NFS_SERVER(dir)->nfs_client);
87} 87}
88 88
89/** 89/**
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 53eb26c16b50..d171696017f4 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -178,7 +178,7 @@ static int wb_priority(struct writeback_control *wbc)
178{ 178{
179 if (wbc->for_reclaim) 179 if (wbc->for_reclaim)
180 return FLUSH_HIGHPRI | FLUSH_STABLE; 180 return FLUSH_HIGHPRI | FLUSH_STABLE;
181 if (wbc->for_kupdate) 181 if (wbc->for_kupdate || wbc->for_background)
182 return FLUSH_LOWPRI; 182 return FLUSH_LOWPRI;
183 return 0; 183 return 0;
184} 184}
@@ -774,7 +774,7 @@ int nfs_updatepage(struct file *file, struct page *page,
774 */ 774 */
775 if (nfs_write_pageuptodate(page, inode) && 775 if (nfs_write_pageuptodate(page, inode) &&
776 inode->i_flock == NULL && 776 inode->i_flock == NULL &&
777 !(file->f_flags & O_SYNC)) { 777 !(file->f_flags & O_DSYNC)) {
778 count = max(count + offset, nfs_page_length(page)); 778 count = max(count + offset, nfs_page_length(page));
779 offset = 0; 779 offset = 0;
780 } 780 }
@@ -1216,7 +1216,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1216 */ 1216 */
1217 argp->stable = NFS_FILE_SYNC; 1217 argp->stable = NFS_FILE_SYNC;
1218 } 1218 }
1219 nfs4_restart_rpc(task, server->nfs_client); 1219 nfs_restart_rpc(task, server->nfs_client);
1220 return -EAGAIN; 1220 return -EAGAIN;
1221 } 1221 }
1222 if (time_before(complain, jiffies)) { 1222 if (time_before(complain, jiffies)) {
@@ -1228,7 +1228,6 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1228 /* Can't do anything about it except throw an error. */ 1228 /* Can't do anything about it except throw an error. */
1229 task->tk_status = -EIO; 1229 task->tk_status = -EIO;
1230 } 1230 }
1231 nfs4_sequence_free_slot(server->nfs_client, &data->res.seq_res);
1232 return 0; 1231 return 0;
1233} 1232}
1234 1233
@@ -1612,15 +1611,16 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
1612 if (ret) 1611 if (ret)
1613 goto out_unlock; 1612 goto out_unlock;
1614 page_cache_get(newpage); 1613 page_cache_get(newpage);
1614 spin_lock(&mapping->host->i_lock);
1615 req->wb_page = newpage; 1615 req->wb_page = newpage;
1616 SetPagePrivate(newpage); 1616 SetPagePrivate(newpage);
1617 set_page_private(newpage, page_private(page)); 1617 set_page_private(newpage, (unsigned long)req);
1618 ClearPagePrivate(page); 1618 ClearPagePrivate(page);
1619 set_page_private(page, 0); 1619 set_page_private(page, 0);
1620 spin_unlock(&mapping->host->i_lock);
1620 page_cache_release(page); 1621 page_cache_release(page);
1621out_unlock: 1622out_unlock:
1622 nfs_clear_page_tag_locked(req); 1623 nfs_clear_page_tag_locked(req);
1623 nfs_release_request(req);
1624out: 1624out:
1625 return ret; 1625 return ret;
1626} 1626}