xref: /haiku/src/add-ons/kernel/file_systems/nfs4/Request.cpp (revision be4c74ead31246bd9b332f83a9e298969385fc4e)
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 
10*be4c74eaSPawel Dziepak #include "Inode.h"
1101d6381dSPawel Dziepak #include "Request.h"
1201d6381dSPawel Dziepak 
1301d6381dSPawel Dziepak 
1401d6381dSPawel Dziepak status_t
15*be4c74eaSPawel Dziepak Request::Send(Cookie* cookie)
1601d6381dSPawel Dziepak {
175945c55aSPawel Dziepak 	switch (fServer->ID().fProtocol) {
18*be4c74eaSPawel Dziepak 		case ProtocolUDP:	return _SendUDP(cookie);
19*be4c74eaSPawel Dziepak 		case ProtocolTCP:	return _SendTCP(cookie);
205945c55aSPawel Dziepak 	}
215945c55aSPawel Dziepak 
225945c55aSPawel Dziepak 	return B_BAD_VALUE;
233ce57b34SPawel Dziepak }
243ce57b34SPawel Dziepak 
253ce57b34SPawel Dziepak 
263ce57b34SPawel Dziepak status_t
27*be4c74eaSPawel Dziepak Request::_SendUDP(Cookie* cookie)
283ce57b34SPawel Dziepak {
29*be4c74eaSPawel Dziepak 	RPC::Reply *rpl = NULL;
303ce57b34SPawel Dziepak 	RPC::Request *rpc;
313ce57b34SPawel Dziepak 
323ce57b34SPawel Dziepak 	status_t result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
3301d6381dSPawel Dziepak 	if (result != B_OK)
3401d6381dSPawel Dziepak 		return result;
3501d6381dSPawel Dziepak 
36*be4c74eaSPawel Dziepak 	if (cookie != NULL)
37*be4c74eaSPawel Dziepak 		cookie->RegisterRequest(rpc);
38*be4c74eaSPawel Dziepak 
393ce57b34SPawel Dziepak 	result = fServer->WaitCall(rpc);
403ce57b34SPawel Dziepak 	if (result != B_OK) {
415945c55aSPawel Dziepak 		int attempts = 1;
420792abe0SPawel Dziepak 		while (result != B_OK && attempts++ < kRetryLimit) {
435945c55aSPawel Dziepak 			result = fServer->ResendCallAsync(fBuilder.Request(), rpc);
44*be4c74eaSPawel Dziepak 			if (result != B_OK) {
45*be4c74eaSPawel Dziepak 				if (cookie != NULL)
46*be4c74eaSPawel Dziepak 					cookie->UnregisterRequest(rpc);
470792abe0SPawel Dziepak 				return result;
48*be4c74eaSPawel Dziepak 			}
495945c55aSPawel Dziepak 
500792abe0SPawel Dziepak 			result = fServer->WaitCall(rpc);
510792abe0SPawel Dziepak 		}
520792abe0SPawel Dziepak 
530792abe0SPawel Dziepak 		if (result != B_OK) {
54*be4c74eaSPawel Dziepak 			if (cookie != NULL)
55*be4c74eaSPawel Dziepak 				cookie->UnregisterRequest(rpc);
563ce57b34SPawel Dziepak 			fServer->CancelCall(rpc);
573ce57b34SPawel Dziepak 			delete rpc;
583ce57b34SPawel Dziepak 			return result;
593ce57b34SPawel Dziepak 		}
605945c55aSPawel Dziepak 	}
615945c55aSPawel Dziepak 
62*be4c74eaSPawel Dziepak 	if (cookie != NULL)
63*be4c74eaSPawel Dziepak 		cookie->UnregisterRequest(rpc);
64*be4c74eaSPawel Dziepak 
65*be4c74eaSPawel Dziepak 	if (rpc->fError != B_OK) {
66*be4c74eaSPawel Dziepak 		delete rpl;
67*be4c74eaSPawel Dziepak 		result = rpc->fError;
68*be4c74eaSPawel Dziepak 		delete rpc;
69*be4c74eaSPawel Dziepak 		return result;
70*be4c74eaSPawel Dziepak 	} else {
71*be4c74eaSPawel Dziepak 		fReply.SetTo(rpl);
72*be4c74eaSPawel Dziepak 		delete rpc;
73*be4c74eaSPawel Dziepak 		return B_OK;
74*be4c74eaSPawel Dziepak 	}
755945c55aSPawel Dziepak }
765945c55aSPawel Dziepak 
775945c55aSPawel Dziepak 
785945c55aSPawel Dziepak status_t
79*be4c74eaSPawel Dziepak Request::_SendTCP(Cookie* cookie)
805945c55aSPawel Dziepak {
81*be4c74eaSPawel Dziepak 	RPC::Reply *rpl = NULL;
825945c55aSPawel Dziepak 	RPC::Request *rpc;
835945c55aSPawel Dziepak 
845945c55aSPawel Dziepak 	status_t result;
855945c55aSPawel Dziepak 	int attempts = 0;
865945c55aSPawel Dziepak 	do {
875945c55aSPawel Dziepak 		result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
885945c55aSPawel Dziepak 		if (result == B_NO_MEMORY)
895945c55aSPawel Dziepak 			return result;
905945c55aSPawel Dziepak 		else if (result != B_OK) {
915945c55aSPawel Dziepak 			fServer->Repair();
925945c55aSPawel Dziepak 			continue;
935945c55aSPawel Dziepak 		}
945945c55aSPawel Dziepak 
95*be4c74eaSPawel Dziepak 		if (cookie != NULL)
96*be4c74eaSPawel Dziepak 			cookie->RegisterRequest(rpc);
97*be4c74eaSPawel Dziepak 
985945c55aSPawel Dziepak 		result = fServer->WaitCall(rpc);
995945c55aSPawel Dziepak 		if (result != B_OK) {
100*be4c74eaSPawel Dziepak 			if (cookie != NULL)
101*be4c74eaSPawel Dziepak 				cookie->UnregisterRequest(rpc);
102*be4c74eaSPawel Dziepak 
1035945c55aSPawel Dziepak 			fServer->CancelCall(rpc);
1045945c55aSPawel Dziepak 			delete rpc;
1055945c55aSPawel Dziepak 
1065945c55aSPawel Dziepak 			fServer->Repair();
1075945c55aSPawel Dziepak 		}
1085945c55aSPawel Dziepak 	} while (result != B_OK && attempts++ < kRetryLimit);
1093ce57b34SPawel Dziepak 
110*be4c74eaSPawel Dziepak 	if (cookie != NULL)
111*be4c74eaSPawel Dziepak 		cookie->UnregisterRequest(rpc);
112*be4c74eaSPawel Dziepak 
113*be4c74eaSPawel Dziepak 	if (rpc->fError != B_OK) {
114*be4c74eaSPawel Dziepak 		delete rpl;
115*be4c74eaSPawel Dziepak 		result = rpc->fError;
116*be4c74eaSPawel Dziepak 		delete rpc;
117*be4c74eaSPawel Dziepak 		return result;
118*be4c74eaSPawel Dziepak 	} else {
119*be4c74eaSPawel Dziepak 		fReply.SetTo(rpl);
120*be4c74eaSPawel Dziepak 		delete rpc;
121*be4c74eaSPawel Dziepak 		return B_OK;
122*be4c74eaSPawel Dziepak 	};
12301d6381dSPawel Dziepak }
12401d6381dSPawel Dziepak 
12501d6381dSPawel Dziepak 
12601d6381dSPawel Dziepak void
12701d6381dSPawel Dziepak Request::Reset()
12801d6381dSPawel Dziepak {
12901d6381dSPawel Dziepak 	fBuilder.Reset();
13001d6381dSPawel Dziepak 	fReply.Reset();
13101d6381dSPawel Dziepak }
13201d6381dSPawel Dziepak 
133