summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c89
1 files changed, 74 insertions, 15 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1949bbd806eb..f5aecaabcb7c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -634,15 +634,11 @@ out_sleep:
634} 634}
635EXPORT_SYMBOL_GPL(nfs40_setup_sequence); 635EXPORT_SYMBOL_GPL(nfs40_setup_sequence);
636 636
637static int nfs40_sequence_done(struct rpc_task *task, 637static void nfs40_sequence_free_slot(struct nfs4_sequence_res *res)
638 struct nfs4_sequence_res *res)
639{ 638{
640 struct nfs4_slot *slot = res->sr_slot; 639 struct nfs4_slot *slot = res->sr_slot;
641 struct nfs4_slot_table *tbl; 640 struct nfs4_slot_table *tbl;
642 641
643 if (slot == NULL)
644 goto out;
645
646 tbl = slot->table; 642 tbl = slot->table;
647 spin_lock(&tbl->slot_tbl_lock); 643 spin_lock(&tbl->slot_tbl_lock);
648 if (!nfs41_wake_and_assign_slot(tbl, slot)) 644 if (!nfs41_wake_and_assign_slot(tbl, slot))
@@ -650,7 +646,13 @@ static int nfs40_sequence_done(struct rpc_task *task,
650 spin_unlock(&tbl->slot_tbl_lock); 646 spin_unlock(&tbl->slot_tbl_lock);
651 647
652 res->sr_slot = NULL; 648 res->sr_slot = NULL;
653out: 649}
650
651static int nfs40_sequence_done(struct rpc_task *task,
652 struct nfs4_sequence_res *res)
653{
654 if (res->sr_slot != NULL)
655 nfs40_sequence_free_slot(res);
654 return 1; 656 return 1;
655} 657}
656 658
@@ -666,6 +668,11 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
666 tbl = slot->table; 668 tbl = slot->table;
667 session = tbl->session; 669 session = tbl->session;
668 670
671 /* Bump the slot sequence number */
672 if (slot->seq_done)
673 slot->seq_nr++;
674 slot->seq_done = 0;
675
669 spin_lock(&tbl->slot_tbl_lock); 676 spin_lock(&tbl->slot_tbl_lock);
670 /* Be nice to the server: try to ensure that the last transmitted 677 /* Be nice to the server: try to ensure that the last transmitted
671 * value for highest_user_slotid <= target_highest_slotid 678 * value for highest_user_slotid <= target_highest_slotid
@@ -686,9 +693,12 @@ out_unlock:
686 res->sr_slot = NULL; 693 res->sr_slot = NULL;
687 if (send_new_highest_used_slotid) 694 if (send_new_highest_used_slotid)
688 nfs41_notify_server(session->clp); 695 nfs41_notify_server(session->clp);
696 if (waitqueue_active(&tbl->slot_waitq))
697 wake_up_all(&tbl->slot_waitq);
689} 698}
690 699
691int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) 700static int nfs41_sequence_process(struct rpc_task *task,
701 struct nfs4_sequence_res *res)
692{ 702{
693 struct nfs4_session *session; 703 struct nfs4_session *session;
694 struct nfs4_slot *slot = res->sr_slot; 704 struct nfs4_slot *slot = res->sr_slot;
@@ -714,7 +724,7 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
714 switch (res->sr_status) { 724 switch (res->sr_status) {
715 case 0: 725 case 0:
716 /* Update the slot's sequence and clientid lease timer */ 726 /* Update the slot's sequence and clientid lease timer */
717 ++slot->seq_nr; 727 slot->seq_done = 1;
718 clp = session->clp; 728 clp = session->clp;
719 do_renew_lease(clp, res->sr_timestamp); 729 do_renew_lease(clp, res->sr_timestamp);
720 /* Check sequence flags */ 730 /* Check sequence flags */
@@ -769,16 +779,16 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
769 goto retry_nowait; 779 goto retry_nowait;
770 default: 780 default:
771 /* Just update the slot sequence no. */ 781 /* Just update the slot sequence no. */
772 ++slot->seq_nr; 782 slot->seq_done = 1;
773 } 783 }
774out: 784out:
775 /* The session may be reset by one of the error handlers. */ 785 /* The session may be reset by one of the error handlers. */
776 dprintk("%s: Error %d free the slot \n", __func__, res->sr_status); 786 dprintk("%s: Error %d free the slot \n", __func__, res->sr_status);
777 nfs41_sequence_free_slot(res);
778out_noaction: 787out_noaction:
779 return ret; 788 return ret;
780retry_nowait: 789retry_nowait:
781 if (rpc_restart_call_prepare(task)) { 790 if (rpc_restart_call_prepare(task)) {
791 nfs41_sequence_free_slot(res);
782 task->tk_status = 0; 792 task->tk_status = 0;
783 ret = 0; 793 ret = 0;
784 } 794 }
@@ -789,8 +799,37 @@ out_retry:
789 rpc_delay(task, NFS4_POLL_RETRY_MAX); 799 rpc_delay(task, NFS4_POLL_RETRY_MAX);
790 return 0; 800 return 0;
791} 801}
802
803int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
804{
805 if (!nfs41_sequence_process(task, res))
806 return 0;
807 if (res->sr_slot != NULL)
808 nfs41_sequence_free_slot(res);
809 return 1;
810
811}
792EXPORT_SYMBOL_GPL(nfs41_sequence_done); 812EXPORT_SYMBOL_GPL(nfs41_sequence_done);
793 813
814static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res)
815{
816 if (res->sr_slot == NULL)
817 return 1;
818 if (res->sr_slot->table->session != NULL)
819 return nfs41_sequence_process(task, res);
820 return nfs40_sequence_done(task, res);
821}
822
823static void nfs4_sequence_free_slot(struct nfs4_sequence_res *res)
824{
825 if (res->sr_slot != NULL) {
826 if (res->sr_slot->table->session != NULL)
827 nfs41_sequence_free_slot(res);
828 else
829 nfs40_sequence_free_slot(res);
830 }
831}
832
794int nfs4_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) 833int nfs4_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
795{ 834{
796 if (res->sr_slot == NULL) 835 if (res->sr_slot == NULL)
@@ -920,6 +959,17 @@ static int nfs4_setup_sequence(const struct nfs_server *server,
920 args, res, task); 959 args, res, task);
921} 960}
922 961
962static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res)
963{
964 return nfs40_sequence_done(task, res);
965}
966
967static void nfs4_sequence_free_slot(struct nfs4_sequence_res *res)
968{
969 if (res->sr_slot != NULL)
970 nfs40_sequence_free_slot(res);
971}
972
923int nfs4_sequence_done(struct rpc_task *task, 973int nfs4_sequence_done(struct rpc_task *task,
924 struct nfs4_sequence_res *res) 974 struct nfs4_sequence_res *res)
925{ 975{
@@ -1197,6 +1247,7 @@ static void nfs4_opendata_free(struct kref *kref)
1197 struct super_block *sb = p->dentry->d_sb; 1247 struct super_block *sb = p->dentry->d_sb;
1198 1248
1199 nfs_free_seqid(p->o_arg.seqid); 1249 nfs_free_seqid(p->o_arg.seqid);
1250 nfs4_sequence_free_slot(&p->o_res.seq_res);
1200 if (p->state != NULL) 1251 if (p->state != NULL)
1201 nfs4_put_open_state(p->state); 1252 nfs4_put_open_state(p->state);
1202 nfs4_put_state_owner(p->owner); 1253 nfs4_put_state_owner(p->owner);
@@ -1656,9 +1707,14 @@ err:
1656static struct nfs4_state * 1707static struct nfs4_state *
1657nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data) 1708nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
1658{ 1709{
1710 struct nfs4_state *ret;
1711
1659 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) 1712 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS)
1660 return _nfs4_opendata_reclaim_to_nfs4_state(data); 1713 ret =_nfs4_opendata_reclaim_to_nfs4_state(data);
1661 return _nfs4_opendata_to_nfs4_state(data); 1714 else
1715 ret = _nfs4_opendata_to_nfs4_state(data);
1716 nfs4_sequence_free_slot(&data->o_res.seq_res);
1717 return ret;
1662} 1718}
1663 1719
1664static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state) 1720static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state)
@@ -2056,7 +2112,7 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
2056 2112
2057 data->rpc_status = task->tk_status; 2113 data->rpc_status = task->tk_status;
2058 2114
2059 if (!nfs4_sequence_done(task, &data->o_res.seq_res)) 2115 if (!nfs4_sequence_process(task, &data->o_res.seq_res))
2060 return; 2116 return;
2061 2117
2062 if (task->tk_status == 0) { 2118 if (task->tk_status == 0) {
@@ -7864,7 +7920,7 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
7864 struct nfs4_layoutget *lgp = calldata; 7920 struct nfs4_layoutget *lgp = calldata;
7865 7921
7866 dprintk("--> %s\n", __func__); 7922 dprintk("--> %s\n", __func__);
7867 nfs41_sequence_done(task, &lgp->res.seq_res); 7923 nfs41_sequence_process(task, &lgp->res.seq_res);
7868 dprintk("<-- %s\n", __func__); 7924 dprintk("<-- %s\n", __func__);
7869} 7925}
7870 7926
@@ -8080,6 +8136,7 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout, gfp_t gfp_flags)
8080 /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */ 8136 /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */
8081 if (status == 0 && lgp->res.layoutp->len) 8137 if (status == 0 && lgp->res.layoutp->len)
8082 lseg = pnfs_layout_process(lgp); 8138 lseg = pnfs_layout_process(lgp);
8139 nfs4_sequence_free_slot(&lgp->res.seq_res);
8083 rpc_put_task(task); 8140 rpc_put_task(task);
8084 dprintk("<-- %s status=%d\n", __func__, status); 8141 dprintk("<-- %s status=%d\n", __func__, status);
8085 if (status) 8142 if (status)
@@ -8106,7 +8163,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
8106 8163
8107 dprintk("--> %s\n", __func__); 8164 dprintk("--> %s\n", __func__);
8108 8165
8109 if (!nfs41_sequence_done(task, &lrp->res.seq_res)) 8166 if (!nfs41_sequence_process(task, &lrp->res.seq_res))
8110 return; 8167 return;
8111 8168
8112 server = NFS_SERVER(lrp->args.inode); 8169 server = NFS_SERVER(lrp->args.inode);
@@ -8118,6 +8175,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
8118 case -NFS4ERR_DELAY: 8175 case -NFS4ERR_DELAY:
8119 if (nfs4_async_handle_error(task, server, NULL, NULL) != -EAGAIN) 8176 if (nfs4_async_handle_error(task, server, NULL, NULL) != -EAGAIN)
8120 break; 8177 break;
8178 nfs4_sequence_free_slot(&lrp->res.seq_res);
8121 rpc_restart_call_prepare(task); 8179 rpc_restart_call_prepare(task);
8122 return; 8180 return;
8123 } 8181 }
@@ -8138,6 +8196,7 @@ static void nfs4_layoutreturn_release(void *calldata)
8138 pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); 8196 pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
8139 pnfs_clear_layoutreturn_waitbit(lo); 8197 pnfs_clear_layoutreturn_waitbit(lo);
8140 spin_unlock(&lo->plh_inode->i_lock); 8198 spin_unlock(&lo->plh_inode->i_lock);
8199 nfs4_sequence_free_slot(&lrp->res.seq_res);
8141 pnfs_free_lseg_list(&freeme); 8200 pnfs_free_lseg_list(&freeme);
8142 pnfs_put_layout_hdr(lrp->args.layout); 8201 pnfs_put_layout_hdr(lrp->args.layout);
8143 nfs_iput_and_deactive(lrp->inode); 8202 nfs_iput_and_deactive(lrp->inode);