aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-05 16:25:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-05 16:25:45 -0500
commitcc7889ff5ee7a1c1a2b5073c53db5ad9b76f14e2 (patch)
tree647e11872abe7c20c0145de9adbb60f15085dad0 /fs
parentb13d3c6e8ab6ac53e8c1858a9c837cb6ba3bbef0 (diff)
parent3fa04ecd72780da31ba8b329e148179bc24a9c7d (diff)
Merge branch 'nfs-for-2.6.34' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
* 'nfs-for-2.6.34' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6: (44 commits) NFS: Remove requirement for inode->i_mutex from nfs_invalidate_mapping NFS: Clean up nfs_sync_mapping NFS: Simplify nfs_wb_page() NFS: Replace __nfs_write_mapping with sync_inode() NFS: Simplify nfs_wb_page_cancel() NFS: Ensure inode is always marked I_DIRTY_DATASYNC, if it has unstable pages NFS: Run COMMIT as an asynchronous RPC call when wbc->for_background is set NFS: Reduce the number of unnecessary COMMIT calls NFS: Add a count of the number of unstable writes carried by an inode NFS: Cleanup - move nfs_write_inode() into fs/nfs/write.c nfs41 fix NFS4ERR_CLID_INUSE for exchange id NFS: Fix an allocation-under-spinlock bug SUNRPC: Handle EINVAL error returns from the TCP connect operation NFSv4.1: Various fixes to the sequence flag error handling nfs4: renewd renew operations should take/put a client reference nfs41: renewd sequence operations should take/put client reference nfs: prevent backlogging of renewd requests nfs: kill renewd before clearing client minor version NFS: Make close(2) asynchronous when closing NFS O_DIRECT files NFS: Improve NFS iostat byte count accuracy for writes ...
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/callback.h8
-rw-r--r--fs/nfs/callback_proc.c165
-rw-r--r--fs/nfs/callback_xdr.c105
-rw-r--r--fs/nfs/client.c48
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/nfs/dns_resolve.c18
-rw-r--r--fs/nfs/file.c30
-rw-r--r--fs/nfs/inode.c90
-rw-r--r--fs/nfs/nfs3proc.c9
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4proc.c103
-rw-r--r--fs/nfs/nfs4renewd.c24
-rw-r--r--fs/nfs/nfs4state.c118
-rw-r--r--fs/nfs/nfs4xdr.c10
-rw-r--r--fs/nfs/proc.c41
-rw-r--r--fs/nfs/symlink.c2
-rw-r--r--fs/nfs/write.c247
17 files changed, 600 insertions, 422 deletions
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index d4036be0b589..85a7cfd1b8dd 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -119,6 +119,14 @@ struct cb_recallanyargs {
119}; 119};
120 120
121extern unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy); 121extern unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy);
122
123struct cb_recallslotargs {
124 struct sockaddr *crsa_addr;
125 uint32_t crsa_target_max_slots;
126};
127extern unsigned nfs4_callback_recallslot(struct cb_recallslotargs *args,
128 void *dummy);
129
122#endif /* CONFIG_NFS_V4_1 */ 130#endif /* CONFIG_NFS_V4_1 */
123 131
124extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res); 132extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res);
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index defa9b4c470e..84761b5bb8e2 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -143,44 +143,49 @@ int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const n
143 * 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
144 * this slot, accounting for wraparound. Increments the slot's sequence. 144 * this slot, accounting for wraparound. Increments the slot's sequence.
145 * 145 *
146 * We don't yet implement a duplicate request cache, so at this time 146 * We don't yet implement a duplicate request cache, instead we set the
147 * we will log replays, and process them as if we had not seen them before, 147 * back channel ca_maxresponsesize_cached to zero. This is OK for now
148 * but we don't bump the sequence in the slot. Not too worried about it,
149 * since we only currently implement idempotent callbacks anyway. 148 * since we only currently implement idempotent callbacks anyway.
150 * 149 *
151 * We have a single slot backchannel at this time, so we don't bother 150 * We have a single slot backchannel at this time, so we don't bother
152 * checking the used_slots bit array on the table. The lower layer guarantees 151 * checking the used_slots bit array on the table. The lower layer guarantees
153 * a single outstanding callback request at a time. 152 * a single outstanding callback request at a time.
154 */ 153 */
155static int 154static __be32
156validate_seqid(struct nfs4_slot_table *tbl, u32 slotid, u32 seqid) 155validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
157{ 156{
158 struct nfs4_slot *slot; 157 struct nfs4_slot *slot;
159 158
160 dprintk("%s enter. slotid %d seqid %d\n", 159 dprintk("%s enter. slotid %d seqid %d\n",
161 __func__, slotid, seqid); 160 __func__, args->csa_slotid, args->csa_sequenceid);
162 161
163 if (slotid > NFS41_BC_MAX_CALLBACKS) 162 if (args->csa_slotid > NFS41_BC_MAX_CALLBACKS)
164 return htonl(NFS4ERR_BADSLOT); 163 return htonl(NFS4ERR_BADSLOT);
165 164
166 slot = tbl->slots + slotid; 165 slot = tbl->slots + args->csa_slotid;
167 dprintk("%s slot table seqid: %d\n", __func__, slot->seq_nr); 166 dprintk("%s slot table seqid: %d\n", __func__, slot->seq_nr);
168 167
169 /* Normal */ 168 /* Normal */
170 if (likely(seqid == slot->seq_nr + 1)) { 169 if (likely(args->csa_sequenceid == slot->seq_nr + 1)) {
171 slot->seq_nr++; 170 slot->seq_nr++;
172 return htonl(NFS4_OK); 171 return htonl(NFS4_OK);
173 } 172 }
174 173
175 /* Replay */ 174 /* Replay */
176 if (seqid == slot->seq_nr) { 175 if (args->csa_sequenceid == slot->seq_nr) {
177 dprintk("%s seqid %d is a replay - no DRC available\n", 176 dprintk("%s seqid %d is a replay\n",
178 __func__, seqid); 177 __func__, args->csa_sequenceid);
179 return htonl(NFS4_OK); 178 /* Signal process_op to set this error on next op */
179 if (args->csa_cachethis == 0)
180 return htonl(NFS4ERR_RETRY_UNCACHED_REP);
181
182 /* The ca_maxresponsesize_cached is 0 with no DRC */
183 else if (args->csa_cachethis == 1)
184 return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE);
180 } 185 }
181 186
182 /* Wraparound */ 187 /* Wraparound */
183 if (seqid == 1 && (slot->seq_nr + 1) == 0) { 188 if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) {
184 slot->seq_nr = 1; 189 slot->seq_nr = 1;
185 return htonl(NFS4_OK); 190 return htonl(NFS4_OK);
186 } 191 }
@@ -225,27 +230,87 @@ validate_seqid(struct nfs4_slot_table *tbl, u32 slotid, u32 seqid)
225 return NULL; 230 return NULL;
226} 231}
227 232
228/* FIXME: referring calls should be processed */ 233/*
229unsigned nfs4_callback_sequence(struct cb_sequenceargs *args, 234 * For each referring call triple, check the session's slot table for
235 * a match. If the slot is in use and the sequence numbers match, the
236 * client is still waiting for a response to the original request.
237 */
238static bool referring_call_exists(struct nfs_client *clp,
239 uint32_t nrclists,
240 struct referring_call_list *rclists)
241{
242 bool status = 0;
243 int i, j;
244 struct nfs4_session *session;
245 struct nfs4_slot_table *tbl;
246 struct referring_call_list *rclist;
247 struct referring_call *ref;
248
249 /*
250 * XXX When client trunking is implemented, this becomes
251 * a session lookup from within the loop
252 */
253 session = clp->cl_session;
254 tbl = &session->fc_slot_table;
255
256 for (i = 0; i < nrclists; i++) {
257 rclist = &rclists[i];
258 if (memcmp(session->sess_id.data,
259 rclist->rcl_sessionid.data,
260 NFS4_MAX_SESSIONID_LEN) != 0)
261 continue;
262
263 for (j = 0; j < rclist->rcl_nrefcalls; j++) {
264 ref = &rclist->rcl_refcalls[j];
265
266 dprintk("%s: sessionid %x:%x:%x:%x sequenceid %u "
267 "slotid %u\n", __func__,
268 ((u32 *)&rclist->rcl_sessionid.data)[0],
269 ((u32 *)&rclist->rcl_sessionid.data)[1],
270 ((u32 *)&rclist->rcl_sessionid.data)[2],
271 ((u32 *)&rclist->rcl_sessionid.data)[3],
272 ref->rc_sequenceid, ref->rc_slotid);
273
274 spin_lock(&tbl->slot_tbl_lock);
275 status = (test_bit(ref->rc_slotid, tbl->used_slots) &&
276 tbl->slots[ref->rc_slotid].seq_nr ==
277 ref->rc_sequenceid);
278 spin_unlock(&tbl->slot_tbl_lock);
279 if (status)
280 goto out;
281 }
282 }
283
284out:
285 return status;
286}
287
288__be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
230 struct cb_sequenceres *res) 289 struct cb_sequenceres *res)
231{ 290{
232 struct nfs_client *clp; 291 struct nfs_client *clp;
233 int i, status; 292 int i;
234 293 __be32 status;
235 for (i = 0; i < args->csa_nrclists; i++)
236 kfree(args->csa_rclists[i].rcl_refcalls);
237 kfree(args->csa_rclists);
238 294
239 status = htonl(NFS4ERR_BADSESSION); 295 status = htonl(NFS4ERR_BADSESSION);
240 clp = find_client_with_session(args->csa_addr, 4, &args->csa_sessionid); 296 clp = find_client_with_session(args->csa_addr, 4, &args->csa_sessionid);
241 if (clp == NULL) 297 if (clp == NULL)
242 goto out; 298 goto out;
243 299
244 status = validate_seqid(&clp->cl_session->bc_slot_table, 300 status = validate_seqid(&clp->cl_session->bc_slot_table, args);
245 args->csa_slotid, args->csa_sequenceid);
246 if (status) 301 if (status)
247 goto out_putclient; 302 goto out_putclient;
248 303
304 /*
305 * Check for pending referring calls. If a match is found, a
306 * related callback was received before the response to the original
307 * call.
308 */
309 if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) {
310 status = htonl(NFS4ERR_DELAY);
311 goto out_putclient;
312 }
313
249 memcpy(&res->csr_sessionid, &args->csa_sessionid, 314 memcpy(&res->csr_sessionid, &args->csa_sessionid,
250 sizeof(res->csr_sessionid)); 315 sizeof(res->csr_sessionid));
251 res->csr_sequenceid = args->csa_sequenceid; 316 res->csr_sequenceid = args->csa_sequenceid;
@@ -256,15 +321,23 @@ unsigned nfs4_callback_sequence(struct cb_sequenceargs *args,
256out_putclient: 321out_putclient:
257 nfs_put_client(clp); 322 nfs_put_client(clp);
258out: 323out:
259 dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); 324 for (i = 0; i < args->csa_nrclists; i++)
260 res->csr_status = status; 325 kfree(args->csa_rclists[i].rcl_refcalls);
261 return res->csr_status; 326 kfree(args->csa_rclists);
327
328 if (status == htonl(NFS4ERR_RETRY_UNCACHED_REP))
329 res->csr_status = 0;
330 else
331 res->csr_status = status;
332 dprintk("%s: exit with status = %d res->csr_status %d\n", __func__,
333 ntohl(status), ntohl(res->csr_status));
334 return status;
262} 335}
263 336
264unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy) 337__be32 nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy)
265{ 338{
266 struct nfs_client *clp; 339 struct nfs_client *clp;
267 int status; 340 __be32 status;
268 fmode_t flags = 0; 341 fmode_t flags = 0;
269 342
270 status = htonl(NFS4ERR_OP_NOT_IN_SESSION); 343 status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
@@ -289,4 +362,40 @@ out:
289 dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); 362 dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
290 return status; 363 return status;
291} 364}
365
366/* Reduce the fore channel's max_slots to the target value */
367__be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy)
368{
369 struct nfs_client *clp;
370 struct nfs4_slot_table *fc_tbl;
371 __be32 status;
372
373 status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
374 clp = nfs_find_client(args->crsa_addr, 4);
375 if (clp == NULL)
376 goto out;
377
378 dprintk("NFS: CB_RECALL_SLOT request from %s target max slots %d\n",
379 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR),
380 args->crsa_target_max_slots);
381
382 fc_tbl = &clp->cl_session->fc_slot_table;
383
384 status = htonl(NFS4ERR_BAD_HIGH_SLOT);
385 if (args->crsa_target_max_slots > fc_tbl->max_slots ||
386 args->crsa_target_max_slots < 1)
387 goto out_putclient;
388
389 status = htonl(NFS4_OK);
390 if (args->crsa_target_max_slots == fc_tbl->max_slots)
391 goto out_putclient;
392
393 fc_tbl->target_max_slots = args->crsa_target_max_slots;
394 nfs41_handle_recall_slot(clp);
395out_putclient:
396 nfs_put_client(clp); /* balance nfs_find_client */
397out:
398 dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
399 return status;
400}
292#endif /* CONFIG_NFS_V4_1 */ 401#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 8e1a2511c8be..db30c0b398b5 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -24,10 +24,14 @@
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#define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
27#define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
27#endif /* CONFIG_NFS_V4_1 */ 28#endif /* CONFIG_NFS_V4_1 */
28 29
29#define NFSDBG_FACILITY NFSDBG_CALLBACK 30#define NFSDBG_FACILITY NFSDBG_CALLBACK
30 31
32/* Internal error code */
33#define NFS4ERR_RESOURCE_HDR 11050
34
31typedef __be32 (*callback_process_op_t)(void *, void *); 35typedef __be32 (*callback_process_op_t)(void *, void *);
32typedef __be32 (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *); 36typedef __be32 (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *);
33typedef __be32 (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *); 37typedef __be32 (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *);
@@ -173,7 +177,7 @@ static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op)
173 __be32 *p; 177 __be32 *p;
174 p = read_buf(xdr, 4); 178 p = read_buf(xdr, 4);
175 if (unlikely(p == NULL)) 179 if (unlikely(p == NULL))
176 return htonl(NFS4ERR_RESOURCE); 180 return htonl(NFS4ERR_RESOURCE_HDR);
177 *op = ntohl(*p); 181 *op = ntohl(*p);
178 return 0; 182 return 0;
179} 183}
@@ -215,10 +219,10 @@ out:
215 219
216#if defined(CONFIG_NFS_V4_1) 220#if defined(CONFIG_NFS_V4_1)
217 221
218static unsigned decode_sessionid(struct xdr_stream *xdr, 222static __be32 decode_sessionid(struct xdr_stream *xdr,
219 struct nfs4_sessionid *sid) 223 struct nfs4_sessionid *sid)
220{ 224{
221 uint32_t *p; 225 __be32 *p;
222 int len = NFS4_MAX_SESSIONID_LEN; 226 int len = NFS4_MAX_SESSIONID_LEN;
223 227
224 p = read_buf(xdr, len); 228 p = read_buf(xdr, len);
@@ -229,12 +233,12 @@ static unsigned decode_sessionid(struct xdr_stream *xdr,
229 return 0; 233 return 0;
230} 234}
231 235
232static unsigned decode_rc_list(struct xdr_stream *xdr, 236static __be32 decode_rc_list(struct xdr_stream *xdr,
233 struct referring_call_list *rc_list) 237 struct referring_call_list *rc_list)
234{ 238{
235 uint32_t *p; 239 __be32 *p;
236 int i; 240 int i;
237 unsigned status; 241 __be32 status;
238 242
239 status = decode_sessionid(xdr, &rc_list->rcl_sessionid); 243 status = decode_sessionid(xdr, &rc_list->rcl_sessionid);
240 if (status) 244 if (status)
@@ -267,13 +271,13 @@ out:
267 return status; 271 return status;
268} 272}
269 273
270static unsigned decode_cb_sequence_args(struct svc_rqst *rqstp, 274static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp,
271 struct xdr_stream *xdr, 275 struct xdr_stream *xdr,
272 struct cb_sequenceargs *args) 276 struct cb_sequenceargs *args)
273{ 277{
274 uint32_t *p; 278 __be32 *p;
275 int i; 279 int i;
276 unsigned status; 280 __be32 status;
277 281
278 status = decode_sessionid(xdr, &args->csa_sessionid); 282 status = decode_sessionid(xdr, &args->csa_sessionid);
279 if (status) 283 if (status)
@@ -327,11 +331,11 @@ out_free:
327 goto out; 331 goto out;
328} 332}
329 333
330static unsigned decode_recallany_args(struct svc_rqst *rqstp, 334static __be32 decode_recallany_args(struct svc_rqst *rqstp,
331 struct xdr_stream *xdr, 335 struct xdr_stream *xdr,
332 struct cb_recallanyargs *args) 336 struct cb_recallanyargs *args)
333{ 337{
334 uint32_t *p; 338 __be32 *p;
335 339
336 args->craa_addr = svc_addr(rqstp); 340 args->craa_addr = svc_addr(rqstp);
337 p = read_buf(xdr, 4); 341 p = read_buf(xdr, 4);
@@ -346,6 +350,20 @@ static unsigned decode_recallany_args(struct svc_rqst *rqstp,
346 return 0; 350 return 0;
347} 351}
348 352
353static __be32 decode_recallslot_args(struct svc_rqst *rqstp,
354 struct xdr_stream *xdr,
355 struct cb_recallslotargs *args)
356{
357 __be32 *p;
358
359 args->crsa_addr = svc_addr(rqstp);
360 p = read_buf(xdr, 4);
361 if (unlikely(p == NULL))
362 return htonl(NFS4ERR_BADXDR);
363 args->crsa_target_max_slots = ntohl(*p++);
364 return 0;
365}
366
349#endif /* CONFIG_NFS_V4_1 */ 367#endif /* CONFIG_NFS_V4_1 */
350 368
351static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) 369static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
@@ -465,7 +483,7 @@ static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res)
465 483
466 p = xdr_reserve_space(xdr, 8); 484 p = xdr_reserve_space(xdr, 8);
467 if (unlikely(p == NULL)) 485 if (unlikely(p == NULL))
468 return htonl(NFS4ERR_RESOURCE); 486 return htonl(NFS4ERR_RESOURCE_HDR);
469 *p++ = htonl(op); 487 *p++ = htonl(op);
470 *p = res; 488 *p = res;
471 return 0; 489 return 0;
@@ -499,10 +517,10 @@ out:
499 517
500#if defined(CONFIG_NFS_V4_1) 518#if defined(CONFIG_NFS_V4_1)
501 519
502static unsigned encode_sessionid(struct xdr_stream *xdr, 520static __be32 encode_sessionid(struct xdr_stream *xdr,
503 const struct nfs4_sessionid *sid) 521 const struct nfs4_sessionid *sid)
504{ 522{
505 uint32_t *p; 523 __be32 *p;
506 int len = NFS4_MAX_SESSIONID_LEN; 524 int len = NFS4_MAX_SESSIONID_LEN;
507 525
508 p = xdr_reserve_space(xdr, len); 526 p = xdr_reserve_space(xdr, len);
@@ -513,11 +531,11 @@ static unsigned encode_sessionid(struct xdr_stream *xdr,
513 return 0; 531 return 0;
514} 532}
515 533
516static unsigned encode_cb_sequence_res(struct svc_rqst *rqstp, 534static __be32 encode_cb_sequence_res(struct svc_rqst *rqstp,
517 struct xdr_stream *xdr, 535 struct xdr_stream *xdr,
518 const struct cb_sequenceres *res) 536 const struct cb_sequenceres *res)
519{ 537{
520 uint32_t *p; 538 __be32 *p;
521 unsigned status = res->csr_status; 539 unsigned status = res->csr_status;
522 540
523 if (unlikely(status != 0)) 541 if (unlikely(status != 0))
@@ -554,6 +572,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
554 case OP_CB_RECALL: 572 case OP_CB_RECALL:
555 case OP_CB_SEQUENCE: 573 case OP_CB_SEQUENCE:
556 case OP_CB_RECALL_ANY: 574 case OP_CB_RECALL_ANY:
575 case OP_CB_RECALL_SLOT:
557 *op = &callback_ops[op_nr]; 576 *op = &callback_ops[op_nr];
558 break; 577 break;
559 578
@@ -562,7 +581,6 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
562 case OP_CB_NOTIFY: 581 case OP_CB_NOTIFY:
563 case OP_CB_PUSH_DELEG: 582 case OP_CB_PUSH_DELEG:
564 case OP_CB_RECALLABLE_OBJ_AVAIL: 583 case OP_CB_RECALLABLE_OBJ_AVAIL:
565 case OP_CB_RECALL_SLOT:
566 case OP_CB_WANTS_CANCELLED: 584 case OP_CB_WANTS_CANCELLED:
567 case OP_CB_NOTIFY_LOCK: 585 case OP_CB_NOTIFY_LOCK:
568 return htonl(NFS4ERR_NOTSUPP); 586 return htonl(NFS4ERR_NOTSUPP);
@@ -602,20 +620,18 @@ preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op)
602static __be32 process_op(uint32_t minorversion, int nop, 620static __be32 process_op(uint32_t minorversion, int nop,
603 struct svc_rqst *rqstp, 621 struct svc_rqst *rqstp,
604 struct xdr_stream *xdr_in, void *argp, 622 struct xdr_stream *xdr_in, void *argp,
605 struct xdr_stream *xdr_out, void *resp) 623 struct xdr_stream *xdr_out, void *resp, int* drc_status)
606{ 624{
607 struct callback_op *op = &callback_ops[0]; 625 struct callback_op *op = &callback_ops[0];
608 unsigned int op_nr = OP_CB_ILLEGAL; 626 unsigned int op_nr;
609 __be32 status; 627 __be32 status;
610 long maxlen; 628 long maxlen;
611 __be32 res; 629 __be32 res;
612 630
613 dprintk("%s: start\n", __func__); 631 dprintk("%s: start\n", __func__);
614 status = decode_op_hdr(xdr_in, &op_nr); 632 status = decode_op_hdr(xdr_in, &op_nr);
615 if (unlikely(status)) { 633 if (unlikely(status))
616 status = htonl(NFS4ERR_OP_ILLEGAL); 634 return status;
617 goto out;
618 }
619 635
620 dprintk("%s: minorversion=%d nop=%d op_nr=%u\n", 636 dprintk("%s: minorversion=%d nop=%d op_nr=%u\n",
621 __func__, minorversion, nop, op_nr); 637 __func__, minorversion, nop, op_nr);
@@ -624,19 +640,32 @@ static __be32 process_op(uint32_t minorversion, int nop,
624 preprocess_nfs4_op(op_nr, &op); 640 preprocess_nfs4_op(op_nr, &op);
625 if (status == htonl(NFS4ERR_OP_ILLEGAL)) 641 if (status == htonl(NFS4ERR_OP_ILLEGAL))
626 op_nr = OP_CB_ILLEGAL; 642 op_nr = OP_CB_ILLEGAL;
627out: 643 if (status)
644 goto encode_hdr;
645
646 if (*drc_status) {
647 status = *drc_status;
648 goto encode_hdr;
649 }
650
628 maxlen = xdr_out->end - xdr_out->p; 651 maxlen = xdr_out->end - xdr_out->p;
629 if (maxlen > 0 && maxlen < PAGE_SIZE) { 652 if (maxlen > 0 && maxlen < PAGE_SIZE) {
630 if (likely(status == 0 && op->decode_args != NULL)) 653 status = op->decode_args(rqstp, xdr_in, argp);
631 status = op->decode_args(rqstp, xdr_in, argp); 654 if (likely(status == 0))
632 if (likely(status == 0 && op->process_op != NULL))
633 status = op->process_op(argp, resp); 655 status = op->process_op(argp, resp);
634 } else 656 } else
635 status = htonl(NFS4ERR_RESOURCE); 657 status = htonl(NFS4ERR_RESOURCE);
636 658
659 /* Only set by OP_CB_SEQUENCE processing */
660 if (status == htonl(NFS4ERR_RETRY_UNCACHED_REP)) {
661 *drc_status = status;
662 status = 0;
663 }
664
665encode_hdr:
637 res = encode_op_hdr(xdr_out, op_nr, status); 666 res = encode_op_hdr(xdr_out, op_nr, status);
638 if (status == 0) 667 if (unlikely(res))
639 status = res; 668 return res;
640 if (op->encode_res != NULL && status == 0) 669 if (op->encode_res != NULL && status == 0)
641 status = op->encode_res(rqstp, xdr_out, resp); 670 status = op->encode_res(rqstp, xdr_out, resp);
642 dprintk("%s: done, status = %d\n", __func__, ntohl(status)); 671 dprintk("%s: done, status = %d\n", __func__, ntohl(status));
@@ -652,7 +681,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
652 struct cb_compound_hdr_res hdr_res = { NULL }; 681 struct cb_compound_hdr_res hdr_res = { NULL };
653 struct xdr_stream xdr_in, xdr_out; 682 struct xdr_stream xdr_in, xdr_out;
654 __be32 *p; 683 __be32 *p;
655 __be32 status; 684 __be32 status, drc_status = 0;
656 unsigned int nops = 0; 685 unsigned int nops = 0;
657 686
658 dprintk("%s: start\n", __func__); 687 dprintk("%s: start\n", __func__);
@@ -672,11 +701,18 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
672 return rpc_system_err; 701 return rpc_system_err;
673 702
674 while (status == 0 && nops != hdr_arg.nops) { 703 while (status == 0 && nops != hdr_arg.nops) {
675 status = process_op(hdr_arg.minorversion, nops, 704 status = process_op(hdr_arg.minorversion, nops, rqstp,
676 rqstp, &xdr_in, argp, &xdr_out, resp); 705 &xdr_in, argp, &xdr_out, resp, &drc_status);
677 nops++; 706 nops++;
678 } 707 }
679 708
709 /* Buffer overflow in decode_ops_hdr or encode_ops_hdr. Return
710 * resource error in cb_compound status without returning op */
711 if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) {
712 status = htonl(NFS4ERR_RESOURCE);
713 nops--;
714 }
715
680 *hdr_res.status = status; 716 *hdr_res.status = status;
681 *hdr_res.nops = htonl(nops); 717 *hdr_res.nops = htonl(nops);
682 dprintk("%s: done, status = %u\n", __func__, ntohl(status)); 718 dprintk("%s: done, status = %u\n", __func__, ntohl(status));
@@ -713,6 +749,11 @@ static struct callback_op callback_ops[] = {
713 .decode_args = (callback_decode_arg_t)decode_recallany_args, 749 .decode_args = (callback_decode_arg_t)decode_recallany_args,
714 .res_maxsize = CB_OP_RECALLANY_RES_MAXSZ, 750 .res_maxsize = CB_OP_RECALLANY_RES_MAXSZ,
715 }, 751 },
752 [OP_CB_RECALL_SLOT] = {
753 .process_op = (callback_process_op_t)nfs4_callback_recallslot,
754 .decode_args = (callback_decode_arg_t)decode_recallslot_args,
755 .res_maxsize = CB_OP_RECALLSLOT_RES_MAXSZ,
756 },
716#endif /* CONFIG_NFS_V4_1 */ 757#endif /* CONFIG_NFS_V4_1 */
717}; 758};
718 759
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index ee77713ce68b..2274f1737336 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -164,30 +164,7 @@ error_0:
164 return ERR_PTR(err); 164 return ERR_PTR(err);
165} 165}
166 166
167static void nfs4_shutdown_client(struct nfs_client *clp)
168{
169#ifdef CONFIG_NFS_V4
170 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
171 nfs4_kill_renewd(clp);
172 BUG_ON(!RB_EMPTY_ROOT(&clp->cl_state_owners));
173 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
174 nfs_idmap_delete(clp);
175
176 rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
177#endif
178}
179
180/*
181 * Destroy the NFS4 callback service
182 */
183static void nfs4_destroy_callback(struct nfs_client *clp)
184{
185#ifdef CONFIG_NFS_V4 167#ifdef CONFIG_NFS_V4
186 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
187 nfs_callback_down(clp->cl_minorversion);
188#endif /* CONFIG_NFS_V4 */
189}
190
191/* 168/*
192 * Clears/puts all minor version specific parts from an nfs_client struct 169 * Clears/puts all minor version specific parts from an nfs_client struct
193 * reverting it to minorversion 0. 170 * reverting it to minorversion 0.
@@ -202,9 +179,33 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
202 179
203 clp->cl_call_sync = _nfs4_call_sync; 180 clp->cl_call_sync = _nfs4_call_sync;
204#endif /* CONFIG_NFS_V4_1 */ 181#endif /* CONFIG_NFS_V4_1 */
182}
205 183
184/*
185 * Destroy the NFS4 callback service
186 */
187static void nfs4_destroy_callback(struct nfs_client *clp)
188{
189 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
190 nfs_callback_down(clp->cl_minorversion);
191}
192
193static void nfs4_shutdown_client(struct nfs_client *clp)
194{
195 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
196 nfs4_kill_renewd(clp);
197 nfs4_clear_client_minor_version(clp);
206 nfs4_destroy_callback(clp); 198 nfs4_destroy_callback(clp);
199 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
200 nfs_idmap_delete(clp);
201
202 rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
207} 203}
204#else
205static void nfs4_shutdown_client(struct nfs_client *clp)
206{
207}
208#endif /* CONFIG_NFS_V4 */
208 209
209/* 210/*
210 * Destroy a shared client record 211 * Destroy a shared client record
@@ -213,7 +214,6 @@ static void nfs_free_client(struct nfs_client *clp)
213{ 214{
214 dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version); 215 dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version);
215 216
216 nfs4_clear_client_minor_version(clp);
217 nfs4_shutdown_client(clp); 217 nfs4_shutdown_client(clp);
218 218
219 nfs_fscache_release_client_cookie(clp); 219 nfs_fscache_release_client_cookie(clp);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 3c7f03b669fb..a1f6b4438fb1 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -560,7 +560,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
560 desc->entry = &my_entry; 560 desc->entry = &my_entry;
561 561
562 nfs_block_sillyrename(dentry); 562 nfs_block_sillyrename(dentry);
563 res = nfs_revalidate_mapping_nolock(inode, filp->f_mapping); 563 res = nfs_revalidate_mapping(inode, filp->f_mapping);
564 if (res < 0) 564 if (res < 0)
565 goto out; 565 goto out;
566 566
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index 95e1ca765d47..3f0cd4dfddaf 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -36,6 +36,19 @@ struct nfs_dns_ent {
36}; 36};
37 37
38 38
39static void nfs_dns_ent_update(struct cache_head *cnew,
40 struct cache_head *ckey)
41{
42 struct nfs_dns_ent *new;
43 struct nfs_dns_ent *key;
44
45 new = container_of(cnew, struct nfs_dns_ent, h);
46 key = container_of(ckey, struct nfs_dns_ent, h);
47
48 memcpy(&new->addr, &key->addr, key->addrlen);
49 new->addrlen = key->addrlen;
50}
51
39static void nfs_dns_ent_init(struct cache_head *cnew, 52static void nfs_dns_ent_init(struct cache_head *cnew,
40 struct cache_head *ckey) 53 struct cache_head *ckey)
41{ 54{
@@ -49,8 +62,7 @@ static void nfs_dns_ent_init(struct cache_head *cnew,
49 new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL); 62 new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL);
50 if (new->hostname) { 63 if (new->hostname) {
51 new->namelen = key->namelen; 64 new->namelen = key->namelen;
52 memcpy(&new->addr, &key->addr, key->addrlen); 65 nfs_dns_ent_update(cnew, ckey);
53 new->addrlen = key->addrlen;
54 } else { 66 } else {
55 new->namelen = 0; 67 new->namelen = 0;
56 new->addrlen = 0; 68 new->addrlen = 0;
@@ -234,7 +246,7 @@ static struct cache_detail nfs_dns_resolve = {
234 .cache_show = nfs_dns_show, 246 .cache_show = nfs_dns_show,
235 .match = nfs_dns_match, 247 .match = nfs_dns_match,
236 .init = nfs_dns_ent_init, 248 .init = nfs_dns_ent_init,
237 .update = nfs_dns_ent_init, 249 .update = nfs_dns_ent_update,
238 .alloc = nfs_dns_ent_alloc, 250 .alloc = nfs_dns_ent_alloc,
239}; 251};
240 252
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 63f2071d6445..ae8d02294e46 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -123,11 +123,11 @@ nfs_file_open(struct inode *inode, struct file *filp)
123 filp->f_path.dentry->d_parent->d_name.name, 123 filp->f_path.dentry->d_parent->d_name.name,
124 filp->f_path.dentry->d_name.name); 124 filp->f_path.dentry->d_name.name);
125 125
126 nfs_inc_stats(inode, NFSIOS_VFSOPEN);
126 res = nfs_check_flags(filp->f_flags); 127 res = nfs_check_flags(filp->f_flags);
127 if (res) 128 if (res)
128 return res; 129 return res;
129 130
130 nfs_inc_stats(inode, NFSIOS_VFSOPEN);
131 res = nfs_open(inode, filp); 131 res = nfs_open(inode, filp);
132 return res; 132 return res;
133} 133}
@@ -237,9 +237,9 @@ nfs_file_flush(struct file *file, fl_owner_t id)
237 dentry->d_parent->d_name.name, 237 dentry->d_parent->d_name.name,
238 dentry->d_name.name); 238 dentry->d_name.name);
239 239
240 nfs_inc_stats(inode, NFSIOS_VFSFLUSH);
240 if ((file->f_mode & FMODE_WRITE) == 0) 241 if ((file->f_mode & FMODE_WRITE) == 0)
241 return 0; 242 return 0;
242 nfs_inc_stats(inode, NFSIOS_VFSFLUSH);
243 243
244 /* Flush writes to the server and return any errors */ 244 /* Flush writes to the server and return any errors */
245 return nfs_do_fsync(ctx, inode); 245 return nfs_do_fsync(ctx, inode);
@@ -262,9 +262,11 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
262 (unsigned long) count, (unsigned long) pos); 262 (unsigned long) count, (unsigned long) pos);
263 263
264 result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); 264 result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
265 nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count); 265 if (!result) {
266 if (!result)
267 result = generic_file_aio_read(iocb, iov, nr_segs, pos); 266 result = generic_file_aio_read(iocb, iov, nr_segs, pos);
267 if (result > 0)
268 nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, result);
269 }
268 return result; 270 return result;
269} 271}
270 272
@@ -282,8 +284,11 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
282 (unsigned long) count, (unsigned long long) *ppos); 284 (unsigned long) count, (unsigned long long) *ppos);
283 285
284 res = nfs_revalidate_mapping(inode, filp->f_mapping); 286 res = nfs_revalidate_mapping(inode, filp->f_mapping);
285 if (!res) 287 if (!res) {
286 res = generic_file_splice_read(filp, ppos, pipe, count, flags); 288 res = generic_file_splice_read(filp, ppos, pipe, count, flags);
289 if (res > 0)
290 nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, res);
291 }
287 return res; 292 return res;
288} 293}
289 294
@@ -596,6 +601,7 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
596{ 601{
597 struct dentry * dentry = iocb->ki_filp->f_path.dentry; 602 struct dentry * dentry = iocb->ki_filp->f_path.dentry;
598 struct inode * inode = dentry->d_inode; 603 struct inode * inode = dentry->d_inode;
604 unsigned long written = 0;
599 ssize_t result; 605 ssize_t result;
600 size_t count = iov_length(iov, nr_segs); 606 size_t count = iov_length(iov, nr_segs);
601 607
@@ -622,14 +628,18 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
622 if (!count) 628 if (!count)
623 goto out; 629 goto out;
624 630
625 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
626 result = generic_file_aio_write(iocb, iov, nr_segs, pos); 631 result = generic_file_aio_write(iocb, iov, nr_segs, pos);
632 if (result > 0)
633 written = result;
634
627 /* Return error values for O_DSYNC and IS_SYNC() */ 635 /* Return error values for O_DSYNC and IS_SYNC() */
628 if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) { 636 if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
629 int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode); 637 int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode);
630 if (err < 0) 638 if (err < 0)
631 result = err; 639 result = err;
632 } 640 }
641 if (result > 0)
642 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
633out: 643out:
634 return result; 644 return result;
635 645
@@ -644,6 +654,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
644{ 654{
645 struct dentry *dentry = filp->f_path.dentry; 655 struct dentry *dentry = filp->f_path.dentry;
646 struct inode *inode = dentry->d_inode; 656 struct inode *inode = dentry->d_inode;
657 unsigned long written = 0;
647 ssize_t ret; 658 ssize_t ret;
648 659
649 dprintk("NFS splice_write(%s/%s, %lu@%llu)\n", 660 dprintk("NFS splice_write(%s/%s, %lu@%llu)\n",
@@ -654,14 +665,17 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
654 * The combination of splice and an O_APPEND destination is disallowed. 665 * The combination of splice and an O_APPEND destination is disallowed.
655 */ 666 */
656 667
657 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
658
659 ret = generic_file_splice_write(pipe, filp, ppos, count, flags); 668 ret = generic_file_splice_write(pipe, filp, ppos, count, flags);
669 if (ret > 0)
670 written = ret;
671
660 if (ret >= 0 && nfs_need_sync_write(filp, inode)) { 672 if (ret >= 0 && nfs_need_sync_write(filp, inode)) {
661 int err = nfs_do_fsync(nfs_file_open_context(filp), inode); 673 int err = nfs_do_fsync(nfs_file_open_context(filp), inode);
662 if (err < 0) 674 if (err < 0)
663 ret = err; 675 ret = err;
664 } 676 }
677 if (ret > 0)
678 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
665 return ret; 679 return ret;
666} 680}
667 681
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 7f9ecc46f3fb..657201acda84 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -97,18 +97,6 @@ u64 nfs_compat_user_ino64(u64 fileid)
97 return ino; 97 return ino;
98} 98}
99 99
100int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
101{
102 int ret;
103
104 ret = nfs_commit_inode(inode,
105 wbc->sync_mode == WB_SYNC_ALL ? FLUSH_SYNC : 0);
106 if (ret >= 0)
107 return 0;
108 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
109 return ret;
110}
111
112void nfs_clear_inode(struct inode *inode) 100void nfs_clear_inode(struct inode *inode)
113{ 101{
114 /* 102 /*
@@ -126,16 +114,12 @@ void nfs_clear_inode(struct inode *inode)
126 */ 114 */
127int nfs_sync_mapping(struct address_space *mapping) 115int nfs_sync_mapping(struct address_space *mapping)
128{ 116{
129 int ret; 117 int ret = 0;
130 118
131 if (mapping->nrpages == 0) 119 if (mapping->nrpages != 0) {
132 return 0; 120 unmap_mapping_range(mapping, 0, 0, 0);
133 unmap_mapping_range(mapping, 0, 0, 0); 121 ret = nfs_wb_all(mapping->host);
134 ret = filemap_write_and_wait(mapping); 122 }
135 if (ret != 0)
136 goto out;
137 ret = nfs_wb_all(mapping->host);
138out:
139 return ret; 123 return ret;
140} 124}
141 125
@@ -507,17 +491,11 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
507 int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; 491 int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
508 int err; 492 int err;
509 493
510 /* 494 /* Flush out writes to the server in order to update c/mtime. */
511 * Flush out writes to the server in order to update c/mtime.
512 *
513 * Hold the i_mutex to suspend application writes temporarily;
514 * this prevents long-running writing applications from blocking
515 * nfs_wb_nocommit.
516 */
517 if (S_ISREG(inode->i_mode)) { 495 if (S_ISREG(inode->i_mode)) {
518 mutex_lock(&inode->i_mutex); 496 err = filemap_write_and_wait(inode->i_mapping);
519 nfs_wb_nocommit(inode); 497 if (err)
520 mutex_unlock(&inode->i_mutex); 498 goto out;
521 } 499 }
522 500
523 /* 501 /*
@@ -541,6 +519,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
541 generic_fillattr(inode, stat); 519 generic_fillattr(inode, stat);
542 stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); 520 stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
543 } 521 }
522out:
544 return err; 523 return err;
545} 524}
546 525
@@ -616,11 +595,6 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
616 __put_nfs_open_context(ctx, 0); 595 __put_nfs_open_context(ctx, 0);
617} 596}
618 597
619static void put_nfs_open_context_sync(struct nfs_open_context *ctx)
620{
621 __put_nfs_open_context(ctx, 1);
622}
623
624/* 598/*
625 * Ensure that mmap has a recent RPC credential for use when writing out 599 * Ensure that mmap has a recent RPC credential for use when writing out
626 * shared pages 600 * shared pages
@@ -667,7 +641,7 @@ static void nfs_file_clear_open_context(struct file *filp)
667 spin_lock(&inode->i_lock); 641 spin_lock(&inode->i_lock);
668 list_move_tail(&ctx->list, &NFS_I(inode)->open_files); 642 list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
669 spin_unlock(&inode->i_lock); 643 spin_unlock(&inode->i_lock);
670 put_nfs_open_context_sync(ctx); 644 __put_nfs_open_context(ctx, filp->f_flags & O_DIRECT ? 0 : 1);
671 } 645 }
672} 646}
673 647
@@ -775,7 +749,7 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
775 return __nfs_revalidate_inode(server, inode); 749 return __nfs_revalidate_inode(server, inode);
776} 750}
777 751
778static int nfs_invalidate_mapping_nolock(struct inode *inode, struct address_space *mapping) 752static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
779{ 753{
780 struct nfs_inode *nfsi = NFS_I(inode); 754 struct nfs_inode *nfsi = NFS_I(inode);
781 755
@@ -796,49 +770,10 @@ static int nfs_invalidate_mapping_nolock(struct inode *inode, struct address_spa
796 return 0; 770 return 0;
797} 771}
798 772
799static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
800{
801 int ret = 0;
802
803 mutex_lock(&inode->i_mutex);
804 if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_DATA) {
805 ret = nfs_sync_mapping(mapping);
806 if (ret == 0)
807 ret = nfs_invalidate_mapping_nolock(inode, mapping);
808 }
809 mutex_unlock(&inode->i_mutex);
810 return ret;
811}
812
813/**
814 * nfs_revalidate_mapping_nolock - Revalidate the pagecache
815 * @inode - pointer to host inode
816 * @mapping - pointer to mapping
817 */
818int nfs_revalidate_mapping_nolock(struct inode *inode, struct address_space *mapping)
819{
820 struct nfs_inode *nfsi = NFS_I(inode);
821 int ret = 0;
822
823 if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
824 || nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
825 ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
826 if (ret < 0)
827 goto out;
828 }
829 if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
830 ret = nfs_invalidate_mapping_nolock(inode, mapping);
831out:
832 return ret;
833}
834
835/** 773/**
836 * nfs_revalidate_mapping - Revalidate the pagecache 774 * nfs_revalidate_mapping - Revalidate the pagecache
837 * @inode - pointer to host inode 775 * @inode - pointer to host inode
838 * @mapping - pointer to mapping 776 * @mapping - pointer to mapping
839 *
840 * This version of the function will take the inode->i_mutex and attempt to
841 * flush out all dirty data if it needs to invalidate the page cache.
842 */ 777 */
843int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) 778int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
844{ 779{
@@ -1416,6 +1351,7 @@ static void init_once(void *foo)
1416 INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); 1351 INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
1417 INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); 1352 INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
1418 nfsi->npages = 0; 1353 nfsi->npages = 0;
1354 nfsi->ncommit = 0;
1419 atomic_set(&nfsi->silly_count, 1); 1355 atomic_set(&nfsi->silly_count, 1);
1420 INIT_HLIST_HEAD(&nfsi->silly_list); 1356 INIT_HLIST_HEAD(&nfsi->silly_list);
1421 init_waitqueue_head(&nfsi->waitqueue); 1357 init_waitqueue_head(&nfsi->waitqueue);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 3f8881d1a050..24992f0a29f2 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -22,14 +22,14 @@
22 22
23#define NFSDBG_FACILITY NFSDBG_PROC 23#define NFSDBG_FACILITY NFSDBG_PROC
24 24
25/* A wrapper to handle the EJUKEBOX error message */ 25/* A wrapper to handle the EJUKEBOX and EKEYEXPIRED error messages */
26static int 26static int
27nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) 27nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
28{ 28{
29 int res; 29 int res;
30 do { 30 do {
31 res = rpc_call_sync(clnt, msg, flags); 31 res = rpc_call_sync(clnt, msg, flags);
32 if (res != -EJUKEBOX) 32 if (res != -EJUKEBOX && res != -EKEYEXPIRED)
33 break; 33 break;
34 schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME); 34 schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
35 res = -ERESTARTSYS; 35 res = -ERESTARTSYS;
@@ -42,9 +42,10 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
42static int 42static int
43nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode) 43nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
44{ 44{
45 if (task->tk_status != -EJUKEBOX) 45 if (task->tk_status != -EJUKEBOX && task->tk_status != -EKEYEXPIRED)
46 return 0; 46 return 0;
47 nfs_inc_stats(inode, NFSIOS_DELAY); 47 if (task->tk_status == -EJUKEBOX)
48 nfs_inc_stats(inode, NFSIOS_DELAY);
48 task->tk_status = 0; 49 task->tk_status = 0;
49 rpc_restart_call(task); 50 rpc_restart_call(task);
50 rpc_delay(task, NFS_JUKEBOX_RETRY_TIME); 51 rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 0c6fda33d66e..a187200a7aac 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -46,6 +46,7 @@ enum nfs4_client_state {
46 NFS4CLNT_DELEGRETURN, 46 NFS4CLNT_DELEGRETURN,
47 NFS4CLNT_SESSION_RESET, 47 NFS4CLNT_SESSION_RESET,
48 NFS4CLNT_SESSION_DRAINING, 48 NFS4CLNT_SESSION_DRAINING,
49 NFS4CLNT_RECALL_SLOT,
49}; 50};
50 51
51/* 52/*
@@ -280,6 +281,7 @@ extern void nfs4_schedule_state_manager(struct nfs_client *);
280extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state); 281extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state);
281extern int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state); 282extern int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state);
282extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); 283extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
284extern void nfs41_handle_recall_slot(struct nfs_client *clp);
283extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); 285extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
284extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); 286extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
285extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); 287extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 84d83be25a98..eda74c42d552 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -281,6 +281,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
281 } 281 }
282 case -NFS4ERR_GRACE: 282 case -NFS4ERR_GRACE:
283 case -NFS4ERR_DELAY: 283 case -NFS4ERR_DELAY:
284 case -EKEYEXPIRED:
284 ret = nfs4_delay(server->client, &exception->timeout); 285 ret = nfs4_delay(server->client, &exception->timeout);
285 if (ret != 0) 286 if (ret != 0)
286 break; 287 break;
@@ -418,7 +419,8 @@ static void nfs41_sequence_done(struct nfs_client *clp,
418 clp->cl_last_renewal = timestamp; 419 clp->cl_last_renewal = timestamp;
419 spin_unlock(&clp->cl_lock); 420 spin_unlock(&clp->cl_lock);
420 /* Check sequence flags */ 421 /* Check sequence flags */
421 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags); 422 if (atomic_read(&clp->cl_count) > 1)
423 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags);
422 } 424 }
423out: 425out:
424 /* The session may be reset by one of the error handlers. */ 426 /* The session may be reset by one of the error handlers. */
@@ -1163,7 +1165,7 @@ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
1163 int err; 1165 int err;
1164 do { 1166 do {
1165 err = _nfs4_do_open_reclaim(ctx, state); 1167 err = _nfs4_do_open_reclaim(ctx, state);
1166 if (err != -NFS4ERR_DELAY) 1168 if (err != -NFS4ERR_DELAY && err != -EKEYEXPIRED)
1167 break; 1169 break;
1168 nfs4_handle_exception(server, err, &exception); 1170 nfs4_handle_exception(server, err, &exception);
1169 } while (exception.retry); 1171 } while (exception.retry);
@@ -1582,6 +1584,7 @@ static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state
1582 goto out; 1584 goto out;
1583 case -NFS4ERR_GRACE: 1585 case -NFS4ERR_GRACE:
1584 case -NFS4ERR_DELAY: 1586 case -NFS4ERR_DELAY:
1587 case -EKEYEXPIRED:
1585 nfs4_handle_exception(server, err, &exception); 1588 nfs4_handle_exception(server, err, &exception);
1586 err = 0; 1589 err = 0;
1587 } 1590 }
@@ -3145,10 +3148,19 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
3145 * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special 3148 * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special
3146 * standalone procedure for queueing an asynchronous RENEW. 3149 * standalone procedure for queueing an asynchronous RENEW.
3147 */ 3150 */
3151static void nfs4_renew_release(void *data)
3152{
3153 struct nfs_client *clp = data;
3154
3155 if (atomic_read(&clp->cl_count) > 1)
3156 nfs4_schedule_state_renewal(clp);
3157 nfs_put_client(clp);
3158}
3159
3148static void nfs4_renew_done(struct rpc_task *task, void *data) 3160static void nfs4_renew_done(struct rpc_task *task, void *data)
3149{ 3161{
3150 struct nfs_client *clp = (struct nfs_client *)task->tk_msg.rpc_argp; 3162 struct nfs_client *clp = data;
3151 unsigned long timestamp = (unsigned long)data; 3163 unsigned long timestamp = task->tk_start;
3152 3164
3153 if (task->tk_status < 0) { 3165 if (task->tk_status < 0) {
3154 /* Unless we're shutting down, schedule state recovery! */ 3166 /* Unless we're shutting down, schedule state recovery! */
@@ -3164,6 +3176,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
3164 3176
3165static const struct rpc_call_ops nfs4_renew_ops = { 3177static const struct rpc_call_ops nfs4_renew_ops = {
3166 .rpc_call_done = nfs4_renew_done, 3178 .rpc_call_done = nfs4_renew_done,
3179 .rpc_release = nfs4_renew_release,
3167}; 3180};
3168 3181
3169int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred) 3182int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
@@ -3174,8 +3187,10 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
3174 .rpc_cred = cred, 3187 .rpc_cred = cred,
3175 }; 3188 };
3176 3189
3190 if (!atomic_inc_not_zero(&clp->cl_count))
3191 return -EIO;
3177 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, 3192 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
3178 &nfs4_renew_ops, (void *)jiffies); 3193 &nfs4_renew_ops, clp);
3179} 3194}
3180 3195
3181int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) 3196int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
@@ -3452,6 +3467,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3452 if (server) 3467 if (server)
3453 nfs_inc_server_stats(server, NFSIOS_DELAY); 3468 nfs_inc_server_stats(server, NFSIOS_DELAY);
3454 case -NFS4ERR_GRACE: 3469 case -NFS4ERR_GRACE:
3470 case -EKEYEXPIRED:
3455 rpc_delay(task, NFS4_POLL_RETRY_MAX); 3471 rpc_delay(task, NFS4_POLL_RETRY_MAX);
3456 task->tk_status = 0; 3472 task->tk_status = 0;
3457 return -EAGAIN; 3473 return -EAGAIN;
@@ -3564,6 +3580,7 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
3564 case -NFS4ERR_RESOURCE: 3580 case -NFS4ERR_RESOURCE:
3565 /* The IBM lawyers misread another document! */ 3581 /* The IBM lawyers misread another document! */
3566 case -NFS4ERR_DELAY: 3582 case -NFS4ERR_DELAY:
3583 case -EKEYEXPIRED:
3567 err = nfs4_delay(clp->cl_rpcclient, &timeout); 3584 err = nfs4_delay(clp->cl_rpcclient, &timeout);
3568 } 3585 }
3569 } while (err == 0); 3586 } while (err == 0);
@@ -4179,7 +4196,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
4179 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4196 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4180 return 0; 4197 return 0;
4181 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM); 4198 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM);
4182 if (err != -NFS4ERR_DELAY) 4199 if (err != -NFS4ERR_DELAY && err != -EKEYEXPIRED)
4183 break; 4200 break;
4184 nfs4_handle_exception(server, err, &exception); 4201 nfs4_handle_exception(server, err, &exception);
4185 } while (exception.retry); 4202 } while (exception.retry);
@@ -4204,6 +4221,7 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
4204 goto out; 4221 goto out;
4205 case -NFS4ERR_GRACE: 4222 case -NFS4ERR_GRACE:
4206 case -NFS4ERR_DELAY: 4223 case -NFS4ERR_DELAY:
4224 case -EKEYEXPIRED:
4207 nfs4_handle_exception(server, err, &exception); 4225 nfs4_handle_exception(server, err, &exception);
4208 err = 0; 4226 err = 0;
4209 } 4227 }
@@ -4355,6 +4373,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4355 err = 0; 4373 err = 0;
4356 goto out; 4374 goto out;
4357 case -NFS4ERR_DELAY: 4375 case -NFS4ERR_DELAY:
4376 case -EKEYEXPIRED:
4358 break; 4377 break;
4359 } 4378 }
4360 err = nfs4_handle_exception(server, err, &exception); 4379 err = nfs4_handle_exception(server, err, &exception);
@@ -4500,7 +4519,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4500 4519
4501 status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); 4520 status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
4502 4521
4503 if (status != NFS4ERR_CLID_INUSE) 4522 if (status != -NFS4ERR_CLID_INUSE)
4504 break; 4523 break;
4505 4524
4506 if (signalled()) 4525 if (signalled())
@@ -4554,6 +4573,7 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
4554 switch (task->tk_status) { 4573 switch (task->tk_status) {
4555 case -NFS4ERR_DELAY: 4574 case -NFS4ERR_DELAY:
4556 case -NFS4ERR_GRACE: 4575 case -NFS4ERR_GRACE:
4576 case -EKEYEXPIRED:
4557 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); 4577 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
4558 rpc_delay(task, NFS4_POLL_RETRY_MIN); 4578 rpc_delay(task, NFS4_POLL_RETRY_MIN);
4559 task->tk_status = 0; 4579 task->tk_status = 0;
@@ -4611,26 +4631,32 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
4611/* 4631/*
4612 * Reset a slot table 4632 * Reset a slot table
4613 */ 4633 */
4614static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, int max_slots, 4634static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
4615 int old_max_slots, int ivalue) 4635 int ivalue)
4616{ 4636{
4637 struct nfs4_slot *new = NULL;
4617 int i; 4638 int i;
4618 int ret = 0; 4639 int ret = 0;
4619 4640
4620 dprintk("--> %s: max_reqs=%u, tbl %p\n", __func__, max_slots, tbl); 4641 dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__,
4642 max_reqs, tbl->max_slots);
4621 4643
4622 /* 4644 /* Does the newly negotiated max_reqs match the existing slot table? */
4623 * Until we have dynamic slot table adjustment, insist 4645 if (max_reqs != tbl->max_slots) {
4624 * upon the same slot table size 4646 ret = -ENOMEM;
4625 */ 4647 new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
4626 if (max_slots != old_max_slots) { 4648 GFP_KERNEL);
4627 dprintk("%s reset slot table does't match old\n", 4649 if (!new)
4628 __func__); 4650 goto out;
4629 ret = -EINVAL; /*XXX NFS4ERR_REQ_TOO_BIG ? */ 4651 ret = 0;
4630 goto out; 4652 kfree(tbl->slots);
4631 } 4653 }
4632 spin_lock(&tbl->slot_tbl_lock); 4654 spin_lock(&tbl->slot_tbl_lock);
4633 for (i = 0; i < max_slots; ++i) 4655 if (new) {
4656 tbl->slots = new;
4657 tbl->max_slots = max_reqs;
4658 }
4659 for (i = 0; i < tbl->max_slots; ++i)
4634 tbl->slots[i].seq_nr = ivalue; 4660 tbl->slots[i].seq_nr = ivalue;
4635 spin_unlock(&tbl->slot_tbl_lock); 4661 spin_unlock(&tbl->slot_tbl_lock);
4636 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, 4662 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
@@ -4648,16 +4674,12 @@ static int nfs4_reset_slot_tables(struct nfs4_session *session)
4648 int status; 4674 int status;
4649 4675
4650 status = nfs4_reset_slot_table(&session->fc_slot_table, 4676 status = nfs4_reset_slot_table(&session->fc_slot_table,
4651 session->fc_attrs.max_reqs, 4677 session->fc_attrs.max_reqs, 1);
4652 session->fc_slot_table.max_slots,
4653 1);
4654 if (status) 4678 if (status)
4655 return status; 4679 return status;
4656 4680
4657 status = nfs4_reset_slot_table(&session->bc_slot_table, 4681 status = nfs4_reset_slot_table(&session->bc_slot_table,
4658 session->bc_attrs.max_reqs, 4682 session->bc_attrs.max_reqs, 0);
4659 session->bc_slot_table.max_slots,
4660 0);
4661 return status; 4683 return status;
4662} 4684}
4663 4685
@@ -4798,16 +4820,14 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
4798 args->fc_attrs.headerpadsz = 0; 4820 args->fc_attrs.headerpadsz = 0;
4799 args->fc_attrs.max_rqst_sz = mxrqst_sz; 4821 args->fc_attrs.max_rqst_sz = mxrqst_sz;
4800 args->fc_attrs.max_resp_sz = mxresp_sz; 4822 args->fc_attrs.max_resp_sz = mxresp_sz;
4801 args->fc_attrs.max_resp_sz_cached = mxresp_sz;
4802 args->fc_attrs.max_ops = NFS4_MAX_OPS; 4823 args->fc_attrs.max_ops = NFS4_MAX_OPS;
4803 args->fc_attrs.max_reqs = session->clp->cl_rpcclient->cl_xprt->max_reqs; 4824 args->fc_attrs.max_reqs = session->clp->cl_rpcclient->cl_xprt->max_reqs;
4804 4825
4805 dprintk("%s: Fore Channel : max_rqst_sz=%u max_resp_sz=%u " 4826 dprintk("%s: Fore Channel : max_rqst_sz=%u max_resp_sz=%u "
4806 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n", 4827 "max_ops=%u max_reqs=%u\n",
4807 __func__, 4828 __func__,
4808 args->fc_attrs.max_rqst_sz, args->fc_attrs.max_resp_sz, 4829 args->fc_attrs.max_rqst_sz, args->fc_attrs.max_resp_sz,
4809 args->fc_attrs.max_resp_sz_cached, args->fc_attrs.max_ops, 4830 args->fc_attrs.max_ops, args->fc_attrs.max_reqs);
4810 args->fc_attrs.max_reqs);
4811 4831
4812 /* Back channel attributes */ 4832 /* Back channel attributes */
4813 args->bc_attrs.headerpadsz = 0; 4833 args->bc_attrs.headerpadsz = 0;
@@ -5016,7 +5036,16 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
5016 &res, args.sa_cache_this, 1); 5036 &res, args.sa_cache_this, 1);
5017} 5037}
5018 5038
5019void nfs41_sequence_call_done(struct rpc_task *task, void *data) 5039static void nfs41_sequence_release(void *data)
5040{
5041 struct nfs_client *clp = (struct nfs_client *)data;
5042
5043 if (atomic_read(&clp->cl_count) > 1)
5044 nfs4_schedule_state_renewal(clp);
5045 nfs_put_client(clp);
5046}
5047
5048static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
5020{ 5049{
5021 struct nfs_client *clp = (struct nfs_client *)data; 5050 struct nfs_client *clp = (struct nfs_client *)data;
5022 5051
@@ -5024,6 +5053,8 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
5024 5053
5025 if (task->tk_status < 0) { 5054 if (task->tk_status < 0) {
5026 dprintk("%s ERROR %d\n", __func__, task->tk_status); 5055 dprintk("%s ERROR %d\n", __func__, task->tk_status);
5056 if (atomic_read(&clp->cl_count) == 1)
5057 goto out;
5027 5058
5028 if (_nfs4_async_handle_error(task, NULL, clp, NULL) 5059 if (_nfs4_async_handle_error(task, NULL, clp, NULL)
5029 == -EAGAIN) { 5060 == -EAGAIN) {
@@ -5032,7 +5063,7 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
5032 } 5063 }
5033 } 5064 }
5034 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); 5065 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
5035 5066out:
5036 kfree(task->tk_msg.rpc_argp); 5067 kfree(task->tk_msg.rpc_argp);
5037 kfree(task->tk_msg.rpc_resp); 5068 kfree(task->tk_msg.rpc_resp);
5038 5069
@@ -5057,6 +5088,7 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
5057static const struct rpc_call_ops nfs41_sequence_ops = { 5088static const struct rpc_call_ops nfs41_sequence_ops = {
5058 .rpc_call_done = nfs41_sequence_call_done, 5089 .rpc_call_done = nfs41_sequence_call_done,
5059 .rpc_call_prepare = nfs41_sequence_prepare, 5090 .rpc_call_prepare = nfs41_sequence_prepare,
5091 .rpc_release = nfs41_sequence_release,
5060}; 5092};
5061 5093
5062static int nfs41_proc_async_sequence(struct nfs_client *clp, 5094static int nfs41_proc_async_sequence(struct nfs_client *clp,
@@ -5069,12 +5101,13 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
5069 .rpc_cred = cred, 5101 .rpc_cred = cred,
5070 }; 5102 };
5071 5103
5104 if (!atomic_inc_not_zero(&clp->cl_count))
5105 return -EIO;
5072 args = kzalloc(sizeof(*args), GFP_KERNEL); 5106 args = kzalloc(sizeof(*args), GFP_KERNEL);
5073 if (!args)
5074 return -ENOMEM;
5075 res = kzalloc(sizeof(*res), GFP_KERNEL); 5107 res = kzalloc(sizeof(*res), GFP_KERNEL);
5076 if (!res) { 5108 if (!args || !res) {
5077 kfree(args); 5109 kfree(args);
5110 nfs_put_client(clp);
5078 return -ENOMEM; 5111 return -ENOMEM;
5079 } 5112 }
5080 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 5113 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 0156c01c212c..d87f10327b72 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -36,11 +36,6 @@
36 * as an rpc_task, not a real kernel thread, so it always runs in rpciod's 36 * as an rpc_task, not a real kernel thread, so it always runs in rpciod's
37 * context. There is one renewd per nfs_server. 37 * context. There is one renewd per nfs_server.
38 * 38 *
39 * TODO: If the send queue gets backlogged (e.g., if the server goes down),
40 * we will keep filling the queue with periodic RENEW requests. We need a
41 * mechanism for ensuring that if renewd successfully sends off a request,
42 * then it only wakes up when the request is finished. Maybe use the
43 * child task framework of the RPC layer?
44 */ 39 */
45 40
46#include <linux/mm.h> 41#include <linux/mm.h>
@@ -63,7 +58,7 @@ nfs4_renew_state(struct work_struct *work)
63 struct nfs_client *clp = 58 struct nfs_client *clp =
64 container_of(work, struct nfs_client, cl_renewd.work); 59 container_of(work, struct nfs_client, cl_renewd.work);
65 struct rpc_cred *cred; 60 struct rpc_cred *cred;
66 long lease, timeout; 61 long lease;
67 unsigned long last, now; 62 unsigned long last, now;
68 63
69 ops = nfs4_state_renewal_ops[clp->cl_minorversion]; 64 ops = nfs4_state_renewal_ops[clp->cl_minorversion];
@@ -75,7 +70,6 @@ nfs4_renew_state(struct work_struct *work)
75 lease = clp->cl_lease_time; 70 lease = clp->cl_lease_time;
76 last = clp->cl_last_renewal; 71 last = clp->cl_last_renewal;
77 now = jiffies; 72 now = jiffies;
78 timeout = (2 * lease) / 3 + (long)last - (long)now;
79 /* Are we close to a lease timeout? */ 73 /* Are we close to a lease timeout? */
80 if (time_after(now, last + lease/3)) { 74 if (time_after(now, last + lease/3)) {
81 cred = ops->get_state_renewal_cred_locked(clp); 75 cred = ops->get_state_renewal_cred_locked(clp);
@@ -90,19 +84,15 @@ nfs4_renew_state(struct work_struct *work)
90 /* Queue an asynchronous RENEW. */ 84 /* Queue an asynchronous RENEW. */
91 ops->sched_state_renewal(clp, cred); 85 ops->sched_state_renewal(clp, cred);
92 put_rpccred(cred); 86 put_rpccred(cred);
87 goto out_exp;
93 } 88 }
94 timeout = (2 * lease) / 3; 89 } else {
95 spin_lock(&clp->cl_lock);
96 } else
97 dprintk("%s: failed to call renewd. Reason: lease not expired \n", 90 dprintk("%s: failed to call renewd. Reason: lease not expired \n",
98 __func__); 91 __func__);
99 if (timeout < 5 * HZ) /* safeguard */ 92 spin_unlock(&clp->cl_lock);
100 timeout = 5 * HZ; 93 }
101 dprintk("%s: requeueing work. Lease period = %ld\n", 94 nfs4_schedule_state_renewal(clp);
102 __func__, (timeout + HZ - 1) / HZ); 95out_exp:
103 cancel_delayed_work(&clp->cl_renewd);
104 schedule_delayed_work(&clp->cl_renewd, timeout);
105 spin_unlock(&clp->cl_lock);
106 nfs_expire_unreferenced_delegations(clp); 96 nfs_expire_unreferenced_delegations(clp);
107out: 97out:
108 dprintk("%s: done\n", __func__); 98 dprintk("%s: done\n", __func__);
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index c1e2733f4fa4..6c5ed51f105e 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1249,26 +1249,65 @@ static int nfs4_reclaim_lease(struct nfs_client *clp)
1249} 1249}
1250 1250
1251#ifdef CONFIG_NFS_V4_1 1251#ifdef CONFIG_NFS_V4_1
1252void nfs41_handle_recall_slot(struct nfs_client *clp)
1253{
1254 set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
1255 nfs4_schedule_state_recovery(clp);
1256}
1257
1258static void nfs4_reset_all_state(struct nfs_client *clp)
1259{
1260 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
1261 clp->cl_boot_time = CURRENT_TIME;
1262 nfs4_state_start_reclaim_nograce(clp);
1263 nfs4_schedule_state_recovery(clp);
1264 }
1265}
1266
1267static void nfs41_handle_server_reboot(struct nfs_client *clp)
1268{
1269 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
1270 nfs4_state_start_reclaim_reboot(clp);
1271 nfs4_schedule_state_recovery(clp);
1272 }
1273}
1274
1275static void nfs41_handle_state_revoked(struct nfs_client *clp)
1276{
1277 /* Temporary */
1278 nfs4_reset_all_state(clp);
1279}
1280
1281static void nfs41_handle_recallable_state_revoked(struct nfs_client *clp)
1282{
1283 /* This will need to handle layouts too */
1284 nfs_expire_all_delegations(clp);
1285}
1286
1287static void nfs41_handle_cb_path_down(struct nfs_client *clp)
1288{
1289 nfs_expire_all_delegations(clp);
1290 if (test_and_set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) == 0)
1291 nfs4_schedule_state_recovery(clp);
1292}
1293
1252void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) 1294void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
1253{ 1295{
1254 if (!flags) 1296 if (!flags)
1255 return; 1297 return;
1256 else if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) { 1298 else if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED)
1257 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1299 nfs41_handle_server_reboot(clp);
1258 nfs4_state_start_reclaim_reboot(clp); 1300 else if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
1259 nfs4_schedule_state_recovery(clp);
1260 } else if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
1261 SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED | 1301 SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED |
1262 SEQ4_STATUS_ADMIN_STATE_REVOKED | 1302 SEQ4_STATUS_ADMIN_STATE_REVOKED |
1263 SEQ4_STATUS_RECALLABLE_STATE_REVOKED | 1303 SEQ4_STATUS_LEASE_MOVED))
1264 SEQ4_STATUS_LEASE_MOVED)) { 1304 nfs41_handle_state_revoked(clp);
1265 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1305 else if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED)
1266 nfs4_state_start_reclaim_nograce(clp); 1306 nfs41_handle_recallable_state_revoked(clp);
1267 nfs4_schedule_state_recovery(clp); 1307 else if (flags & (SEQ4_STATUS_CB_PATH_DOWN |
1268 } else if (flags & (SEQ4_STATUS_CB_PATH_DOWN |
1269 SEQ4_STATUS_BACKCHANNEL_FAULT | 1308 SEQ4_STATUS_BACKCHANNEL_FAULT |
1270 SEQ4_STATUS_CB_PATH_DOWN_SESSION)) 1309 SEQ4_STATUS_CB_PATH_DOWN_SESSION))
1271 nfs_expire_all_delegations(clp); 1310 nfs41_handle_cb_path_down(clp);
1272} 1311}
1273 1312
1274static int nfs4_reset_session(struct nfs_client *clp) 1313static int nfs4_reset_session(struct nfs_client *clp)
@@ -1285,23 +1324,52 @@ static int nfs4_reset_session(struct nfs_client *clp)
1285 1324
1286 memset(clp->cl_session->sess_id.data, 0, NFS4_MAX_SESSIONID_LEN); 1325 memset(clp->cl_session->sess_id.data, 0, NFS4_MAX_SESSIONID_LEN);
1287 status = nfs4_proc_create_session(clp); 1326 status = nfs4_proc_create_session(clp);
1288 if (status) 1327 if (status) {
1289 status = nfs4_recovery_handle_error(clp, status); 1328 status = nfs4_recovery_handle_error(clp, status);
1329 goto out;
1330 }
1331 /* create_session negotiated new slot table */
1332 clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
1290 1333
1291out: 1334 /* Let the state manager reestablish state */
1292 /* 1335 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
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); 1336 nfs41_setup_state_renewal(clp);
1298 1337out:
1299 return status; 1338 return status;
1300} 1339}
1301 1340
1341static int nfs4_recall_slot(struct nfs_client *clp)
1342{
1343 struct nfs4_slot_table *fc_tbl = &clp->cl_session->fc_slot_table;
1344 struct nfs4_channel_attrs *fc_attrs = &clp->cl_session->fc_attrs;
1345 struct nfs4_slot *new, *old;
1346 int i;
1347
1348 nfs4_begin_drain_session(clp);
1349 new = kmalloc(fc_tbl->target_max_slots * sizeof(struct nfs4_slot),
1350 GFP_KERNEL);
1351 if (!new)
1352 return -ENOMEM;
1353
1354 spin_lock(&fc_tbl->slot_tbl_lock);
1355 for (i = 0; i < fc_tbl->target_max_slots; i++)
1356 new[i].seq_nr = fc_tbl->slots[i].seq_nr;
1357 old = fc_tbl->slots;
1358 fc_tbl->slots = new;
1359 fc_tbl->max_slots = fc_tbl->target_max_slots;
1360 fc_tbl->target_max_slots = 0;
1361 fc_attrs->max_reqs = fc_tbl->max_slots;
1362 spin_unlock(&fc_tbl->slot_tbl_lock);
1363
1364 kfree(old);
1365 nfs4_end_drain_session(clp);
1366 return 0;
1367}
1368
1302#else /* CONFIG_NFS_V4_1 */ 1369#else /* CONFIG_NFS_V4_1 */
1303static int nfs4_reset_session(struct nfs_client *clp) { return 0; } 1370static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
1304static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; } 1371static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; }
1372static int nfs4_recall_slot(struct nfs_client *clp) { return 0; }
1305#endif /* CONFIG_NFS_V4_1 */ 1373#endif /* CONFIG_NFS_V4_1 */
1306 1374
1307/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors 1375/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
@@ -1314,6 +1382,7 @@ static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
1314 case -NFS4ERR_DELAY: 1382 case -NFS4ERR_DELAY:
1315 case -NFS4ERR_CLID_INUSE: 1383 case -NFS4ERR_CLID_INUSE:
1316 case -EAGAIN: 1384 case -EAGAIN:
1385 case -EKEYEXPIRED:
1317 break; 1386 break;
1318 1387
1319 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery 1388 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
@@ -1397,6 +1466,15 @@ static void nfs4_state_manager(struct nfs_client *clp)
1397 nfs_client_return_marked_delegations(clp); 1466 nfs_client_return_marked_delegations(clp);
1398 continue; 1467 continue;
1399 } 1468 }
1469 /* Recall session slots */
1470 if (test_and_clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state)
1471 && nfs4_has_session(clp)) {
1472 status = nfs4_recall_slot(clp);
1473 if (status < 0)
1474 goto out_error;
1475 continue;
1476 }
1477
1400 1478
1401 nfs4_clear_state_manager_bit(clp); 1479 nfs4_clear_state_manager_bit(clp);
1402 /* Did we race with an attempt to give us more work? */ 1480 /* Did we race with an attempt to give us more work? */
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 5cd5184b56db..4d338be492cb 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1578,6 +1578,14 @@ static void encode_create_session(struct xdr_stream *xdr,
1578 char machine_name[NFS4_MAX_MACHINE_NAME_LEN]; 1578 char machine_name[NFS4_MAX_MACHINE_NAME_LEN];
1579 uint32_t len; 1579 uint32_t len;
1580 struct nfs_client *clp = args->client; 1580 struct nfs_client *clp = args->client;
1581 u32 max_resp_sz_cached;
1582
1583 /*
1584 * Assumes OPEN is the biggest non-idempotent compound.
1585 * 2 is the verifier.
1586 */
1587 max_resp_sz_cached = (NFS4_dec_open_sz + RPC_REPHDRSIZE +
1588 RPC_MAX_AUTH_SIZE + 2) * XDR_UNIT;
1581 1589
1582 len = scnprintf(machine_name, sizeof(machine_name), "%s", 1590 len = scnprintf(machine_name, sizeof(machine_name), "%s",
1583 clp->cl_ipaddr); 1591 clp->cl_ipaddr);
@@ -1592,7 +1600,7 @@ static void encode_create_session(struct xdr_stream *xdr,
1592 *p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */ 1600 *p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */
1593 *p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz); /* max req size */ 1601 *p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz); /* max req size */
1594 *p++ = cpu_to_be32(args->fc_attrs.max_resp_sz); /* max resp size */ 1602 *p++ = cpu_to_be32(args->fc_attrs.max_resp_sz); /* max resp size */
1595 *p++ = cpu_to_be32(args->fc_attrs.max_resp_sz_cached); /* Max resp sz cached */ 1603 *p++ = cpu_to_be32(max_resp_sz_cached); /* Max resp sz cached */
1596 *p++ = cpu_to_be32(args->fc_attrs.max_ops); /* max operations */ 1604 *p++ = cpu_to_be32(args->fc_attrs.max_ops); /* max operations */
1597 *p++ = cpu_to_be32(args->fc_attrs.max_reqs); /* max requests */ 1605 *p++ = cpu_to_be32(args->fc_attrs.max_reqs); /* max requests */
1598 *p++ = cpu_to_be32(0); /* rdmachannel_attrs */ 1606 *p++ = cpu_to_be32(0); /* rdmachannel_attrs */
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index ef583854d8d0..c752d944fe9e 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -47,6 +47,39 @@
47#define NFSDBG_FACILITY NFSDBG_PROC 47#define NFSDBG_FACILITY NFSDBG_PROC
48 48
49/* 49/*
50 * wrapper to handle the -EKEYEXPIRED error message. This should generally
51 * only happen if using krb5 auth and a user's TGT expires. NFSv2 doesn't
52 * support the NFSERR_JUKEBOX error code, but we handle this situation in the
53 * same way that we handle that error with NFSv3.
54 */
55static int
56nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
57{
58 int res;
59 do {
60 res = rpc_call_sync(clnt, msg, flags);
61 if (res != -EKEYEXPIRED)
62 break;
63 schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
64 res = -ERESTARTSYS;
65 } while (!fatal_signal_pending(current));
66 return res;
67}
68
69#define rpc_call_sync(clnt, msg, flags) nfs_rpc_wrapper(clnt, msg, flags)
70
71static int
72nfs_async_handle_expired_key(struct rpc_task *task)
73{
74 if (task->tk_status != -EKEYEXPIRED)
75 return 0;
76 task->tk_status = 0;
77 rpc_restart_call(task);
78 rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
79 return 1;
80}
81
82/*
50 * Bare-bones access to getattr: this is for nfs_read_super. 83 * Bare-bones access to getattr: this is for nfs_read_super.
51 */ 84 */
52static int 85static int
@@ -307,6 +340,8 @@ nfs_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
307 340
308static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir) 341static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir)
309{ 342{
343 if (nfs_async_handle_expired_key(task))
344 return 0;
310 nfs_mark_for_revalidate(dir); 345 nfs_mark_for_revalidate(dir);
311 return 1; 346 return 1;
312} 347}
@@ -560,6 +595,9 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
560 595
561static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data) 596static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
562{ 597{
598 if (nfs_async_handle_expired_key(task))
599 return -EAGAIN;
600
563 nfs_invalidate_atime(data->inode); 601 nfs_invalidate_atime(data->inode);
564 if (task->tk_status >= 0) { 602 if (task->tk_status >= 0) {
565 nfs_refresh_inode(data->inode, data->res.fattr); 603 nfs_refresh_inode(data->inode, data->res.fattr);
@@ -579,6 +617,9 @@ static void nfs_proc_read_setup(struct nfs_read_data *data, struct rpc_message *
579 617
580static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data) 618static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
581{ 619{
620 if (nfs_async_handle_expired_key(task))
621 return -EAGAIN;
622
582 if (task->tk_status >= 0) 623 if (task->tk_status >= 0)
583 nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr); 624 nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr);
584 return 0; 625 return 0;
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index 412738dbfbc7..2ea9e5c27e55 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -50,7 +50,7 @@ static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
50 struct page *page; 50 struct page *page;
51 void *err; 51 void *err;
52 52
53 err = ERR_PTR(nfs_revalidate_mapping_nolock(inode, inode->i_mapping)); 53 err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping));
54 if (err) 54 if (err)
55 goto read_failed; 55 goto read_failed;
56 page = read_cache_page(&inode->i_data, 0, 56 page = read_cache_page(&inode->i_data, 0,
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index d63d964a0392..53ff70e23993 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -438,6 +438,7 @@ nfs_mark_request_commit(struct nfs_page *req)
438 radix_tree_tag_set(&nfsi->nfs_page_tree, 438 radix_tree_tag_set(&nfsi->nfs_page_tree,
439 req->wb_index, 439 req->wb_index,
440 NFS_PAGE_TAG_COMMIT); 440 NFS_PAGE_TAG_COMMIT);
441 nfsi->ncommit++;
441 spin_unlock(&inode->i_lock); 442 spin_unlock(&inode->i_lock);
442 inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 443 inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
443 inc_bdi_stat(req->wb_page->mapping->backing_dev_info, BDI_RECLAIMABLE); 444 inc_bdi_stat(req->wb_page->mapping->backing_dev_info, BDI_RECLAIMABLE);
@@ -501,57 +502,6 @@ int nfs_reschedule_unstable_write(struct nfs_page *req)
501} 502}
502#endif 503#endif
503 504
504/*
505 * Wait for a request to complete.
506 *
507 * Interruptible by fatal signals only.
508 */
509static int nfs_wait_on_requests_locked(struct inode *inode, pgoff_t idx_start, unsigned int npages)
510{
511 struct nfs_inode *nfsi = NFS_I(inode);
512 struct nfs_page *req;
513 pgoff_t idx_end, next;
514 unsigned int res = 0;
515 int error;
516
517 if (npages == 0)
518 idx_end = ~0;
519 else
520 idx_end = idx_start + npages - 1;
521
522 next = idx_start;
523 while (radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, (void **)&req, next, 1, NFS_PAGE_TAG_LOCKED)) {
524 if (req->wb_index > idx_end)
525 break;
526
527 next = req->wb_index + 1;
528 BUG_ON(!NFS_WBACK_BUSY(req));
529
530 kref_get(&req->wb_kref);
531 spin_unlock(&inode->i_lock);
532 error = nfs_wait_on_request(req);
533 nfs_release_request(req);
534 spin_lock(&inode->i_lock);
535 if (error < 0)
536 return error;
537 res++;
538 }
539 return res;
540}
541
542static void nfs_cancel_commit_list(struct list_head *head)
543{
544 struct nfs_page *req;
545
546 while(!list_empty(head)) {
547 req = nfs_list_entry(head->next);
548 nfs_list_remove_request(req);
549 nfs_clear_request_commit(req);
550 nfs_inode_remove_request(req);
551 nfs_unlock_request(req);
552 }
553}
554
555#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 505#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
556static int 506static int
557nfs_need_commit(struct nfs_inode *nfsi) 507nfs_need_commit(struct nfs_inode *nfsi)
@@ -573,11 +523,17 @@ static int
573nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages) 523nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages)
574{ 524{
575 struct nfs_inode *nfsi = NFS_I(inode); 525 struct nfs_inode *nfsi = NFS_I(inode);
526 int ret;
576 527
577 if (!nfs_need_commit(nfsi)) 528 if (!nfs_need_commit(nfsi))
578 return 0; 529 return 0;
579 530
580 return nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT); 531 ret = nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT);
532 if (ret > 0)
533 nfsi->ncommit -= ret;
534 if (nfs_need_commit(NFS_I(inode)))
535 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
536 return ret;
581} 537}
582#else 538#else
583static inline int nfs_need_commit(struct nfs_inode *nfsi) 539static inline int nfs_need_commit(struct nfs_inode *nfsi)
@@ -642,9 +598,10 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
642 spin_lock(&inode->i_lock); 598 spin_lock(&inode->i_lock);
643 } 599 }
644 600
645 if (nfs_clear_request_commit(req)) 601 if (nfs_clear_request_commit(req) &&
646 radix_tree_tag_clear(&NFS_I(inode)->nfs_page_tree, 602 radix_tree_tag_clear(&NFS_I(inode)->nfs_page_tree,
647 req->wb_index, NFS_PAGE_TAG_COMMIT); 603 req->wb_index, NFS_PAGE_TAG_COMMIT) != NULL)
604 NFS_I(inode)->ncommit--;
648 605
649 /* Okay, the request matches. Update the region */ 606 /* Okay, the request matches. Update the region */
650 if (offset < req->wb_offset) { 607 if (offset < req->wb_offset) {
@@ -1391,7 +1348,7 @@ static const struct rpc_call_ops nfs_commit_ops = {
1391 .rpc_release = nfs_commit_release, 1348 .rpc_release = nfs_commit_release,
1392}; 1349};
1393 1350
1394int nfs_commit_inode(struct inode *inode, int how) 1351static int nfs_commit_inode(struct inode *inode, int how)
1395{ 1352{
1396 LIST_HEAD(head); 1353 LIST_HEAD(head);
1397 int res; 1354 int res;
@@ -1406,92 +1363,51 @@ int nfs_commit_inode(struct inode *inode, int how)
1406 } 1363 }
1407 return res; 1364 return res;
1408} 1365}
1409#else
1410static inline int nfs_commit_list(struct inode *inode, struct list_head *head, int how)
1411{
1412 return 0;
1413}
1414#endif
1415 1366
1416long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_control *wbc, int how) 1367static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_control *wbc)
1417{ 1368{
1418 struct inode *inode = mapping->host; 1369 struct nfs_inode *nfsi = NFS_I(inode);
1419 pgoff_t idx_start, idx_end; 1370 int flags = FLUSH_SYNC;
1420 unsigned int npages = 0; 1371 int ret = 0;
1421 LIST_HEAD(head); 1372
1422 int nocommit = how & FLUSH_NOCOMMIT; 1373 /* Don't commit yet if this is a non-blocking flush and there are
1423 long pages, ret; 1374 * lots of outstanding writes for this mapping.
1424 1375 */
1425 /* FIXME */ 1376 if (wbc->sync_mode == WB_SYNC_NONE &&
1426 if (wbc->range_cyclic) 1377 nfsi->ncommit <= (nfsi->npages >> 1))
1427 idx_start = 0; 1378 goto out_mark_dirty;
1428 else { 1379
1429 idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; 1380 if (wbc->nonblocking || wbc->for_background)
1430 idx_end = wbc->range_end >> PAGE_CACHE_SHIFT; 1381 flags = 0;
1431 if (idx_end > idx_start) { 1382 ret = nfs_commit_inode(inode, flags);
1432 pgoff_t l_npages = 1 + idx_end - idx_start; 1383 if (ret >= 0) {
1433 npages = l_npages; 1384 if (wbc->sync_mode == WB_SYNC_NONE) {
1434 if (sizeof(npages) != sizeof(l_npages) && 1385 if (ret < wbc->nr_to_write)
1435 (pgoff_t)npages != l_npages) 1386 wbc->nr_to_write -= ret;
1436 npages = 0; 1387 else
1388 wbc->nr_to_write = 0;
1437 } 1389 }
1390 return 0;
1438 } 1391 }
1439 how &= ~FLUSH_NOCOMMIT; 1392out_mark_dirty:
1440 spin_lock(&inode->i_lock); 1393 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
1441 do {
1442 ret = nfs_wait_on_requests_locked(inode, idx_start, npages);
1443 if (ret != 0)
1444 continue;
1445 if (nocommit)
1446 break;
1447 pages = nfs_scan_commit(inode, &head, idx_start, npages);
1448 if (pages == 0)
1449 break;
1450 if (how & FLUSH_INVALIDATE) {
1451 spin_unlock(&inode->i_lock);
1452 nfs_cancel_commit_list(&head);
1453 ret = pages;
1454 spin_lock(&inode->i_lock);
1455 continue;
1456 }
1457 pages += nfs_scan_commit(inode, &head, 0, 0);
1458 spin_unlock(&inode->i_lock);
1459 ret = nfs_commit_list(inode, &head, how);
1460 spin_lock(&inode->i_lock);
1461
1462 } while (ret >= 0);
1463 spin_unlock(&inode->i_lock);
1464 return ret; 1394 return ret;
1465} 1395}
1466 1396#else
1467static int __nfs_write_mapping(struct address_space *mapping, struct writeback_control *wbc, int how) 1397static int nfs_commit_inode(struct inode *inode, int how)
1468{ 1398{
1469 int ret;
1470
1471 ret = nfs_writepages(mapping, wbc);
1472 if (ret < 0)
1473 goto out;
1474 ret = nfs_sync_mapping_wait(mapping, wbc, how);
1475 if (ret < 0)
1476 goto out;
1477 return 0; 1399 return 0;
1478out:
1479 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
1480 return ret;
1481} 1400}
1482 1401
1483/* Two pass sync: first using WB_SYNC_NONE, then WB_SYNC_ALL */ 1402static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_control *wbc)
1484static int nfs_write_mapping(struct address_space *mapping, int how)
1485{ 1403{
1486 struct writeback_control wbc = { 1404 return 0;
1487 .bdi = mapping->backing_dev_info, 1405}
1488 .sync_mode = WB_SYNC_ALL, 1406#endif
1489 .nr_to_write = LONG_MAX,
1490 .range_start = 0,
1491 .range_end = LLONG_MAX,
1492 };
1493 1407
1494 return __nfs_write_mapping(mapping, &wbc, how); 1408int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
1409{
1410 return nfs_commit_unstable_pages(inode, wbc);
1495} 1411}
1496 1412
1497/* 1413/*
@@ -1499,37 +1415,26 @@ static int nfs_write_mapping(struct address_space *mapping, int how)
1499 */ 1415 */
1500int nfs_wb_all(struct inode *inode) 1416int nfs_wb_all(struct inode *inode)
1501{ 1417{
1502 return nfs_write_mapping(inode->i_mapping, 0); 1418 struct writeback_control wbc = {
1503} 1419 .sync_mode = WB_SYNC_ALL,
1420 .nr_to_write = LONG_MAX,
1421 .range_start = 0,
1422 .range_end = LLONG_MAX,
1423 };
1504 1424
1505int nfs_wb_nocommit(struct inode *inode) 1425 return sync_inode(inode, &wbc);
1506{
1507 return nfs_write_mapping(inode->i_mapping, FLUSH_NOCOMMIT);
1508} 1426}
1509 1427
1510int nfs_wb_page_cancel(struct inode *inode, struct page *page) 1428int nfs_wb_page_cancel(struct inode *inode, struct page *page)
1511{ 1429{
1512 struct nfs_page *req; 1430 struct nfs_page *req;
1513 loff_t range_start = page_offset(page);
1514 loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1);
1515 struct writeback_control wbc = {
1516 .bdi = page->mapping->backing_dev_info,
1517 .sync_mode = WB_SYNC_ALL,
1518 .nr_to_write = LONG_MAX,
1519 .range_start = range_start,
1520 .range_end = range_end,
1521 };
1522 int ret = 0; 1431 int ret = 0;
1523 1432
1524 BUG_ON(!PageLocked(page)); 1433 BUG_ON(!PageLocked(page));
1525 for (;;) { 1434 for (;;) {
1526 req = nfs_page_find_request(page); 1435 req = nfs_page_find_request(page);
1527 if (req == NULL) 1436 if (req == NULL)
1528 goto out;
1529 if (test_bit(PG_CLEAN, &req->wb_flags)) {
1530 nfs_release_request(req);
1531 break; 1437 break;
1532 }
1533 if (nfs_lock_request_dontget(req)) { 1438 if (nfs_lock_request_dontget(req)) {
1534 nfs_inode_remove_request(req); 1439 nfs_inode_remove_request(req);
1535 /* 1440 /*
@@ -1543,54 +1448,54 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
1543 ret = nfs_wait_on_request(req); 1448 ret = nfs_wait_on_request(req);
1544 nfs_release_request(req); 1449 nfs_release_request(req);
1545 if (ret < 0) 1450 if (ret < 0)
1546 goto out; 1451 break;
1547 } 1452 }
1548 if (!PagePrivate(page))
1549 return 0;
1550 ret = nfs_sync_mapping_wait(page->mapping, &wbc, FLUSH_INVALIDATE);
1551out:
1552 return ret; 1453 return ret;
1553} 1454}
1554 1455
1555static int nfs_wb_page_priority(struct inode *inode, struct page *page, 1456/*
1556 int how) 1457 * Write back all requests on one page - we do this before reading it.
1458 */
1459int nfs_wb_page(struct inode *inode, struct page *page)
1557{ 1460{
1558 loff_t range_start = page_offset(page); 1461 loff_t range_start = page_offset(page);
1559 loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); 1462 loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1);
1560 struct writeback_control wbc = { 1463 struct writeback_control wbc = {
1561 .bdi = page->mapping->backing_dev_info,
1562 .sync_mode = WB_SYNC_ALL, 1464 .sync_mode = WB_SYNC_ALL,
1563 .nr_to_write = LONG_MAX, 1465 .nr_to_write = 0,
1564 .range_start = range_start, 1466 .range_start = range_start,
1565 .range_end = range_end, 1467 .range_end = range_end,
1566 }; 1468 };
1469 struct nfs_page *req;
1470 int need_commit;
1567 int ret; 1471 int ret;
1568 1472
1569 do { 1473 while(PagePrivate(page)) {
1570 if (clear_page_dirty_for_io(page)) { 1474 if (clear_page_dirty_for_io(page)) {
1571 ret = nfs_writepage_locked(page, &wbc); 1475 ret = nfs_writepage_locked(page, &wbc);
1572 if (ret < 0) 1476 if (ret < 0)
1573 goto out_error; 1477 goto out_error;
1574 } else if (!PagePrivate(page)) 1478 }
1479 req = nfs_find_and_lock_request(page);
1480 if (!req)
1575 break; 1481 break;
1576 ret = nfs_sync_mapping_wait(page->mapping, &wbc, how); 1482 if (IS_ERR(req)) {
1577 if (ret < 0) 1483 ret = PTR_ERR(req);
1578 goto out_error; 1484 goto out_error;
1579 } while (PagePrivate(page)); 1485 }
1486 need_commit = test_bit(PG_CLEAN, &req->wb_flags);
1487 nfs_clear_page_tag_locked(req);
1488 if (need_commit) {
1489 ret = nfs_commit_inode(inode, FLUSH_SYNC);
1490 if (ret < 0)
1491 goto out_error;
1492 }
1493 }
1580 return 0; 1494 return 0;
1581out_error: 1495out_error:
1582 __mark_inode_dirty(inode, I_DIRTY_PAGES);
1583 return ret; 1496 return ret;
1584} 1497}
1585 1498
1586/*
1587 * Write back all requests on one page - we do this before reading it.
1588 */
1589int nfs_wb_page(struct inode *inode, struct page* page)
1590{
1591 return nfs_wb_page_priority(inode, page, FLUSH_STABLE);
1592}
1593
1594#ifdef CONFIG_MIGRATION 1499#ifdef CONFIG_MIGRATION
1595int nfs_migrate_page(struct address_space *mapping, struct page *newpage, 1500int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
1596 struct page *page) 1501 struct page *page)