aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c458
1 files changed, 287 insertions, 171 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 741a562177fc..9f5f11ecfd93 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -270,11 +270,18 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
270 case -NFS4ERR_SEQ_MISORDERED: 270 case -NFS4ERR_SEQ_MISORDERED:
271 dprintk("%s ERROR: %d Reset session\n", __func__, 271 dprintk("%s ERROR: %d Reset session\n", __func__,
272 errorcode); 272 errorcode);
273 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); 273 nfs4_schedule_state_recovery(clp);
274 exception->retry = 1; 274 exception->retry = 1;
275 /* FALLTHROUGH */ 275 break;
276#endif /* !defined(CONFIG_NFS_V4_1) */ 276#endif /* !defined(CONFIG_NFS_V4_1) */
277 case -NFS4ERR_FILE_OPEN: 277 case -NFS4ERR_FILE_OPEN:
278 if (exception->timeout > HZ) {
279 /* We have retried a decent amount, time to
280 * fail
281 */
282 ret = -EBUSY;
283 break;
284 }
278 case -NFS4ERR_GRACE: 285 case -NFS4ERR_GRACE:
279 case -NFS4ERR_DELAY: 286 case -NFS4ERR_DELAY:
280 ret = nfs4_delay(server->client, &exception->timeout); 287 ret = nfs4_delay(server->client, &exception->timeout);
@@ -311,48 +318,54 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
311 * so we need to scan down from highest_used_slotid to 0 looking for the now 318 * so we need to scan down from highest_used_slotid to 0 looking for the now
312 * highest slotid in use. 319 * highest slotid in use.
313 * If none found, highest_used_slotid is set to -1. 320 * If none found, highest_used_slotid is set to -1.
321 *
322 * Must be called while holding tbl->slot_tbl_lock
314 */ 323 */
315static void 324static void
316nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) 325nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
317{ 326{
318 int slotid = free_slotid; 327 int slotid = free_slotid;
319 328
320 spin_lock(&tbl->slot_tbl_lock);
321 /* clear used bit in bitmap */ 329 /* clear used bit in bitmap */
322 __clear_bit(slotid, tbl->used_slots); 330 __clear_bit(slotid, tbl->used_slots);
323 331
324 /* update highest_used_slotid when it is freed */ 332 /* update highest_used_slotid when it is freed */
325 if (slotid == tbl->highest_used_slotid) { 333 if (slotid == tbl->highest_used_slotid) {
326 slotid = find_last_bit(tbl->used_slots, tbl->max_slots); 334 slotid = find_last_bit(tbl->used_slots, tbl->max_slots);
327 if (slotid >= 0 && slotid < tbl->max_slots) 335 if (slotid < tbl->max_slots)
328 tbl->highest_used_slotid = slotid; 336 tbl->highest_used_slotid = slotid;
329 else 337 else
330 tbl->highest_used_slotid = -1; 338 tbl->highest_used_slotid = -1;
331 } 339 }
332 rpc_wake_up_next(&tbl->slot_tbl_waitq);
333 spin_unlock(&tbl->slot_tbl_lock);
334 dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__, 340 dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__,
335 free_slotid, tbl->highest_used_slotid); 341 free_slotid, tbl->highest_used_slotid);
336} 342}
337 343
338void nfs41_sequence_free_slot(const struct nfs_client *clp, 344static void nfs41_sequence_free_slot(const struct nfs_client *clp,
339 struct nfs4_sequence_res *res) 345 struct nfs4_sequence_res *res)
340{ 346{
341 struct nfs4_slot_table *tbl; 347 struct nfs4_slot_table *tbl;
342 348
343 if (!nfs4_has_session(clp)) {
344 dprintk("%s: No session\n", __func__);
345 return;
346 }
347 tbl = &clp->cl_session->fc_slot_table; 349 tbl = &clp->cl_session->fc_slot_table;
348 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) { 350 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) {
349 dprintk("%s: No slot\n", __func__);
350 /* just wake up the next guy waiting since 351 /* just wake up the next guy waiting since
351 * we may have not consumed a slot after all */ 352 * we may have not consumed a slot after all */
352 rpc_wake_up_next(&tbl->slot_tbl_waitq); 353 dprintk("%s: No slot\n", __func__);
353 return; 354 return;
354 } 355 }
356
357 spin_lock(&tbl->slot_tbl_lock);
355 nfs4_free_slot(tbl, res->sr_slotid); 358 nfs4_free_slot(tbl, res->sr_slotid);
359
360 /* Signal state manager thread if session is drained */
361 if (test_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) {
362 if (tbl->highest_used_slotid == -1) {
363 dprintk("%s COMPLETE: Session Drained\n", __func__);
364 complete(&clp->cl_session->complete);
365 }
366 } else
367 rpc_wake_up_next(&tbl->slot_tbl_waitq);
368 spin_unlock(&tbl->slot_tbl_lock);
356 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 369 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
357} 370}
358 371
@@ -377,10 +390,10 @@ static void nfs41_sequence_done(struct nfs_client *clp,
377 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) 390 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE)
378 goto out; 391 goto out;
379 392
380 tbl = &clp->cl_session->fc_slot_table; 393 /* Check the SEQUENCE operation status */
381 slot = tbl->slots + res->sr_slotid;
382
383 if (res->sr_status == 0) { 394 if (res->sr_status == 0) {
395 tbl = &clp->cl_session->fc_slot_table;
396 slot = tbl->slots + res->sr_slotid;
384 /* Update the slot's sequence and clientid lease timer */ 397 /* Update the slot's sequence and clientid lease timer */
385 ++slot->seq_nr; 398 ++slot->seq_nr;
386 timestamp = res->sr_renewal_time; 399 timestamp = res->sr_renewal_time;
@@ -388,7 +401,8 @@ static void nfs41_sequence_done(struct nfs_client *clp,
388 if (time_before(clp->cl_last_renewal, timestamp)) 401 if (time_before(clp->cl_last_renewal, timestamp))
389 clp->cl_last_renewal = timestamp; 402 clp->cl_last_renewal = timestamp;
390 spin_unlock(&clp->cl_lock); 403 spin_unlock(&clp->cl_lock);
391 return; 404 /* Check sequence flags */
405 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags);
392 } 406 }
393out: 407out:
394 /* The session may be reset by one of the error handlers. */ 408 /* The session may be reset by one of the error handlers. */
@@ -429,24 +443,6 @@ out:
429 return ret_id; 443 return ret_id;
430} 444}
431 445
432static int nfs4_recover_session(struct nfs4_session *session)
433{
434 struct nfs_client *clp = session->clp;
435 unsigned int loop;
436 int ret;
437
438 for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
439 ret = nfs4_wait_clnt_recover(clp);
440 if (ret != 0)
441 break;
442 if (!test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
443 break;
444 nfs4_schedule_state_manager(clp);
445 ret = -EIO;
446 }
447 return ret;
448}
449
450static int nfs41_setup_sequence(struct nfs4_session *session, 446static int nfs41_setup_sequence(struct nfs4_session *session,
451 struct nfs4_sequence_args *args, 447 struct nfs4_sequence_args *args,
452 struct nfs4_sequence_res *res, 448 struct nfs4_sequence_res *res,
@@ -455,7 +451,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
455{ 451{
456 struct nfs4_slot *slot; 452 struct nfs4_slot *slot;
457 struct nfs4_slot_table *tbl; 453 struct nfs4_slot_table *tbl;
458 int status = 0;
459 u8 slotid; 454 u8 slotid;
460 455
461 dprintk("--> %s\n", __func__); 456 dprintk("--> %s\n", __func__);
@@ -468,21 +463,15 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
468 tbl = &session->fc_slot_table; 463 tbl = &session->fc_slot_table;
469 464
470 spin_lock(&tbl->slot_tbl_lock); 465 spin_lock(&tbl->slot_tbl_lock);
471 if (test_bit(NFS4CLNT_SESSION_SETUP, &session->clp->cl_state)) { 466 if (test_bit(NFS4CLNT_SESSION_DRAINING, &session->clp->cl_state)) {
472 if (tbl->highest_used_slotid != -1) { 467 /*
473 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 468 * The state manager will wait until the slot table is empty.
474 spin_unlock(&tbl->slot_tbl_lock); 469 * Schedule the reset thread
475 dprintk("<-- %s: Session reset: draining\n", __func__); 470 */
476 return -EAGAIN; 471 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
477 }
478
479 /* The slot table is empty; start the reset thread */
480 dprintk("%s Session Reset\n", __func__);
481 spin_unlock(&tbl->slot_tbl_lock); 472 spin_unlock(&tbl->slot_tbl_lock);
482 status = nfs4_recover_session(session); 473 dprintk("%s Schedule Session Reset\n", __func__);
483 if (status) 474 return -EAGAIN;
484 return status;
485 spin_lock(&tbl->slot_tbl_lock);
486 } 475 }
487 476
488 slotid = nfs4_find_slot(tbl, task); 477 slotid = nfs4_find_slot(tbl, task);
@@ -527,7 +516,7 @@ int nfs4_setup_sequence(struct nfs_client *clp,
527 goto out; 516 goto out;
528 ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply, 517 ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply,
529 task); 518 task);
530 if (ret != -EAGAIN) { 519 if (ret && ret != -EAGAIN) {
531 /* terminate rpc task */ 520 /* terminate rpc task */
532 task->tk_status = ret; 521 task->tk_status = ret;
533 task->tk_action = NULL; 522 task->tk_action = NULL;
@@ -561,7 +550,6 @@ static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
561 struct nfs41_call_sync_data *data = calldata; 550 struct nfs41_call_sync_data *data = calldata;
562 551
563 nfs41_sequence_done(data->clp, data->seq_res, task->tk_status); 552 nfs41_sequence_done(data->clp, data->seq_res, task->tk_status);
564 nfs41_sequence_free_slot(data->clp, data->seq_res);
565} 553}
566 554
567struct rpc_call_ops nfs41_call_sync_ops = { 555struct rpc_call_ops nfs41_call_sync_ops = {
@@ -637,15 +625,6 @@ static void nfs4_sequence_done(const struct nfs_server *server,
637#endif /* CONFIG_NFS_V4_1 */ 625#endif /* CONFIG_NFS_V4_1 */
638} 626}
639 627
640/* no restart, therefore free slot here */
641static void nfs4_sequence_done_free_slot(const struct nfs_server *server,
642 struct nfs4_sequence_res *res,
643 int rpc_status)
644{
645 nfs4_sequence_done(server, res, rpc_status);
646 nfs4_sequence_free_slot(server->nfs_client, res);
647}
648
649static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) 628static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
650{ 629{
651 struct nfs_inode *nfsi = NFS_I(dir); 630 struct nfs_inode *nfsi = NFS_I(dir);
@@ -720,9 +699,15 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
720 p->o_arg.bitmask = server->attr_bitmask; 699 p->o_arg.bitmask = server->attr_bitmask;
721 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 700 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
722 if (flags & O_EXCL) { 701 if (flags & O_EXCL) {
723 u32 *s = (u32 *) p->o_arg.u.verifier.data; 702 if (nfs4_has_persistent_session(server->nfs_client)) {
724 s[0] = jiffies; 703 /* GUARDED */
725 s[1] = current->pid; 704 p->o_arg.u.attrs = &p->attrs;
705 memcpy(&p->attrs, attrs, sizeof(p->attrs));
706 } else { /* EXCLUSIVE4_1 */
707 u32 *s = (u32 *) p->o_arg.u.verifier.data;
708 s[0] = jiffies;
709 s[1] = current->pid;
710 }
726 } else if (flags & O_CREAT) { 711 } else if (flags & O_CREAT) {
727 p->o_arg.u.attrs = &p->attrs; 712 p->o_arg.u.attrs = &p->attrs;
728 memcpy(&p->attrs, attrs, sizeof(p->attrs)); 713 memcpy(&p->attrs, attrs, sizeof(p->attrs));
@@ -776,13 +761,16 @@ static int can_open_cached(struct nfs4_state *state, fmode_t mode, int open_mode
776 goto out; 761 goto out;
777 switch (mode & (FMODE_READ|FMODE_WRITE)) { 762 switch (mode & (FMODE_READ|FMODE_WRITE)) {
778 case FMODE_READ: 763 case FMODE_READ:
779 ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0; 764 ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0
765 && state->n_rdonly != 0;
780 break; 766 break;
781 case FMODE_WRITE: 767 case FMODE_WRITE:
782 ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0; 768 ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0
769 && state->n_wronly != 0;
783 break; 770 break;
784 case FMODE_READ|FMODE_WRITE: 771 case FMODE_READ|FMODE_WRITE:
785 ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0; 772 ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0
773 && state->n_rdwr != 0;
786 } 774 }
787out: 775out:
788 return ret; 776 return ret;
@@ -1183,6 +1171,14 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1183 case -ENOENT: 1171 case -ENOENT:
1184 case -ESTALE: 1172 case -ESTALE:
1185 goto out; 1173 goto out;
1174 case -NFS4ERR_BADSESSION:
1175 case -NFS4ERR_BADSLOT:
1176 case -NFS4ERR_BAD_HIGH_SLOT:
1177 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1178 case -NFS4ERR_DEADSESSION:
1179 nfs4_schedule_state_recovery(
1180 server->nfs_client);
1181 goto out;
1186 case -NFS4ERR_STALE_CLIENTID: 1182 case -NFS4ERR_STALE_CLIENTID:
1187 case -NFS4ERR_STALE_STATEID: 1183 case -NFS4ERR_STALE_STATEID:
1188 case -NFS4ERR_EXPIRED: 1184 case -NFS4ERR_EXPIRED:
@@ -1336,8 +1332,8 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
1336 1332
1337 data->rpc_status = task->tk_status; 1333 data->rpc_status = task->tk_status;
1338 1334
1339 nfs4_sequence_done_free_slot(data->o_arg.server, &data->o_res.seq_res, 1335 nfs4_sequence_done(data->o_arg.server, &data->o_res.seq_res,
1340 task->tk_status); 1336 task->tk_status);
1341 1337
1342 if (RPC_ASSASSINATED(task)) 1338 if (RPC_ASSASSINATED(task))
1343 return; 1339 return;
@@ -1488,7 +1484,7 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
1488 return ret; 1484 return ret;
1489} 1485}
1490 1486
1491static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) 1487static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
1492{ 1488{
1493 struct nfs_server *server = NFS_SERVER(state->inode); 1489 struct nfs_server *server = NFS_SERVER(state->inode);
1494 struct nfs4_exception exception = { }; 1490 struct nfs4_exception exception = { };
@@ -1496,10 +1492,16 @@ static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4
1496 1492
1497 do { 1493 do {
1498 err = _nfs4_open_expired(ctx, state); 1494 err = _nfs4_open_expired(ctx, state);
1499 if (err != -NFS4ERR_DELAY) 1495 switch (err) {
1500 break; 1496 default:
1501 nfs4_handle_exception(server, err, &exception); 1497 goto out;
1498 case -NFS4ERR_GRACE:
1499 case -NFS4ERR_DELAY:
1500 nfs4_handle_exception(server, err, &exception);
1501 err = 0;
1502 }
1502 } while (exception.retry); 1503 } while (exception.retry);
1504out:
1503 return err; 1505 return err;
1504} 1506}
1505 1507
@@ -1712,6 +1714,18 @@ static void nfs4_free_closedata(void *data)
1712 kfree(calldata); 1714 kfree(calldata);
1713} 1715}
1714 1716
1717static void nfs4_close_clear_stateid_flags(struct nfs4_state *state,
1718 fmode_t fmode)
1719{
1720 spin_lock(&state->owner->so_lock);
1721 if (!(fmode & FMODE_READ))
1722 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
1723 if (!(fmode & FMODE_WRITE))
1724 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
1725 clear_bit(NFS_O_RDWR_STATE, &state->flags);
1726 spin_unlock(&state->owner->so_lock);
1727}
1728
1715static void nfs4_close_done(struct rpc_task *task, void *data) 1729static void nfs4_close_done(struct rpc_task *task, void *data)
1716{ 1730{
1717 struct nfs4_closedata *calldata = data; 1731 struct nfs4_closedata *calldata = data;
@@ -1728,6 +1742,8 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1728 case 0: 1742 case 0:
1729 nfs_set_open_stateid(state, &calldata->res.stateid, 0); 1743 nfs_set_open_stateid(state, &calldata->res.stateid, 0);
1730 renew_lease(server, calldata->timestamp); 1744 renew_lease(server, calldata->timestamp);
1745 nfs4_close_clear_stateid_flags(state,
1746 calldata->arg.fmode);
1731 break; 1747 break;
1732 case -NFS4ERR_STALE_STATEID: 1748 case -NFS4ERR_STALE_STATEID:
1733 case -NFS4ERR_OLD_STATEID: 1749 case -NFS4ERR_OLD_STATEID:
@@ -1737,11 +1753,10 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1737 break; 1753 break;
1738 default: 1754 default:
1739 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) { 1755 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) {
1740 nfs4_restart_rpc(task, server->nfs_client); 1756 nfs_restart_rpc(task, server->nfs_client);
1741 return; 1757 return;
1742 } 1758 }
1743 } 1759 }
1744 nfs4_sequence_free_slot(server->nfs_client, &calldata->res.seq_res);
1745 nfs_refresh_inode(calldata->inode, calldata->res.fattr); 1760 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
1746} 1761}
1747 1762
@@ -1749,38 +1764,39 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
1749{ 1764{
1750 struct nfs4_closedata *calldata = data; 1765 struct nfs4_closedata *calldata = data;
1751 struct nfs4_state *state = calldata->state; 1766 struct nfs4_state *state = calldata->state;
1752 int clear_rd, clear_wr, clear_rdwr; 1767 int call_close = 0;
1753 1768
1754 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) 1769 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
1755 return; 1770 return;
1756 1771
1757 clear_rd = clear_wr = clear_rdwr = 0; 1772 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1773 calldata->arg.fmode = FMODE_READ|FMODE_WRITE;
1758 spin_lock(&state->owner->so_lock); 1774 spin_lock(&state->owner->so_lock);
1759 /* Calculate the change in open mode */ 1775 /* Calculate the change in open mode */
1760 if (state->n_rdwr == 0) { 1776 if (state->n_rdwr == 0) {
1761 if (state->n_rdonly == 0) { 1777 if (state->n_rdonly == 0) {
1762 clear_rd |= test_and_clear_bit(NFS_O_RDONLY_STATE, &state->flags); 1778 call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags);
1763 clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); 1779 call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
1780 calldata->arg.fmode &= ~FMODE_READ;
1764 } 1781 }
1765 if (state->n_wronly == 0) { 1782 if (state->n_wronly == 0) {
1766 clear_wr |= test_and_clear_bit(NFS_O_WRONLY_STATE, &state->flags); 1783 call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags);
1767 clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); 1784 call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
1785 calldata->arg.fmode &= ~FMODE_WRITE;
1768 } 1786 }
1769 } 1787 }
1770 spin_unlock(&state->owner->so_lock); 1788 spin_unlock(&state->owner->so_lock);
1771 if (!clear_rd && !clear_wr && !clear_rdwr) { 1789
1790 if (!call_close) {
1772 /* Note: exit _without_ calling nfs4_close_done */ 1791 /* Note: exit _without_ calling nfs4_close_done */
1773 task->tk_action = NULL; 1792 task->tk_action = NULL;
1774 return; 1793 return;
1775 } 1794 }
1795
1796 if (calldata->arg.fmode == 0)
1797 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
1798
1776 nfs_fattr_init(calldata->res.fattr); 1799 nfs_fattr_init(calldata->res.fattr);
1777 if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0) {
1778 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1779 calldata->arg.fmode = FMODE_READ;
1780 } else if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0) {
1781 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1782 calldata->arg.fmode = FMODE_WRITE;
1783 }
1784 calldata->timestamp = jiffies; 1800 calldata->timestamp = jiffies;
1785 if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client, 1801 if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client,
1786 &calldata->arg.seq_args, &calldata->res.seq_res, 1802 &calldata->arg.seq_args, &calldata->res.seq_res,
@@ -1981,7 +1997,7 @@ out_drop:
1981 return 0; 1997 return 0;
1982} 1998}
1983 1999
1984void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) 2000static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
1985{ 2001{
1986 if (ctx->state == NULL) 2002 if (ctx->state == NULL)
1987 return; 2003 return;
@@ -2532,7 +2548,6 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
2532 nfs4_sequence_done(res->server, &res->seq_res, task->tk_status); 2548 nfs4_sequence_done(res->server, &res->seq_res, task->tk_status);
2533 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) 2549 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
2534 return 0; 2550 return 0;
2535 nfs4_sequence_free_slot(res->server->nfs_client, &res->seq_res);
2536 update_changeattr(dir, &res->cinfo); 2551 update_changeattr(dir, &res->cinfo);
2537 nfs_post_op_update_inode(dir, &res->dir_attr); 2552 nfs_post_op_update_inode(dir, &res->dir_attr);
2538 return 1; 2553 return 1;
@@ -2971,11 +2986,10 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
2971 2986
2972 dprintk("--> %s\n", __func__); 2987 dprintk("--> %s\n", __func__);
2973 2988
2974 /* nfs4_sequence_free_slot called in the read rpc_call_done */
2975 nfs4_sequence_done(server, &data->res.seq_res, task->tk_status); 2989 nfs4_sequence_done(server, &data->res.seq_res, task->tk_status);
2976 2990
2977 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 2991 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
2978 nfs4_restart_rpc(task, server->nfs_client); 2992 nfs_restart_rpc(task, server->nfs_client);
2979 return -EAGAIN; 2993 return -EAGAIN;
2980 } 2994 }
2981 2995
@@ -2995,12 +3009,11 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
2995{ 3009{
2996 struct inode *inode = data->inode; 3010 struct inode *inode = data->inode;
2997 3011
2998 /* slot is freed in nfs_writeback_done */
2999 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, 3012 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
3000 task->tk_status); 3013 task->tk_status);
3001 3014
3002 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 3015 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
3003 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3016 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
3004 return -EAGAIN; 3017 return -EAGAIN;
3005 } 3018 }
3006 if (task->tk_status >= 0) { 3019 if (task->tk_status >= 0) {
@@ -3028,11 +3041,9 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
3028 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, 3041 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
3029 task->tk_status); 3042 task->tk_status);
3030 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 3043 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
3031 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3044 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
3032 return -EAGAIN; 3045 return -EAGAIN;
3033 } 3046 }
3034 nfs4_sequence_free_slot(NFS_SERVER(inode)->nfs_client,
3035 &data->res.seq_res);
3036 nfs_refresh_inode(inode, data->res.fattr); 3047 nfs_refresh_inode(inode, data->res.fattr);
3037 return 0; 3048 return 0;
3038} 3049}
@@ -3350,7 +3361,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3350 case -NFS4ERR_SEQ_MISORDERED: 3361 case -NFS4ERR_SEQ_MISORDERED:
3351 dprintk("%s ERROR %d, Reset session\n", __func__, 3362 dprintk("%s ERROR %d, Reset session\n", __func__,
3352 task->tk_status); 3363 task->tk_status);
3353 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); 3364 nfs4_schedule_state_recovery(clp);
3354 task->tk_status = 0; 3365 task->tk_status = 0;
3355 return -EAGAIN; 3366 return -EAGAIN;
3356#endif /* CONFIG_NFS_V4_1 */ 3367#endif /* CONFIG_NFS_V4_1 */
@@ -3483,12 +3494,23 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
3483{ 3494{
3484 struct nfs4_delegreturndata *data = calldata; 3495 struct nfs4_delegreturndata *data = calldata;
3485 3496
3486 nfs4_sequence_done_free_slot(data->res.server, &data->res.seq_res, 3497 nfs4_sequence_done(data->res.server, &data->res.seq_res,
3487 task->tk_status); 3498 task->tk_status);
3488 3499
3489 data->rpc_status = task->tk_status; 3500 switch (task->tk_status) {
3490 if (data->rpc_status == 0) 3501 case -NFS4ERR_STALE_STATEID:
3502 case -NFS4ERR_EXPIRED:
3503 case 0:
3491 renew_lease(data->res.server, data->timestamp); 3504 renew_lease(data->res.server, data->timestamp);
3505 break;
3506 default:
3507 if (nfs4_async_handle_error(task, data->res.server, NULL) ==
3508 -EAGAIN) {
3509 nfs_restart_rpc(task, data->res.server->nfs_client);
3510 return;
3511 }
3512 }
3513 data->rpc_status = task->tk_status;
3492} 3514}
3493 3515
3494static void nfs4_delegreturn_release(void *calldata) 3516static void nfs4_delegreturn_release(void *calldata)
@@ -3741,11 +3763,9 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3741 break; 3763 break;
3742 default: 3764 default:
3743 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) 3765 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
3744 nfs4_restart_rpc(task, 3766 nfs_restart_rpc(task,
3745 calldata->server->nfs_client); 3767 calldata->server->nfs_client);
3746 } 3768 }
3747 nfs4_sequence_free_slot(calldata->server->nfs_client,
3748 &calldata->res.seq_res);
3749} 3769}
3750 3770
3751static void nfs4_locku_prepare(struct rpc_task *task, void *data) 3771static void nfs4_locku_prepare(struct rpc_task *task, void *data)
@@ -3927,8 +3947,8 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3927 3947
3928 dprintk("%s: begin!\n", __func__); 3948 dprintk("%s: begin!\n", __func__);
3929 3949
3930 nfs4_sequence_done_free_slot(data->server, &data->res.seq_res, 3950 nfs4_sequence_done(data->server, &data->res.seq_res,
3931 task->tk_status); 3951 task->tk_status);
3932 3952
3933 data->rpc_status = task->tk_status; 3953 data->rpc_status = task->tk_status;
3934 if (RPC_ASSASSINATED(task)) 3954 if (RPC_ASSASSINATED(task))
@@ -4049,10 +4069,16 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
4049 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4069 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4050 return 0; 4070 return 0;
4051 err = _nfs4_do_setlk(state, F_SETLK, request, 0); 4071 err = _nfs4_do_setlk(state, F_SETLK, request, 0);
4052 if (err != -NFS4ERR_DELAY) 4072 switch (err) {
4053 break; 4073 default:
4054 nfs4_handle_exception(server, err, &exception); 4074 goto out;
4075 case -NFS4ERR_GRACE:
4076 case -NFS4ERR_DELAY:
4077 nfs4_handle_exception(server, err, &exception);
4078 err = 0;
4079 }
4055 } while (exception.retry); 4080 } while (exception.retry);
4081out:
4056 return err; 4082 return err;
4057} 4083}
4058 4084
@@ -4172,6 +4198,11 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4172 case -NFS4ERR_EXPIRED: 4198 case -NFS4ERR_EXPIRED:
4173 case -NFS4ERR_STALE_CLIENTID: 4199 case -NFS4ERR_STALE_CLIENTID:
4174 case -NFS4ERR_STALE_STATEID: 4200 case -NFS4ERR_STALE_STATEID:
4201 case -NFS4ERR_BADSESSION:
4202 case -NFS4ERR_BADSLOT:
4203 case -NFS4ERR_BAD_HIGH_SLOT:
4204 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
4205 case -NFS4ERR_DEADSESSION:
4175 nfs4_schedule_state_recovery(server->nfs_client); 4206 nfs4_schedule_state_recovery(server->nfs_client);
4176 goto out; 4207 goto out;
4177 case -ERESTARTSYS: 4208 case -ERESTARTSYS:
@@ -4296,7 +4327,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4296 * NFS4ERR_BADSESSION in the sequence operation, and will therefore 4327 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
4297 * be in some phase of session reset. 4328 * be in some phase of session reset.
4298 */ 4329 */
4299static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) 4330int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4300{ 4331{
4301 nfs4_verifier verifier; 4332 nfs4_verifier verifier;
4302 struct nfs41_exchange_id_args args = { 4333 struct nfs41_exchange_id_args args = {
@@ -4318,6 +4349,9 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4318 dprintk("--> %s\n", __func__); 4349 dprintk("--> %s\n", __func__);
4319 BUG_ON(clp == NULL); 4350 BUG_ON(clp == NULL);
4320 4351
4352 /* Remove server-only flags */
4353 args.flags &= ~EXCHGID4_FLAG_CONFIRMED_R;
4354
4321 p = (u32 *)verifier.data; 4355 p = (u32 *)verifier.data;
4322 *p++ = htonl((u32)clp->cl_boot_time.tv_sec); 4356 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
4323 *p = htonl((u32)clp->cl_boot_time.tv_nsec); 4357 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
@@ -4389,10 +4423,9 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
4389 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); 4423 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
4390 rpc_delay(task, NFS4_POLL_RETRY_MIN); 4424 rpc_delay(task, NFS4_POLL_RETRY_MIN);
4391 task->tk_status = 0; 4425 task->tk_status = 0;
4392 nfs4_restart_rpc(task, data->clp); 4426 nfs_restart_rpc(task, data->clp);
4393 return; 4427 return;
4394 } 4428 }
4395 nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res);
4396 dprintk("<-- %s\n", __func__); 4429 dprintk("<-- %s\n", __func__);
4397} 4430}
4398 4431
@@ -4465,7 +4498,6 @@ static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, int max_slots,
4465 spin_lock(&tbl->slot_tbl_lock); 4498 spin_lock(&tbl->slot_tbl_lock);
4466 for (i = 0; i < max_slots; ++i) 4499 for (i = 0; i < max_slots; ++i)
4467 tbl->slots[i].seq_nr = ivalue; 4500 tbl->slots[i].seq_nr = ivalue;
4468 tbl->highest_used_slotid = -1;
4469 spin_unlock(&tbl->slot_tbl_lock); 4501 spin_unlock(&tbl->slot_tbl_lock);
4470 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, 4502 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
4471 tbl, tbl->slots, tbl->max_slots); 4503 tbl, tbl->slots, tbl->max_slots);
@@ -4515,7 +4547,6 @@ static void nfs4_destroy_slot_tables(struct nfs4_session *session)
4515static int nfs4_init_slot_table(struct nfs4_slot_table *tbl, 4547static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4516 int max_slots, int ivalue) 4548 int max_slots, int ivalue)
4517{ 4549{
4518 int i;
4519 struct nfs4_slot *slot; 4550 struct nfs4_slot *slot;
4520 int ret = -ENOMEM; 4551 int ret = -ENOMEM;
4521 4552
@@ -4526,18 +4557,9 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4526 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL); 4557 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL);
4527 if (!slot) 4558 if (!slot)
4528 goto out; 4559 goto out;
4529 for (i = 0; i < max_slots; ++i)
4530 slot[i].seq_nr = ivalue;
4531 ret = 0; 4560 ret = 0;
4532 4561
4533 spin_lock(&tbl->slot_tbl_lock); 4562 spin_lock(&tbl->slot_tbl_lock);
4534 if (tbl->slots != NULL) {
4535 spin_unlock(&tbl->slot_tbl_lock);
4536 dprintk("%s: slot table already initialized. tbl=%p slots=%p\n",
4537 __func__, tbl, tbl->slots);
4538 WARN_ON(1);
4539 goto out_free;
4540 }
4541 tbl->max_slots = max_slots; 4563 tbl->max_slots = max_slots;
4542 tbl->slots = slot; 4564 tbl->slots = slot;
4543 tbl->highest_used_slotid = -1; /* no slot is currently used */ 4565 tbl->highest_used_slotid = -1; /* no slot is currently used */
@@ -4547,10 +4569,6 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4547out: 4569out:
4548 dprintk("<-- %s: return %d\n", __func__, ret); 4570 dprintk("<-- %s: return %d\n", __func__, ret);
4549 return ret; 4571 return ret;
4550
4551out_free:
4552 kfree(slot);
4553 goto out;
4554} 4572}
4555 4573
4556/* 4574/*
@@ -4558,17 +4576,24 @@ out_free:
4558 */ 4576 */
4559static int nfs4_init_slot_tables(struct nfs4_session *session) 4577static int nfs4_init_slot_tables(struct nfs4_session *session)
4560{ 4578{
4561 int status; 4579 struct nfs4_slot_table *tbl;
4580 int status = 0;
4562 4581
4563 status = nfs4_init_slot_table(&session->fc_slot_table, 4582 tbl = &session->fc_slot_table;
4564 session->fc_attrs.max_reqs, 1); 4583 if (tbl->slots == NULL) {
4565 if (status) 4584 status = nfs4_init_slot_table(tbl,
4566 return status; 4585 session->fc_attrs.max_reqs, 1);
4586 if (status)
4587 return status;
4588 }
4567 4589
4568 status = nfs4_init_slot_table(&session->bc_slot_table, 4590 tbl = &session->bc_slot_table;
4569 session->bc_attrs.max_reqs, 0); 4591 if (tbl->slots == NULL) {
4570 if (status) 4592 status = nfs4_init_slot_table(tbl,
4571 nfs4_destroy_slot_tables(session); 4593 session->bc_attrs.max_reqs, 0);
4594 if (status)
4595 nfs4_destroy_slot_tables(session);
4596 }
4572 4597
4573 return status; 4598 return status;
4574} 4599}
@@ -4582,7 +4607,6 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4582 if (!session) 4607 if (!session)
4583 return NULL; 4608 return NULL;
4584 4609
4585 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
4586 /* 4610 /*
4587 * The create session reply races with the server back 4611 * The create session reply races with the server back
4588 * channel probe. Mark the client NFS_CS_SESSION_INITING 4612 * channel probe. Mark the client NFS_CS_SESSION_INITING
@@ -4590,12 +4614,15 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4590 * nfs_client struct 4614 * nfs_client struct
4591 */ 4615 */
4592 clp->cl_cons_state = NFS_CS_SESSION_INITING; 4616 clp->cl_cons_state = NFS_CS_SESSION_INITING;
4617 init_completion(&session->complete);
4593 4618
4594 tbl = &session->fc_slot_table; 4619 tbl = &session->fc_slot_table;
4620 tbl->highest_used_slotid = -1;
4595 spin_lock_init(&tbl->slot_tbl_lock); 4621 spin_lock_init(&tbl->slot_tbl_lock);
4596 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); 4622 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
4597 4623
4598 tbl = &session->bc_slot_table; 4624 tbl = &session->bc_slot_table;
4625 tbl->highest_used_slotid = -1;
4599 spin_lock_init(&tbl->slot_tbl_lock); 4626 spin_lock_init(&tbl->slot_tbl_lock);
4600 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table"); 4627 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
4601 4628
@@ -4747,11 +4774,10 @@ static int _nfs4_proc_create_session(struct nfs_client *clp)
4747 * It is the responsibility of the caller to verify the session is 4774 * It is the responsibility of the caller to verify the session is
4748 * expired before calling this routine. 4775 * expired before calling this routine.
4749 */ 4776 */
4750int nfs4_proc_create_session(struct nfs_client *clp, int reset) 4777int nfs4_proc_create_session(struct nfs_client *clp)
4751{ 4778{
4752 int status; 4779 int status;
4753 unsigned *ptr; 4780 unsigned *ptr;
4754 struct nfs_fsinfo fsinfo;
4755 struct nfs4_session *session = clp->cl_session; 4781 struct nfs4_session *session = clp->cl_session;
4756 4782
4757 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); 4783 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
@@ -4760,35 +4786,19 @@ int nfs4_proc_create_session(struct nfs_client *clp, int reset)
4760 if (status) 4786 if (status)
4761 goto out; 4787 goto out;
4762 4788
4763 /* Init or reset the fore channel */ 4789 /* Init and reset the fore channel */
4764 if (reset) 4790 status = nfs4_init_slot_tables(session);
4765 status = nfs4_reset_slot_tables(session); 4791 dprintk("slot table initialization returned %d\n", status);
4766 else 4792 if (status)
4767 status = nfs4_init_slot_tables(session); 4793 goto out;
4768 dprintk("fore channel slot table initialization returned %d\n", status); 4794 status = nfs4_reset_slot_tables(session);
4795 dprintk("slot table reset returned %d\n", status);
4769 if (status) 4796 if (status)
4770 goto out; 4797 goto out;
4771 4798
4772 ptr = (unsigned *)&session->sess_id.data[0]; 4799 ptr = (unsigned *)&session->sess_id.data[0];
4773 dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__, 4800 dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__,
4774 clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]); 4801 clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]);
4775
4776 if (reset)
4777 /* Lease time is aleady set */
4778 goto out;
4779
4780 /* Get the lease time */
4781 status = nfs4_proc_get_lease_time(clp, &fsinfo);
4782 if (status == 0) {
4783 /* Update lease time and schedule renewal */
4784 spin_lock(&clp->cl_lock);
4785 clp->cl_lease_time = fsinfo.lease_time * HZ;
4786 clp->cl_last_renewal = jiffies;
4787 clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
4788 spin_unlock(&clp->cl_lock);
4789
4790 nfs4_schedule_state_renewal(clp);
4791 }
4792out: 4802out:
4793 dprintk("<-- %s\n", __func__); 4803 dprintk("<-- %s\n", __func__);
4794 return status; 4804 return status;
@@ -4827,13 +4837,16 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
4827int nfs4_init_session(struct nfs_server *server) 4837int nfs4_init_session(struct nfs_server *server)
4828{ 4838{
4829 struct nfs_client *clp = server->nfs_client; 4839 struct nfs_client *clp = server->nfs_client;
4840 struct nfs4_session *session;
4830 int ret; 4841 int ret;
4831 4842
4832 if (!nfs4_has_session(clp)) 4843 if (!nfs4_has_session(clp))
4833 return 0; 4844 return 0;
4834 4845
4835 clp->cl_session->fc_attrs.max_rqst_sz = server->wsize; 4846 session = clp->cl_session;
4836 clp->cl_session->fc_attrs.max_resp_sz = server->rsize; 4847 session->fc_attrs.max_rqst_sz = server->wsize + nfs41_maxwrite_overhead;
4848 session->fc_attrs.max_resp_sz = server->rsize + nfs41_maxread_overhead;
4849
4837 ret = nfs4_recover_expired_lease(server); 4850 ret = nfs4_recover_expired_lease(server);
4838 if (!ret) 4851 if (!ret)
4839 ret = nfs4_check_client_ready(clp); 4852 ret = nfs4_check_client_ready(clp);
@@ -4872,11 +4885,10 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
4872 4885
4873 if (_nfs4_async_handle_error(task, NULL, clp, NULL) 4886 if (_nfs4_async_handle_error(task, NULL, clp, NULL)
4874 == -EAGAIN) { 4887 == -EAGAIN) {
4875 nfs4_restart_rpc(task, clp); 4888 nfs_restart_rpc(task, clp);
4876 return; 4889 return;
4877 } 4890 }
4878 } 4891 }
4879 nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp);
4880 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); 4892 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
4881 4893
4882 kfree(task->tk_msg.rpc_argp); 4894 kfree(task->tk_msg.rpc_argp);
@@ -4931,6 +4943,109 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
4931 &nfs41_sequence_ops, (void *)clp); 4943 &nfs41_sequence_ops, (void *)clp);
4932} 4944}
4933 4945
4946struct nfs4_reclaim_complete_data {
4947 struct nfs_client *clp;
4948 struct nfs41_reclaim_complete_args arg;
4949 struct nfs41_reclaim_complete_res res;
4950};
4951
4952static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
4953{
4954 struct nfs4_reclaim_complete_data *calldata = data;
4955
4956 if (nfs4_setup_sequence(calldata->clp, &calldata->arg.seq_args,
4957 &calldata->res.seq_res, 0, task))
4958 return;
4959
4960 rpc_call_start(task);
4961}
4962
4963static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
4964{
4965 struct nfs4_reclaim_complete_data *calldata = data;
4966 struct nfs_client *clp = calldata->clp;
4967 struct nfs4_sequence_res *res = &calldata->res.seq_res;
4968
4969 dprintk("--> %s\n", __func__);
4970 nfs41_sequence_done(clp, res, task->tk_status);
4971 switch (task->tk_status) {
4972 case 0:
4973 case -NFS4ERR_COMPLETE_ALREADY:
4974 break;
4975 case -NFS4ERR_BADSESSION:
4976 case -NFS4ERR_DEADSESSION:
4977 /*
4978 * Handle the session error, but do not retry the operation, as
4979 * we have no way of telling whether the clientid had to be
4980 * reset before we got our reply. If reset, a new wave of
4981 * reclaim operations will follow, containing their own reclaim
4982 * complete. We don't want our retry to get on the way of
4983 * recovery by incorrectly indicating to the server that we're
4984 * done reclaiming state since the process had to be restarted.
4985 */
4986 _nfs4_async_handle_error(task, NULL, clp, NULL);
4987 break;
4988 default:
4989 if (_nfs4_async_handle_error(
4990 task, NULL, clp, NULL) == -EAGAIN) {
4991 rpc_restart_call_prepare(task);
4992 return;
4993 }
4994 }
4995
4996 dprintk("<-- %s\n", __func__);
4997}
4998
4999static void nfs4_free_reclaim_complete_data(void *data)
5000{
5001 struct nfs4_reclaim_complete_data *calldata = data;
5002
5003 kfree(calldata);
5004}
5005
5006static const struct rpc_call_ops nfs4_reclaim_complete_call_ops = {
5007 .rpc_call_prepare = nfs4_reclaim_complete_prepare,
5008 .rpc_call_done = nfs4_reclaim_complete_done,
5009 .rpc_release = nfs4_free_reclaim_complete_data,
5010};
5011
5012/*
5013 * Issue a global reclaim complete.
5014 */
5015static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
5016{
5017 struct nfs4_reclaim_complete_data *calldata;
5018 struct rpc_task *task;
5019 struct rpc_message msg = {
5020 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RECLAIM_COMPLETE],
5021 };
5022 struct rpc_task_setup task_setup_data = {
5023 .rpc_client = clp->cl_rpcclient,
5024 .rpc_message = &msg,
5025 .callback_ops = &nfs4_reclaim_complete_call_ops,
5026 .flags = RPC_TASK_ASYNC,
5027 };
5028 int status = -ENOMEM;
5029
5030 dprintk("--> %s\n", __func__);
5031 calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
5032 if (calldata == NULL)
5033 goto out;
5034 calldata->clp = clp;
5035 calldata->arg.one_fs = 0;
5036 calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
5037
5038 msg.rpc_argp = &calldata->arg;
5039 msg.rpc_resp = &calldata->res;
5040 task_setup_data.callback_data = calldata;
5041 task = rpc_run_task(&task_setup_data);
5042 if (IS_ERR(task))
5043 status = PTR_ERR(task);
5044 rpc_put_task(task);
5045out:
5046 dprintk("<-- %s status=%d\n", __func__, status);
5047 return status;
5048}
4934#endif /* CONFIG_NFS_V4_1 */ 5049#endif /* CONFIG_NFS_V4_1 */
4935 5050
4936struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = { 5051struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
@@ -4948,8 +5063,9 @@ struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
4948 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, 5063 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
4949 .recover_open = nfs4_open_reclaim, 5064 .recover_open = nfs4_open_reclaim,
4950 .recover_lock = nfs4_lock_reclaim, 5065 .recover_lock = nfs4_lock_reclaim,
4951 .establish_clid = nfs4_proc_exchange_id, 5066 .establish_clid = nfs41_init_clientid,
4952 .get_clid_cred = nfs4_get_exchange_id_cred, 5067 .get_clid_cred = nfs4_get_exchange_id_cred,
5068 .reclaim_complete = nfs41_proc_reclaim_complete,
4953}; 5069};
4954#endif /* CONFIG_NFS_V4_1 */ 5070#endif /* CONFIG_NFS_V4_1 */
4955 5071
@@ -4968,7 +5084,7 @@ struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
4968 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, 5084 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
4969 .recover_open = nfs4_open_expired, 5085 .recover_open = nfs4_open_expired,
4970 .recover_lock = nfs4_lock_expired, 5086 .recover_lock = nfs4_lock_expired,
4971 .establish_clid = nfs4_proc_exchange_id, 5087 .establish_clid = nfs41_init_clientid,
4972 .get_clid_cred = nfs4_get_exchange_id_cred, 5088 .get_clid_cred = nfs4_get_exchange_id_cred,
4973}; 5089};
4974#endif /* CONFIG_NFS_V4_1 */ 5090#endif /* CONFIG_NFS_V4_1 */