@@ -4971,6 +4971,110 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
4971
4971
& nfs41_sequence_ops , (void * )clp );
4972
4972
}
4973
4973
4974
+ struct nfs4_reclaim_complete_data {
4975
+ struct nfs_client * clp ;
4976
+ struct nfs41_reclaim_complete_args arg ;
4977
+ struct nfs41_reclaim_complete_res res ;
4978
+ };
4979
+
4980
+ static void nfs4_reclaim_complete_prepare (struct rpc_task * task , void * data )
4981
+ {
4982
+ struct nfs4_reclaim_complete_data * calldata = data ;
4983
+
4984
+ if (nfs4_setup_sequence (calldata -> clp , & calldata -> arg .seq_args ,
4985
+ & calldata -> res .seq_res , 0 , task ))
4986
+ return ;
4987
+
4988
+ rpc_call_start (task );
4989
+ }
4990
+
4991
+ static void nfs4_reclaim_complete_done (struct rpc_task * task , void * data )
4992
+ {
4993
+ struct nfs4_reclaim_complete_data * calldata = data ;
4994
+ struct nfs_client * clp = calldata -> clp ;
4995
+ struct nfs4_sequence_res * res = & calldata -> res .seq_res ;
4996
+
4997
+ dprintk ("--> %s\n" , __func__ );
4998
+ nfs41_sequence_done (clp , res , task -> tk_status );
4999
+ switch (task -> tk_status ) {
5000
+ case 0 :
5001
+ case - NFS4ERR_COMPLETE_ALREADY :
5002
+ break ;
5003
+ case - NFS4ERR_BADSESSION :
5004
+ case - NFS4ERR_DEADSESSION :
5005
+ /*
5006
+ * Handle the session error, but do not retry the operation, as
5007
+ * we have no way of telling whether the clientid had to be
5008
+ * reset before we got our reply. If reset, a new wave of
5009
+ * reclaim operations will follow, containing their own reclaim
5010
+ * complete. We don't want our retry to get on the way of
5011
+ * recovery by incorrectly indicating to the server that we're
5012
+ * done reclaiming state since the process had to be restarted.
5013
+ */
5014
+ _nfs4_async_handle_error (task , NULL , clp , NULL );
5015
+ break ;
5016
+ default :
5017
+ if (_nfs4_async_handle_error (
5018
+ task , NULL , clp , NULL ) == - EAGAIN ) {
5019
+ rpc_restart_call_prepare (task );
5020
+ return ;
5021
+ }
5022
+ }
5023
+ nfs41_sequence_free_slot (clp , res );
5024
+
5025
+ dprintk ("<-- %s\n" , __func__ );
5026
+ }
5027
+
5028
+ static void nfs4_free_reclaim_complete_data (void * data )
5029
+ {
5030
+ struct nfs4_reclaim_complete_data * calldata = data ;
5031
+
5032
+ kfree (calldata );
5033
+ }
5034
+
5035
+ static const struct rpc_call_ops nfs4_reclaim_complete_call_ops = {
5036
+ .rpc_call_prepare = nfs4_reclaim_complete_prepare ,
5037
+ .rpc_call_done = nfs4_reclaim_complete_done ,
5038
+ .rpc_release = nfs4_free_reclaim_complete_data ,
5039
+ };
5040
+
5041
+ /*
5042
+ * Issue a global reclaim complete.
5043
+ */
5044
+ static int nfs41_proc_reclaim_complete (struct nfs_client * clp )
5045
+ {
5046
+ struct nfs4_reclaim_complete_data * calldata ;
5047
+ struct rpc_task * task ;
5048
+ struct rpc_message msg = {
5049
+ .rpc_proc = & nfs4_procedures [NFSPROC4_CLNT_RECLAIM_COMPLETE ],
5050
+ };
5051
+ struct rpc_task_setup task_setup_data = {
5052
+ .rpc_client = clp -> cl_rpcclient ,
5053
+ .rpc_message = & msg ,
5054
+ .callback_ops = & nfs4_reclaim_complete_call_ops ,
5055
+ .flags = RPC_TASK_ASYNC ,
5056
+ };
5057
+ int status = - ENOMEM ;
5058
+
5059
+ dprintk ("--> %s\n" , __func__ );
5060
+ calldata = kzalloc (sizeof (* calldata ), GFP_KERNEL );
5061
+ if (calldata == NULL )
5062
+ goto out ;
5063
+ calldata -> clp = clp ;
5064
+ calldata -> arg .one_fs = 0 ;
5065
+ calldata -> res .seq_res .sr_slotid = NFS4_MAX_SLOT_TABLE ;
5066
+
5067
+ msg .rpc_argp = & calldata -> arg ;
5068
+ msg .rpc_resp = & calldata -> res ;
5069
+ task_setup_data .callback_data = calldata ;
5070
+ task = rpc_run_task (& task_setup_data );
5071
+ if (IS_ERR (task ))
5072
+ status = PTR_ERR (task );
5073
+ rpc_put_task (task );
5074
+ out :
5075
+ dprintk ("<-- %s status=%d\n" , __func__ , status );
5076
+ return status ;
5077
+ }
4974
5078
#endif /* CONFIG_NFS_V4_1 */
4975
5079
4976
5080
struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
@@ -4990,6 +5094,7 @@ struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
4990
5094
.recover_lock = nfs4_lock_reclaim ,
4991
5095
.establish_clid = nfs41_init_clientid ,
4992
5096
.get_clid_cred = nfs4_get_exchange_id_cred ,
5097
+ .reclaim_complete = nfs41_proc_reclaim_complete ,
4993
5098
};
4994
5099
#endif /* CONFIG_NFS_V4_1 */
4995
5100
0 commit comments