xref: /haiku/src/add-ons/kernel/file_systems/nfs4/Request.cpp (revision 25a7b01d15612846f332751841da3579db313082)
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
Send(Cookie * cookie)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
_SendUDP(Cookie * cookie)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 
41e4cd963fSPawel Dziepak 	int requestTimeout = sSecToBigTime(60);
42060a4636SPawel Dziepak 	int retryLimit = 0;
43060a4636SPawel Dziepak 	bool hard = true;
44e4cd963fSPawel Dziepak 
45060a4636SPawel Dziepak 	if (fFileSystem != NULL) {
46e4cd963fSPawel Dziepak 		requestTimeout = fFileSystem->GetConfiguration().fRequestTimeout;
47060a4636SPawel Dziepak 		retryLimit = fFileSystem->GetConfiguration().fRetryLimit;
48060a4636SPawel Dziepak 		hard = fFileSystem->GetConfiguration().fHard;
49060a4636SPawel Dziepak 	}
50060a4636SPawel Dziepak 
51e4cd963fSPawel 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);
59*b6868c6eSPawel Dziepak 				delete rpc;
600792abe0SPawel Dziepak 				return result;
61be4c74eaSPawel Dziepak 			}
625945c55aSPawel Dziepak 
63e4cd963fSPawel Dziepak 			result = fServer->WaitCall(rpc, requestTimeout);
640792abe0SPawel Dziepak 		}
650792abe0SPawel Dziepak 
660792abe0SPawel Dziepak 		if (result != B_OK) {
67be4c74eaSPawel Dziepak 			if (cookie != NULL)
68be4c74eaSPawel Dziepak 				cookie->UnregisterRequest(rpc);
693ce57b34SPawel Dziepak 			fServer->CancelCall(rpc);
703ce57b34SPawel Dziepak 			delete rpc;
713ce57b34SPawel Dziepak 			return result;
723ce57b34SPawel Dziepak 		}
735945c55aSPawel Dziepak 	}
745945c55aSPawel Dziepak 
75be4c74eaSPawel Dziepak 	if (cookie != NULL)
76be4c74eaSPawel Dziepak 		cookie->UnregisterRequest(rpc);
77be4c74eaSPawel Dziepak 
78be4c74eaSPawel Dziepak 	if (rpc->fError != B_OK) {
79be4c74eaSPawel Dziepak 		delete rpl;
80be4c74eaSPawel Dziepak 		result = rpc->fError;
81be4c74eaSPawel Dziepak 		delete rpc;
82be4c74eaSPawel Dziepak 		return result;
83be4c74eaSPawel Dziepak 	} else {
84be4c74eaSPawel Dziepak 		fReply.SetTo(rpl);
85be4c74eaSPawel Dziepak 		delete rpc;
86be4c74eaSPawel Dziepak 		return B_OK;
87be4c74eaSPawel Dziepak 	}
885945c55aSPawel Dziepak }
895945c55aSPawel Dziepak 
905945c55aSPawel Dziepak 
915945c55aSPawel Dziepak status_t
_SendTCP(Cookie * cookie)92be4c74eaSPawel Dziepak Request::_SendTCP(Cookie* cookie)
935945c55aSPawel Dziepak {
94be4c74eaSPawel Dziepak 	RPC::Reply* rpl = NULL;
955945c55aSPawel Dziepak 	RPC::Request* rpc;
965945c55aSPawel Dziepak 
975945c55aSPawel Dziepak 	status_t result;
985945c55aSPawel Dziepak 	int attempts = 0;
99060a4636SPawel Dziepak 
100e4cd963fSPawel Dziepak 	int requestTimeout = sSecToBigTime(60);
101060a4636SPawel Dziepak 	int retryLimit = 0;
102060a4636SPawel Dziepak 	bool hard = true;
103060a4636SPawel Dziepak 
104060a4636SPawel Dziepak 	if (fFileSystem != NULL) {
105e4cd963fSPawel Dziepak 		requestTimeout = fFileSystem->GetConfiguration().fRequestTimeout;
106060a4636SPawel Dziepak 		retryLimit = fFileSystem->GetConfiguration().fRetryLimit;
107060a4636SPawel Dziepak 		hard = fFileSystem->GetConfiguration().fHard;
108060a4636SPawel Dziepak 	}
109060a4636SPawel Dziepak 
1105945c55aSPawel Dziepak 	do {
1115945c55aSPawel Dziepak 		result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
1125945c55aSPawel Dziepak 		if (result == B_NO_MEMORY)
1135945c55aSPawel Dziepak 			return result;
1145945c55aSPawel Dziepak 		else if (result != B_OK) {
1155945c55aSPawel Dziepak 			fServer->Repair();
1165945c55aSPawel Dziepak 			continue;
1175945c55aSPawel Dziepak 		}
1185945c55aSPawel Dziepak 
119be4c74eaSPawel Dziepak 		if (cookie != NULL)
120be4c74eaSPawel Dziepak 			cookie->RegisterRequest(rpc);
121be4c74eaSPawel Dziepak 
122e4cd963fSPawel Dziepak 		result = fServer->WaitCall(rpc, requestTimeout);
1235945c55aSPawel Dziepak 		if (result != B_OK) {
124be4c74eaSPawel Dziepak 			if (cookie != NULL)
125be4c74eaSPawel Dziepak 				cookie->UnregisterRequest(rpc);
126be4c74eaSPawel Dziepak 
1275945c55aSPawel Dziepak 			fServer->CancelCall(rpc);
1285945c55aSPawel Dziepak 			delete rpc;
1295945c55aSPawel Dziepak 
1305945c55aSPawel Dziepak 			fServer->Repair();
1315945c55aSPawel Dziepak 		}
132060a4636SPawel Dziepak 	} while (result != B_OK && (hard || attempts++ < retryLimit));
1333ce57b34SPawel Dziepak 
134e8ef557aSPawel Dziepak 	if (result != B_OK)
135e8ef557aSPawel Dziepak 		return result;
136e8ef557aSPawel Dziepak 
137be4c74eaSPawel Dziepak 	if (cookie != NULL)
138be4c74eaSPawel Dziepak 		cookie->UnregisterRequest(rpc);
139be4c74eaSPawel Dziepak 
140be4c74eaSPawel Dziepak 	if (rpc->fError != B_OK) {
141be4c74eaSPawel Dziepak 		delete rpl;
142be4c74eaSPawel Dziepak 		result = rpc->fError;
143be4c74eaSPawel Dziepak 		delete rpc;
144be4c74eaSPawel Dziepak 		return result;
145e8ef557aSPawel Dziepak 	}
146e8ef557aSPawel Dziepak 
147be4c74eaSPawel Dziepak 	fReply.SetTo(rpl);
148be4c74eaSPawel Dziepak 	delete rpc;
149be4c74eaSPawel Dziepak 	return B_OK;
15001d6381dSPawel Dziepak }
15101d6381dSPawel Dziepak 
15201d6381dSPawel Dziepak 
15301d6381dSPawel Dziepak void
Reset()15401d6381dSPawel Dziepak Request::Reset()
15501d6381dSPawel Dziepak {
15601d6381dSPawel Dziepak 	fBuilder.Reset();
15701d6381dSPawel Dziepak 	fReply.Reset();
15801d6381dSPawel Dziepak }
15901d6381dSPawel Dziepak 
160