@@ -96,6 +96,10 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
96
96
struct nfs_open_context * ctx , struct nfs4_label * ilabel ,
97
97
struct nfs4_label * olabel );
98
98
#ifdef CONFIG_NFS_V4_1
99
+ static struct rpc_task * _nfs41_proc_sequence (struct nfs_client * clp ,
100
+ struct rpc_cred * cred ,
101
+ struct nfs4_slot * slot ,
102
+ bool is_privileged );
99
103
static int nfs41_test_stateid (struct nfs_server * , nfs4_stateid * ,
100
104
struct rpc_cred * );
101
105
static int nfs41_free_stateid (struct nfs_server * , const nfs4_stateid * ,
@@ -644,13 +648,14 @@ static int nfs40_sequence_done(struct rpc_task *task,
644
648
645
649
#if defined(CONFIG_NFS_V4_1 )
646
650
647
- static void nfs41_sequence_free_slot (struct nfs4_sequence_res * res )
651
+ static void nfs41_release_slot (struct nfs4_slot * slot )
648
652
{
649
653
struct nfs4_session * session ;
650
654
struct nfs4_slot_table * tbl ;
651
- struct nfs4_slot * slot = res -> sr_slot ;
652
655
bool send_new_highest_used_slotid = false;
653
656
657
+ if (!slot )
658
+ return ;
654
659
tbl = slot -> table ;
655
660
session = tbl -> session ;
656
661
@@ -676,13 +681,18 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
676
681
send_new_highest_used_slotid = false;
677
682
out_unlock :
678
683
spin_unlock (& tbl -> slot_tbl_lock );
679
- res -> sr_slot = NULL ;
680
684
if (send_new_highest_used_slotid )
681
685
nfs41_notify_server (session -> clp );
682
686
if (waitqueue_active (& tbl -> slot_waitq ))
683
687
wake_up_all (& tbl -> slot_waitq );
684
688
}
685
689
690
+ static void nfs41_sequence_free_slot (struct nfs4_sequence_res * res )
691
+ {
692
+ nfs41_release_slot (res -> sr_slot );
693
+ res -> sr_slot = NULL ;
694
+ }
695
+
686
696
static int nfs41_sequence_process (struct rpc_task * task ,
687
697
struct nfs4_sequence_res * res )
688
698
{
@@ -710,13 +720,6 @@ static int nfs41_sequence_process(struct rpc_task *task,
710
720
/* Check the SEQUENCE operation status */
711
721
switch (res -> sr_status ) {
712
722
case 0 :
713
- /* If previous op on slot was interrupted and we reused
714
- * the seq# and got a reply from the cache, then retry
715
- */
716
- if (task -> tk_status == - EREMOTEIO && interrupted ) {
717
- ++ slot -> seq_nr ;
718
- goto retry_nowait ;
719
- }
720
723
/* Update the slot's sequence and clientid lease timer */
721
724
slot -> seq_done = 1 ;
722
725
clp = session -> clp ;
@@ -750,16 +753,16 @@ static int nfs41_sequence_process(struct rpc_task *task,
750
753
* The slot id we used was probably retired. Try again
751
754
* using a different slot id.
752
755
*/
756
+ if (slot -> seq_nr < slot -> table -> target_highest_slotid )
757
+ goto session_recover ;
753
758
goto retry_nowait ;
754
759
case - NFS4ERR_SEQ_MISORDERED :
755
760
/*
756
761
* Was the last operation on this sequence interrupted?
757
762
* If so, retry after bumping the sequence number.
758
763
*/
759
- if (interrupted ) {
760
- ++ slot -> seq_nr ;
761
- goto retry_nowait ;
762
- }
764
+ if (interrupted )
765
+ goto retry_new_seq ;
763
766
/*
764
767
* Could this slot have been previously retired?
765
768
* If so, then the server may be expecting seq_nr = 1!
@@ -768,10 +771,11 @@ static int nfs41_sequence_process(struct rpc_task *task,
768
771
slot -> seq_nr = 1 ;
769
772
goto retry_nowait ;
770
773
}
771
- break ;
774
+ goto session_recover ;
772
775
case - NFS4ERR_SEQ_FALSE_RETRY :
773
- ++ slot -> seq_nr ;
774
- goto retry_nowait ;
776
+ if (interrupted )
777
+ goto retry_new_seq ;
778
+ goto session_recover ;
775
779
default :
776
780
/* Just update the slot sequence no. */
777
781
slot -> seq_done = 1 ;
@@ -781,6 +785,11 @@ static int nfs41_sequence_process(struct rpc_task *task,
781
785
dprintk ("%s: Error %d free the slot \n" , __func__ , res -> sr_status );
782
786
out_noaction :
783
787
return ret ;
788
+ session_recover :
789
+ nfs4_schedule_session_recovery (session , res -> sr_status );
790
+ goto retry_nowait ;
791
+ retry_new_seq :
792
+ ++ slot -> seq_nr ;
784
793
retry_nowait :
785
794
if (rpc_restart_call_prepare (task )) {
786
795
nfs41_sequence_free_slot (res );
@@ -857,6 +866,17 @@ static const struct rpc_call_ops nfs41_call_sync_ops = {
857
866
.rpc_call_done = nfs41_call_sync_done ,
858
867
};
859
868
869
+ static void
870
+ nfs4_sequence_process_interrupted (struct nfs_client * client ,
871
+ struct nfs4_slot * slot , struct rpc_cred * cred )
872
+ {
873
+ struct rpc_task * task ;
874
+
875
+ task = _nfs41_proc_sequence (client , cred , slot , true);
876
+ if (!IS_ERR (task ))
877
+ rpc_put_task_async (task );
878
+ }
879
+
860
880
#else /* !CONFIG_NFS_V4_1 */
861
881
862
882
static int nfs4_sequence_process (struct rpc_task * task , struct nfs4_sequence_res * res )
@@ -877,9 +897,34 @@ int nfs4_sequence_done(struct rpc_task *task,
877
897
}
878
898
EXPORT_SYMBOL_GPL (nfs4_sequence_done );
879
899
900
+ static void
901
+ nfs4_sequence_process_interrupted (struct nfs_client * client ,
902
+ struct nfs4_slot * slot , struct rpc_cred * cred )
903
+ {
904
+ WARN_ON_ONCE (1 );
905
+ slot -> interrupted = 0 ;
906
+ }
907
+
880
908
#endif /* !CONFIG_NFS_V4_1 */
881
909
882
- int nfs4_setup_sequence (const struct nfs_client * client ,
910
+ static
911
+ void nfs4_sequence_attach_slot (struct nfs4_sequence_args * args ,
912
+ struct nfs4_sequence_res * res ,
913
+ struct nfs4_slot * slot )
914
+ {
915
+ if (!slot )
916
+ return ;
917
+ slot -> privileged = args -> sa_privileged ? 1 : 0 ;
918
+ args -> sa_slot = slot ;
919
+
920
+ res -> sr_slot = slot ;
921
+ res -> sr_timestamp = jiffies ;
922
+ res -> sr_status_flags = 0 ;
923
+ res -> sr_status = 1 ;
924
+
925
+ }
926
+
927
+ int nfs4_setup_sequence (struct nfs_client * client ,
883
928
struct nfs4_sequence_args * args ,
884
929
struct nfs4_sequence_res * res ,
885
930
struct rpc_task * task )
@@ -897,29 +942,28 @@ int nfs4_setup_sequence(const struct nfs_client *client,
897
942
task -> tk_timeout = 0 ;
898
943
}
899
944
900
- spin_lock (& tbl -> slot_tbl_lock );
901
- /* The state manager will wait until the slot table is empty */
902
- if (nfs4_slot_tbl_draining (tbl ) && !args -> sa_privileged )
903
- goto out_sleep ;
945
+ for (;;) {
946
+ spin_lock (& tbl -> slot_tbl_lock );
947
+ /* The state manager will wait until the slot table is empty */
948
+ if (nfs4_slot_tbl_draining (tbl ) && !args -> sa_privileged )
949
+ goto out_sleep ;
950
+
951
+ slot = nfs4_alloc_slot (tbl );
952
+ if (IS_ERR (slot )) {
953
+ /* Try again in 1/4 second */
954
+ if (slot == ERR_PTR (- ENOMEM ))
955
+ task -> tk_timeout = HZ >> 2 ;
956
+ goto out_sleep ;
957
+ }
958
+ spin_unlock (& tbl -> slot_tbl_lock );
904
959
905
- slot = nfs4_alloc_slot (tbl );
906
- if (IS_ERR (slot )) {
907
- /* Try again in 1/4 second */
908
- if (slot == ERR_PTR (- ENOMEM ))
909
- task -> tk_timeout = HZ >> 2 ;
910
- goto out_sleep ;
960
+ if (likely (!slot -> interrupted ))
961
+ break ;
962
+ nfs4_sequence_process_interrupted (client ,
963
+ slot , task -> tk_msg .rpc_cred );
911
964
}
912
- spin_unlock (& tbl -> slot_tbl_lock );
913
-
914
- slot -> privileged = args -> sa_privileged ? 1 : 0 ;
915
- args -> sa_slot = slot ;
916
965
917
- res -> sr_slot = slot ;
918
- if (session ) {
919
- res -> sr_timestamp = jiffies ;
920
- res -> sr_status_flags = 0 ;
921
- res -> sr_status = 1 ;
922
- }
966
+ nfs4_sequence_attach_slot (args , res , slot );
923
967
924
968
trace_nfs4_setup_sequence (session , args );
925
969
out_start :
@@ -8118,6 +8162,7 @@ static const struct rpc_call_ops nfs41_sequence_ops = {
8118
8162
8119
8163
static struct rpc_task * _nfs41_proc_sequence (struct nfs_client * clp ,
8120
8164
struct rpc_cred * cred ,
8165
+ struct nfs4_slot * slot ,
8121
8166
bool is_privileged )
8122
8167
{
8123
8168
struct nfs4_sequence_data * calldata ;
@@ -8131,23 +8176,34 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
8131
8176
.callback_ops = & nfs41_sequence_ops ,
8132
8177
.flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT ,
8133
8178
};
8179
+ struct rpc_task * ret ;
8134
8180
8181
+ ret = ERR_PTR (- EIO );
8135
8182
if (!atomic_inc_not_zero (& clp -> cl_count ))
8136
- return ERR_PTR (- EIO );
8183
+ goto out_err ;
8184
+
8185
+ ret = ERR_PTR (- ENOMEM );
8137
8186
calldata = kzalloc (sizeof (* calldata ), GFP_NOFS );
8138
- if (calldata == NULL ) {
8139
- nfs_put_client (clp );
8140
- return ERR_PTR (- ENOMEM );
8141
- }
8187
+ if (calldata == NULL )
8188
+ goto out_put_clp ;
8142
8189
nfs4_init_sequence (& calldata -> args , & calldata -> res , 0 );
8190
+ nfs4_sequence_attach_slot (& calldata -> args , & calldata -> res , slot );
8143
8191
if (is_privileged )
8144
8192
nfs4_set_sequence_privileged (& calldata -> args );
8145
8193
msg .rpc_argp = & calldata -> args ;
8146
8194
msg .rpc_resp = & calldata -> res ;
8147
8195
calldata -> clp = clp ;
8148
8196
task_setup_data .callback_data = calldata ;
8149
8197
8150
- return rpc_run_task (& task_setup_data );
8198
+ ret = rpc_run_task (& task_setup_data );
8199
+ if (IS_ERR (ret ))
8200
+ goto out_err ;
8201
+ return ret ;
8202
+ out_put_clp :
8203
+ nfs_put_client (clp );
8204
+ out_err :
8205
+ nfs41_release_slot (slot );
8206
+ return ret ;
8151
8207
}
8152
8208
8153
8209
static int nfs41_proc_async_sequence (struct nfs_client * clp , struct rpc_cred * cred , unsigned renew_flags )
@@ -8157,7 +8213,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr
8157
8213
8158
8214
if ((renew_flags & NFS4_RENEW_TIMEOUT ) == 0 )
8159
8215
return - EAGAIN ;
8160
- task = _nfs41_proc_sequence (clp , cred , false);
8216
+ task = _nfs41_proc_sequence (clp , cred , NULL , false);
8161
8217
if (IS_ERR (task ))
8162
8218
ret = PTR_ERR (task );
8163
8219
else
@@ -8171,7 +8227,7 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
8171
8227
struct rpc_task * task ;
8172
8228
int ret ;
8173
8229
8174
- task = _nfs41_proc_sequence (clp , cred , true);
8230
+ task = _nfs41_proc_sequence (clp , cred , NULL , true);
8175
8231
if (IS_ERR (task )) {
8176
8232
ret = PTR_ERR (task );
8177
8233
goto out ;
0 commit comments