xref: /haiku/src/add-ons/kernel/file_systems/nfs4/Request.cpp (revision e4cd963ff11902f6b5351314614530a7e3b40272)
101d6381dSPawel Dziepak /*
201d6381dSPawel Dziepak  * Copyright 2012 Haiku, Inc. All rights reserved.
301d6381dSPawel Dziepak  * Distributed under the terms of the MIT License.
401d6381dSPawel Dziepak  *
501d6381dSPawel Dziepak  * Authors:
601d6381dSPawel Dziepak  *		Paweł Dziepak, pdziepak@quarnos.org
701d6381dSPawel Dziepak  */
801d6381dSPawel Dziepak 
901d6381dSPawel Dziepak 
1001d6381dSPawel Dziepak #include "Request.h"
1101d6381dSPawel Dziepak 
12060a4636SPawel Dziepak #include "FileSystem.h"
13060a4636SPawel Dziepak #include "Inode.h"
14060a4636SPawel Dziepak 
1501d6381dSPawel Dziepak 
1601d6381dSPawel Dziepak status_t
17be4c74eaSPawel Dziepak Request::Send(Cookie* cookie)
1801d6381dSPawel Dziepak {
195945c55aSPawel Dziepak 	switch (fServer->ID().fProtocol) {
20c3b57e8eSPawel Dziepak 		case IPPROTO_UDP:	return _SendUDP(cookie);
21c3b57e8eSPawel Dziepak 		case IPPROTO_TCP:	return _SendTCP(cookie);
225945c55aSPawel Dziepak 	}
235945c55aSPawel Dziepak 
245945c55aSPawel Dziepak 	return B_BAD_VALUE;
253ce57b34SPawel Dziepak }
263ce57b34SPawel Dziepak 
273ce57b34SPawel Dziepak 
283ce57b34SPawel Dziepak status_t
29be4c74eaSPawel Dziepak Request::_SendUDP(Cookie* cookie)
303ce57b34SPawel Dziepak {
31be4c74eaSPawel Dziepak 	RPC::Reply* rpl = NULL;
323ce57b34SPawel Dziepak 	RPC::Request* rpc;
333ce57b34SPawel Dziepak 
343ce57b34SPawel Dziepak 	status_t result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
3501d6381dSPawel Dziepak 	if (result != B_OK)
3601d6381dSPawel Dziepak 		return result;
3701d6381dSPawel Dziepak 
38be4c74eaSPawel Dziepak 	if (cookie != NULL)
39be4c74eaSPawel Dziepak 		cookie->RegisterRequest(rpc);
40be4c74eaSPawel Dziepak 
41*e4cd963fSPawel Dziepak 	int requestTimeout = sSecToBigTime(60);
42060a4636SPawel Dziepak 	int retryLimit = 0;
43060a4636SPawel Dziepak 	bool hard = true;
44*e4cd963fSPawel Dziepak 
45060a4636SPawel Dziepak 	if (fFileSystem != NULL) {
46*e4cd963fSPawel Dziepak 		requestTimeout = fFileSystem->GetConfiguration().fRequestTimeout;
47060a4636SPawel Dziepak 		retryLimit = fFileSystem->GetConfiguration().fRetryLimit;
48060a4636SPawel Dziepak 		hard = fFileSystem->GetConfiguration().fHard;
49060a4636SPawel Dziepak 	}
50060a4636SPawel Dziepak 
51*e4cd963fSPawel Dziepak 	result = fServer->WaitCall(rpc, requestTimeout);
523ce57b34SPawel Dziepak 	if (result != B_OK) {
535945c55aSPawel Dziepak 		int attempts = 1;
54060a4636SPawel Dziepak 		while (result != B_OK && (hard || attempts++ < retryLimit)) {
555945c55aSPawel Dziepak 			result = fServer->ResendCallAsync(fBuilder.Request(), rpc);
56be4c74eaSPawel Dziepak 			if (result != B_OK) {
57be4c74eaSPawel Dziepak 				if (cookie != NULL)
58be4c74eaSPawel Dziepak 					cookie->UnregisterRequest(rpc);
590792abe0SPawel Dziepak 				return result;
60be4c74eaSPawel Dziepak 			}
615945c55aSPawel Dziepak 
62*e4cd963fSPawel Dziepak 			result = fServer->WaitCall(rpc, requestTimeout);
630792abe0SPawel Dziepak 		}
640792abe0SPawel Dziepak 
650792abe0SPawel Dziepak 		if (result != B_OK) {
66be4c74eaSPawel Dziepak 			if (cookie != NULL)
67be4c74eaSPawel Dziepak 				cookie->UnregisterRequest(rpc);
683ce57b34SPawel Dziepak 			fServer->CancelCall(rpc);
693ce57b34SPawel Dziepak 			delete rpc;
703ce57b34SPawel Dziepak 			return result;
713ce57b34SPawel Dziepak 		}
725945c55aSPawel Dziepak 	}
735945c55aSPawel Dziepak 
74be4c74eaSPawel Dziepak 	if (cookie != NULL)
75be4c74eaSPawel Dziepak 		cookie->UnregisterRequest(rpc);
76be4c74eaSPawel Dziepak 
77be4c74eaSPawel Dziepak 	if (rpc->fError != B_OK) {
78be4c74eaSPawel Dziepak 		delete rpl;
79be4c74eaSPawel Dziepak 		result = rpc->fError;
80be4c74eaSPawel Dziepak 		delete rpc;
81be4c74eaSPawel Dziepak 		return result;
82be4c74eaSPawel Dziepak 	} else {
83be4c74eaSPawel Dziepak 		fReply.SetTo(rpl);
84be4c74eaSPawel Dziepak 		delete rpc;
85be4c74eaSPawel Dziepak 		return B_OK;
86be4c74eaSPawel Dziepak 	}
875945c55aSPawel Dziepak }
885945c55aSPawel Dziepak 
895945c55aSPawel Dziepak 
905945c55aSPawel Dziepak status_t
91be4c74eaSPawel Dziepak Request::_SendTCP(Cookie* cookie)
925945c55aSPawel Dziepak {
93be4c74eaSPawel Dziepak 	RPC::Reply* rpl = NULL;
945945c55aSPawel Dziepak 	RPC::Request* rpc;
955945c55aSPawel Dziepak 
965945c55aSPawel Dziepak 	status_t result;
975945c55aSPawel Dziepak 	int attempts = 0;
98060a4636SPawel Dziepak 
99*e4cd963fSPawel Dziepak 	int requestTimeout = sSecToBigTime(60);
100060a4636SPawel Dziepak 	int retryLimit = 0;
101060a4636SPawel Dziepak 	bool hard = true;
102060a4636SPawel Dziepak 
103060a4636SPawel Dziepak 	if (fFileSystem != NULL) {
104*e4cd963fSPawel Dziepak 		requestTimeout = fFileSystem->GetConfiguration().fRequestTimeout;
105060a4636SPawel Dziepak 		retryLimit = fFileSystem->GetConfiguration().fRetryLimit;
106060a4636SPawel Dziepak 		hard = fFileSystem->GetConfiguration().fHard;
107060a4636SPawel Dziepak 	}
108060a4636SPawel Dziepak 
1095945c55aSPawel Dziepak 	do {
1105945c55aSPawel Dziepak 		result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
1115945c55aSPawel Dziepak 		if (result == B_NO_MEMORY)
1125945c55aSPawel Dziepak 			return result;
1135945c55aSPawel Dziepak 		else if (result != B_OK) {
1145945c55aSPawel Dziepak 			fServer->Repair();
1155945c55aSPawel Dziepak 			continue;
1165945c55aSPawel Dziepak 		}
1175945c55aSPawel Dziepak 
118be4c74eaSPawel Dziepak 		if (cookie != NULL)
119be4c74eaSPawel Dziepak 			cookie->RegisterRequest(rpc);
120be4c74eaSPawel Dziepak 
121*e4cd963fSPawel Dziepak 		result = fServer->WaitCall(rpc, requestTimeout);
1225945c55aSPawel Dziepak 		if (result != B_OK) {
123be4c74eaSPawel Dziepak 			if (cookie != NULL)
124be4c74eaSPawel Dziepak 				cookie->UnregisterRequest(rpc);
125be4c74eaSPawel Dziepak 
1265945c55aSPawel Dziepak 			fServer->CancelCall(rpc);
1275945c55aSPawel Dziepak 			delete rpc;
1285945c55aSPawel Dziepak 
1295945c55aSPawel Dziepak 			fServer->Repair();
1305945c55aSPawel Dziepak 		}
131060a4636SPawel Dziepak 	} while (result != B_OK && (hard || attempts++ < retryLimit));
1323ce57b34SPawel Dziepak 
133e8ef557aSPawel Dziepak 	if (result != B_OK)
134e8ef557aSPawel Dziepak 		return result;
135e8ef557aSPawel Dziepak 
136be4c74eaSPawel Dziepak 	if (cookie != NULL)
137be4c74eaSPawel Dziepak 		cookie->UnregisterRequest(rpc);
138be4c74eaSPawel Dziepak 
139be4c74eaSPawel Dziepak 	if (rpc->fError != B_OK) {
140be4c74eaSPawel Dziepak 		delete rpl;
141be4c74eaSPawel Dziepak 		result = rpc->fError;
142be4c74eaSPawel Dziepak 		delete rpc;
143be4c74eaSPawel Dziepak 		return result;
144e8ef557aSPawel Dziepak 	}
145e8ef557aSPawel Dziepak 
146be4c74eaSPawel Dziepak 	fReply.SetTo(rpl);
147be4c74eaSPawel Dziepak 	delete rpc;
148be4c74eaSPawel Dziepak 	return B_OK;
14901d6381dSPawel Dziepak }
15001d6381dSPawel Dziepak 
15101d6381dSPawel Dziepak 
15201d6381dSPawel Dziepak void
15301d6381dSPawel Dziepak Request::Reset()
15401d6381dSPawel Dziepak {
15501d6381dSPawel Dziepak 	fBuilder.Reset();
15601d6381dSPawel Dziepak 	fReply.Reset();
15701d6381dSPawel Dziepak }
15801d6381dSPawel Dziepak 
159