xref: /haiku/src/add-ons/kernel/file_systems/nfs4/Request.cpp (revision e8ef557a560f15c0133390e86288d17c2ad41114)
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 
41060a4636SPawel Dziepak 	int retryLimit = 0;
42060a4636SPawel Dziepak 	bool hard = true;
43060a4636SPawel Dziepak 	if (fFileSystem != NULL) {
44060a4636SPawel Dziepak 		retryLimit = fFileSystem->GetConfiguration().fRetryLimit;
45060a4636SPawel Dziepak 		hard = fFileSystem->GetConfiguration().fHard;
46060a4636SPawel Dziepak 	}
47060a4636SPawel Dziepak 
483ce57b34SPawel Dziepak 	result = fServer->WaitCall(rpc);
493ce57b34SPawel Dziepak 	if (result != B_OK) {
505945c55aSPawel Dziepak 		int attempts = 1;
51060a4636SPawel Dziepak 		while (result != B_OK && (hard || attempts++ < retryLimit)) {
525945c55aSPawel Dziepak 			result = fServer->ResendCallAsync(fBuilder.Request(), rpc);
53be4c74eaSPawel Dziepak 			if (result != B_OK) {
54be4c74eaSPawel Dziepak 				if (cookie != NULL)
55be4c74eaSPawel Dziepak 					cookie->UnregisterRequest(rpc);
560792abe0SPawel Dziepak 				return result;
57be4c74eaSPawel Dziepak 			}
585945c55aSPawel Dziepak 
590792abe0SPawel Dziepak 			result = fServer->WaitCall(rpc);
600792abe0SPawel Dziepak 		}
610792abe0SPawel Dziepak 
620792abe0SPawel Dziepak 		if (result != B_OK) {
63be4c74eaSPawel Dziepak 			if (cookie != NULL)
64be4c74eaSPawel Dziepak 				cookie->UnregisterRequest(rpc);
653ce57b34SPawel Dziepak 			fServer->CancelCall(rpc);
663ce57b34SPawel Dziepak 			delete rpc;
673ce57b34SPawel Dziepak 			return result;
683ce57b34SPawel Dziepak 		}
695945c55aSPawel Dziepak 	}
705945c55aSPawel Dziepak 
71be4c74eaSPawel Dziepak 	if (cookie != NULL)
72be4c74eaSPawel Dziepak 		cookie->UnregisterRequest(rpc);
73be4c74eaSPawel Dziepak 
74be4c74eaSPawel Dziepak 	if (rpc->fError != B_OK) {
75be4c74eaSPawel Dziepak 		delete rpl;
76be4c74eaSPawel Dziepak 		result = rpc->fError;
77be4c74eaSPawel Dziepak 		delete rpc;
78be4c74eaSPawel Dziepak 		return result;
79be4c74eaSPawel Dziepak 	} else {
80be4c74eaSPawel Dziepak 		fReply.SetTo(rpl);
81be4c74eaSPawel Dziepak 		delete rpc;
82be4c74eaSPawel Dziepak 		return B_OK;
83be4c74eaSPawel Dziepak 	}
845945c55aSPawel Dziepak }
855945c55aSPawel Dziepak 
865945c55aSPawel Dziepak 
875945c55aSPawel Dziepak status_t
88be4c74eaSPawel Dziepak Request::_SendTCP(Cookie* cookie)
895945c55aSPawel Dziepak {
90be4c74eaSPawel Dziepak 	RPC::Reply* rpl = NULL;
915945c55aSPawel Dziepak 	RPC::Request* rpc;
925945c55aSPawel Dziepak 
935945c55aSPawel Dziepak 	status_t result;
945945c55aSPawel Dziepak 	int attempts = 0;
95060a4636SPawel Dziepak 
96060a4636SPawel Dziepak 	int retryLimit = 0;
97060a4636SPawel Dziepak 	bool hard = true;
98060a4636SPawel Dziepak 
99060a4636SPawel Dziepak 	if (fFileSystem != NULL) {
100060a4636SPawel Dziepak 		retryLimit = fFileSystem->GetConfiguration().fRetryLimit;
101060a4636SPawel Dziepak 		hard = fFileSystem->GetConfiguration().fHard;
102060a4636SPawel Dziepak 	}
103060a4636SPawel Dziepak 
1045945c55aSPawel Dziepak 	do {
1055945c55aSPawel Dziepak 		result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
1065945c55aSPawel Dziepak 		if (result == B_NO_MEMORY)
1075945c55aSPawel Dziepak 			return result;
1085945c55aSPawel Dziepak 		else if (result != B_OK) {
1095945c55aSPawel Dziepak 			fServer->Repair();
1105945c55aSPawel Dziepak 			continue;
1115945c55aSPawel Dziepak 		}
1125945c55aSPawel Dziepak 
113be4c74eaSPawel Dziepak 		if (cookie != NULL)
114be4c74eaSPawel Dziepak 			cookie->RegisterRequest(rpc);
115be4c74eaSPawel Dziepak 
1165945c55aSPawel Dziepak 		result = fServer->WaitCall(rpc);
1175945c55aSPawel Dziepak 		if (result != B_OK) {
118be4c74eaSPawel Dziepak 			if (cookie != NULL)
119be4c74eaSPawel Dziepak 				cookie->UnregisterRequest(rpc);
120be4c74eaSPawel Dziepak 
1215945c55aSPawel Dziepak 			fServer->CancelCall(rpc);
1225945c55aSPawel Dziepak 			delete rpc;
1235945c55aSPawel Dziepak 
1245945c55aSPawel Dziepak 			fServer->Repair();
1255945c55aSPawel Dziepak 		}
126060a4636SPawel Dziepak 	} while (result != B_OK && (hard || attempts++ < retryLimit));
1273ce57b34SPawel Dziepak 
128*e8ef557aSPawel Dziepak 	if (result != B_OK)
129*e8ef557aSPawel Dziepak 		return result;
130*e8ef557aSPawel Dziepak 
131be4c74eaSPawel Dziepak 	if (cookie != NULL)
132be4c74eaSPawel Dziepak 		cookie->UnregisterRequest(rpc);
133be4c74eaSPawel Dziepak 
134be4c74eaSPawel Dziepak 	if (rpc->fError != B_OK) {
135be4c74eaSPawel Dziepak 		delete rpl;
136be4c74eaSPawel Dziepak 		result = rpc->fError;
137be4c74eaSPawel Dziepak 		delete rpc;
138be4c74eaSPawel Dziepak 		return result;
139*e8ef557aSPawel Dziepak 	}
140*e8ef557aSPawel Dziepak 
141be4c74eaSPawel Dziepak 	fReply.SetTo(rpl);
142be4c74eaSPawel Dziepak 	delete rpc;
143be4c74eaSPawel Dziepak 	return B_OK;
14401d6381dSPawel Dziepak }
14501d6381dSPawel Dziepak 
14601d6381dSPawel Dziepak 
14701d6381dSPawel Dziepak void
14801d6381dSPawel Dziepak Request::Reset()
14901d6381dSPawel Dziepak {
15001d6381dSPawel Dziepak 	fBuilder.Reset();
15101d6381dSPawel Dziepak 	fReply.Reset();
15201d6381dSPawel Dziepak }
15301d6381dSPawel Dziepak 
154