nfs4: use exponential backoff when the server ask to wait
This commit is contained in:
@@ -40,6 +40,7 @@ Delegation::GiveUp(bool truncate)
|
|||||||
status_t
|
status_t
|
||||||
Delegation::ReturnDelegation()
|
Delegation::ReturnDelegation()
|
||||||
{
|
{
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -54,8 +55,10 @@ Delegation::ReturnDelegation()
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, NULL, fInode->GetOpenState()))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL,
|
||||||
|
fInode->GetOpenState())) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ Inode::CreateInode(FileSystem* fs, const FileInfo& fi, Inode** _inode)
|
|||||||
inode->fInfo = fi;
|
inode->fInfo = fi;
|
||||||
inode->fFileSystem = fs;
|
inode->fFileSystem = fs;
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
uint64 size;
|
uint64 size;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fs->Server();
|
RPC::Server* serv = fs->Server();
|
||||||
@@ -78,7 +79,7 @@ Inode::CreateInode(FileSystem* fs, const FileInfo& fi, Inode** _inode)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (inode->HandleErrors(reply.NFS4Error(), serv))
|
if (inode->HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ Inode::ReadDirUp(struct dirent* de, uint32 pos, uint32 size)
|
|||||||
{
|
{
|
||||||
ASSERT(de != NULL);
|
ASSERT(de != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -166,7 +167,7 @@ Inode::ReadDirUp(struct dirent* de, uint32 pos, uint32 size)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
|
|||||||
@@ -367,5 +367,13 @@ sSecToBigTime(uint32 sec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
IsFileHandleInvalid(uint32 error)
|
||||||
|
{
|
||||||
|
return error == NFS4ERR_BADHANDLE || error == NFS4ERR_FHEXPIRED
|
||||||
|
|| error == NFS4ERR_STALE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // NFS4DEFS_H
|
#endif // NFS4DEFS_H
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ NFS4Inode::GetChangeInfo(uint64* change, bool attrDir)
|
|||||||
{
|
{
|
||||||
ASSERT(change != NULL);
|
ASSERT(change != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -39,7 +40,7 @@ NFS4Inode::GetChangeInfo(uint64* change, bool attrDir)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -62,6 +63,7 @@ NFS4Inode::GetChangeInfo(uint64* change, bool attrDir)
|
|||||||
status_t
|
status_t
|
||||||
NFS4Inode::CommitWrites()
|
NFS4Inode::CommitWrites()
|
||||||
{
|
{
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -76,7 +78,7 @@ NFS4Inode::CommitWrites()
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -90,6 +92,7 @@ NFS4Inode::Access(uint32* allowed)
|
|||||||
{
|
{
|
||||||
ASSERT(allowed != NULL);
|
ASSERT(allowed != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -104,7 +107,7 @@ NFS4Inode::Access(uint32* allowed)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -120,6 +123,7 @@ NFS4Inode::LookUp(const char* name, uint64* change, uint64* fileID,
|
|||||||
{
|
{
|
||||||
ASSERT(name != NULL);
|
ASSERT(name != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -150,7 +154,7 @@ NFS4Inode::LookUp(const char* name, uint64* change, uint64* fileID,
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -209,6 +213,7 @@ NFS4Inode::Link(Inode* dir, const char* name, ChangeInfo* changeInfo)
|
|||||||
ASSERT(name != NULL);
|
ASSERT(name != NULL);
|
||||||
ASSERT(changeInfo != NULL);
|
ASSERT(changeInfo != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -225,7 +230,7 @@ NFS4Inode::Link(Inode* dir, const char* name, ChangeInfo* changeInfo)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -244,6 +249,7 @@ NFS4Inode::ReadLink(void* buffer, size_t* length)
|
|||||||
ASSERT(buffer != NULL);
|
ASSERT(buffer != NULL);
|
||||||
ASSERT(length != NULL);
|
ASSERT(length != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -258,7 +264,7 @@ NFS4Inode::ReadLink(void* buffer, size_t* length)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -278,6 +284,7 @@ NFS4Inode::GetStat(AttrValue** values, uint32* count, OpenAttrCookie* cookie)
|
|||||||
ASSERT(values != NULL);
|
ASSERT(values != NULL);
|
||||||
ASSERT(count != NULL);
|
ASSERT(count != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -300,7 +307,7 @@ NFS4Inode::GetStat(AttrValue** values, uint32* count, OpenAttrCookie* cookie)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -315,6 +322,7 @@ NFS4Inode::WriteStat(OpenState* state, AttrValue* attrs, uint32 attrCount)
|
|||||||
{
|
{
|
||||||
ASSERT(attrs != NULL);
|
ASSERT(attrs != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -334,7 +342,7 @@ NFS4Inode::WriteStat(OpenState* state, AttrValue* attrs, uint32 attrCount)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -360,9 +368,10 @@ NFS4Inode::RenameNode(Inode* from, Inode* to, const char* fromName,
|
|||||||
ASSERT(fromChange != NULL);
|
ASSERT(fromChange != NULL);
|
||||||
ASSERT(toChange != NULL);
|
ASSERT(toChange != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = from->fFileSystem->Server();
|
RPC::Server* server = from->fFileSystem->Server();
|
||||||
Request request(serv, from->fFileSystem);
|
Request request(server, from->fFileSystem);
|
||||||
RequestBuilder& req = request.Builder();
|
RequestBuilder& req = request.Builder();
|
||||||
|
|
||||||
if (attribute)
|
if (attribute)
|
||||||
@@ -388,24 +397,14 @@ NFS4Inode::RenameNode(Inode* from, Inode* to, const char* fromName,
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
// FileHandle has expired
|
// If we have to wait, migrate to another server, etc then the first
|
||||||
if (reply.NFS4Error() == NFS4ERR_FHEXPIRED) {
|
// HandleErrors() will do that. However, if the file handles
|
||||||
from->fInfo.UpdateFileHandles(from->fFileSystem);
|
// were invalid then we need to update both Inodes.
|
||||||
to->fInfo.UpdateFileHandles(to->fFileSystem);
|
bool retry = from->HandleErrors(attempt, reply.NFS4Error(), server);
|
||||||
|
if (IsFileHandleInvalid(reply.NFS4Error()))
|
||||||
|
retry |= to->HandleErrors(attempt, reply.NFS4Error(), server);
|
||||||
|
if (retry)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// filesystem has been moved
|
|
||||||
if (reply.NFS4Error() == NFS4ERR_MOVED) {
|
|
||||||
from->fFileSystem->Migrate(serv);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to wait
|
|
||||||
if (reply.NFS4Error() == NFS4ERR_DELAY) {
|
|
||||||
snooze_etc(sSecToBigTime(5), B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
reply.SaveFH();
|
reply.SaveFH();
|
||||||
@@ -455,6 +454,7 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms, OpenState* state,
|
|||||||
bool confirm;
|
bool confirm;
|
||||||
status_t result;
|
status_t result;
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
do {
|
do {
|
||||||
state->fClientID = fFileSystem->NFSServer()->ClientId();
|
state->fClientID = fFileSystem->NFSServer()->ClientId();
|
||||||
@@ -499,8 +499,10 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms, OpenState* state,
|
|||||||
|
|
||||||
sequence += IncrementSequence(reply.NFS4Error());
|
sequence += IncrementSequence(reply.NFS4Error());
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, NULL, state, &sequence))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, state,
|
||||||
|
&sequence)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
|
|
||||||
@@ -549,6 +551,8 @@ NFS4Inode::OpenFile(OpenState* state, int mode, OpenDelegationData* delegation)
|
|||||||
|
|
||||||
bool confirm;
|
bool confirm;
|
||||||
status_t result;
|
status_t result;
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
do {
|
do {
|
||||||
state->fClientID = fFileSystem->NFSServer()->ClientId();
|
state->fClientID = fFileSystem->NFSServer()->ClientId();
|
||||||
@@ -594,8 +598,10 @@ NFS4Inode::OpenFile(OpenState* state, int mode, OpenDelegationData* delegation)
|
|||||||
|
|
||||||
sequence += IncrementSequence(reply.NFS4Error());
|
sequence += IncrementSequence(reply.NFS4Error());
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, NULL, state, &sequence))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, state,
|
||||||
|
&sequence)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Verify if the file we want to open is the file this Inode
|
// Verify if the file we want to open is the file this Inode
|
||||||
// represents.
|
// represents.
|
||||||
@@ -656,6 +662,8 @@ NFS4Inode::OpenAttr(OpenState* state, const char* name, int mode,
|
|||||||
|
|
||||||
bool confirm;
|
bool confirm;
|
||||||
status_t result;
|
status_t result;
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
do {
|
do {
|
||||||
state->fClientID = fFileSystem->NFSServer()->ClientId();
|
state->fClientID = fFileSystem->NFSServer()->ClientId();
|
||||||
@@ -680,8 +688,10 @@ NFS4Inode::OpenAttr(OpenState* state, const char* name, int mode,
|
|||||||
|
|
||||||
sequence += IncrementSequence(reply.NFS4Error());
|
sequence += IncrementSequence(reply.NFS4Error());
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, NULL, state, &sequence))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, state,
|
||||||
|
&sequence)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
result = reply.Open(state->fStateID, &state->fStateSeq, &confirm,
|
result = reply.Open(state->fStateID, &state->fStateSeq, &confirm,
|
||||||
@@ -716,6 +726,7 @@ NFS4Inode::ReadFile(OpenStateCookie* cookie, OpenState* state, uint64 position,
|
|||||||
ASSERT(buffer != NULL);
|
ASSERT(buffer != NULL);
|
||||||
ASSERT(eof != NULL);
|
ASSERT(eof != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -730,7 +741,7 @@ NFS4Inode::ReadFile(OpenStateCookie* cookie, OpenState* state, uint64 position,
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, cookie, state))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, cookie, state))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -751,6 +762,7 @@ NFS4Inode::WriteFile(OpenStateCookie* cookie, OpenState* state, uint64 position,
|
|||||||
ASSERT(length != NULL);
|
ASSERT(length != NULL);
|
||||||
ASSERT(buffer != NULL);
|
ASSERT(buffer != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -767,7 +779,7 @@ NFS4Inode::WriteFile(OpenStateCookie* cookie, OpenState* state, uint64 position,
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, cookie, state))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, cookie, state))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -790,6 +802,7 @@ NFS4Inode::CreateObject(const char* name, const char* path, int mode,
|
|||||||
ASSERT(changeInfo != NULL);
|
ASSERT(changeInfo != NULL);
|
||||||
ASSERT(handle != NULL);
|
ASSERT(handle != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -829,7 +842,7 @@ NFS4Inode::CreateObject(const char* name, const char* path, int mode,
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -869,6 +882,7 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo,
|
|||||||
ASSERT(name != NULL);
|
ASSERT(name != NULL);
|
||||||
ASSERT(changeInfo != NULL);
|
ASSERT(changeInfo != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -899,7 +913,7 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo,
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -949,6 +963,7 @@ NFS4Inode::ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie,
|
|||||||
ASSERT(count != NULL);
|
ASSERT(count != NULL);
|
||||||
ASSERT(eof != NULL);
|
ASSERT(eof != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -975,7 +990,7 @@ NFS4Inode::ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie,
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -1022,6 +1037,7 @@ NFS4Inode::OpenAttrDir(FileHandle* handle)
|
|||||||
{
|
{
|
||||||
ASSERT(handle != NULL);
|
ASSERT(handle != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -1037,7 +1053,7 @@ NFS4Inode::OpenAttrDir(FileHandle* handle)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -1059,6 +1075,7 @@ NFS4Inode::TestLock(OpenFileCookie* cookie, LockType* type, uint64* position,
|
|||||||
ASSERT(position != NULL);
|
ASSERT(position != NULL);
|
||||||
ASSERT(length != NULL);
|
ASSERT(length != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -1072,8 +1089,10 @@ NFS4Inode::TestLock(OpenFileCookie* cookie, LockType* type, uint64* position,
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, cookie))
|
if (reply.NFS4Error() != NFS4ERR_DENIED) {
|
||||||
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, cookie))
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
result = reply.LockT(position, length, type);
|
result = reply.LockT(position, length, type);
|
||||||
@@ -1096,6 +1115,7 @@ NFS4Inode::AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo, bool wait)
|
|||||||
ASSERT(cookie != NULL);
|
ASSERT(cookie != NULL);
|
||||||
ASSERT(lockInfo != NULL);
|
ASSERT(lockInfo != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
do {
|
do {
|
||||||
MutexLocker ownerLocker(lockInfo->fOwner->fLock);
|
MutexLocker ownerLocker(lockInfo->fOwner->fLock);
|
||||||
@@ -1121,15 +1141,13 @@ NFS4Inode::AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo, bool wait)
|
|||||||
result = reply.Lock(lockInfo);
|
result = reply.Lock(lockInfo);
|
||||||
|
|
||||||
ownerLocker.Unlock();
|
ownerLocker.Unlock();
|
||||||
if (wait && reply.NFS4Error() == NFS4ERR_DENIED) {
|
|
||||||
fFileSystem->OpenOwnerSequenceUnlock(sequence);
|
if (reply.NFS4Error() != NFS4ERR_DENIED || wait) {
|
||||||
snooze_etc(sSecToBigTime(5), B_SYSTEM_TIMEBASE,
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, cookie, NULL,
|
||||||
B_RELATIVE_TIMEOUT);
|
&sequence)) {
|
||||||
sequence = fFileSystem->OpenOwnerSequenceLock();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, cookie, NULL, &sequence))
|
}
|
||||||
continue;
|
|
||||||
|
|
||||||
fFileSystem->OpenOwnerSequenceUnlock(sequence);
|
fFileSystem->OpenOwnerSequenceUnlock(sequence);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
@@ -1146,6 +1164,7 @@ NFS4Inode::ReleaseLock(OpenFileCookie* cookie, LockInfo* lockInfo)
|
|||||||
ASSERT(cookie != NULL);
|
ASSERT(cookie != NULL);
|
||||||
ASSERT(lockInfo != NULL);
|
ASSERT(lockInfo != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
MutexLocker ownerLocker(lockInfo->fOwner->fLock);
|
MutexLocker ownerLocker(lockInfo->fOwner->fLock);
|
||||||
|
|
||||||
@@ -1166,7 +1185,7 @@ NFS4Inode::ReleaseLock(OpenFileCookie* cookie, LockInfo* lockInfo)
|
|||||||
result = reply.LockU(lockInfo);
|
result = reply.LockU(lockInfo);
|
||||||
|
|
||||||
ownerLocker.Unlock();
|
ownerLocker.Unlock();
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, cookie))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, cookie))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
|
|||||||
@@ -14,12 +14,20 @@
|
|||||||
#include "Request.h"
|
#include "Request.h"
|
||||||
|
|
||||||
|
|
||||||
|
static inline bigtime_t
|
||||||
|
RetryDelay(uint32 attempt, uint32 leaseTime = 0)
|
||||||
|
{
|
||||||
|
bigtime_t delay = (1 << attempt - 1) * 100000;
|
||||||
|
if (leaseTime != 0)
|
||||||
|
delay = min_c(delay, sSecToBigTime(leaseTime));
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
NFS4Object::HandleErrors(uint32& attempt, uint32 nfs4Error, RPC::Server* server,
|
||||||
OpenStateCookie* cookie, OpenState* state, uint32* sequence)
|
OpenStateCookie* cookie, OpenState* state, uint32* sequence)
|
||||||
{
|
{
|
||||||
uint32 leaseTime;
|
|
||||||
|
|
||||||
// No request send by the client should cause any of the following errors.
|
// No request send by the client should cause any of the following errors.
|
||||||
ASSERT(nfs4Error != NFS4ERR_CLID_INUSE);
|
ASSERT(nfs4Error != NFS4ERR_CLID_INUSE);
|
||||||
ASSERT(nfs4Error != NFS4ERR_NOFILEHANDLE);
|
ASSERT(nfs4Error != NFS4ERR_NOFILEHANDLE);
|
||||||
@@ -28,18 +36,43 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
|||||||
ASSERT(nfs4Error != NFS4ERR_LOCKS_HELD);
|
ASSERT(nfs4Error != NFS4ERR_LOCKS_HELD);
|
||||||
ASSERT(nfs4Error != NFS4ERR_OP_ILLEGAL);
|
ASSERT(nfs4Error != NFS4ERR_OP_ILLEGAL);
|
||||||
|
|
||||||
|
attempt++;
|
||||||
|
|
||||||
if (cookie != NULL)
|
if (cookie != NULL)
|
||||||
state = cookie->fOpenState;
|
state = cookie->fOpenState;
|
||||||
|
|
||||||
|
uint32 leaseTime;
|
||||||
|
status_t result;
|
||||||
switch (nfs4Error) {
|
switch (nfs4Error) {
|
||||||
case NFS4_OK:
|
case NFS4_OK:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// retransmission of CLOSE caused seqid to fall back
|
// retransmission of CLOSE caused seqid to fall back
|
||||||
case NFS4ERR_BAD_SEQID:
|
case NFS4ERR_BAD_SEQID:
|
||||||
|
if (attempt == 1) {
|
||||||
ASSERT(sequence != NULL);
|
ASSERT(sequence != NULL);
|
||||||
(*sequence)++;
|
(*sequence)++;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// resource is locked, we need to wait
|
||||||
|
case NFS4ERR_DENIED:
|
||||||
|
if (sequence != NULL)
|
||||||
|
fFileSystem->OpenOwnerSequenceUnlock(*sequence);
|
||||||
|
|
||||||
|
result = acquire_sem_etc(cookie->fSnoozeCancel, 1,
|
||||||
|
B_RELATIVE_TIMEOUT, RetryDelay(attempt));
|
||||||
|
|
||||||
|
if (sequence != NULL)
|
||||||
|
*sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
|
|
||||||
|
if (result != B_TIMED_OUT) {
|
||||||
|
if (result == B_OK)
|
||||||
|
release_sem(cookie->fSnoozeCancel);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
// server needs more time, we need to wait
|
// server needs more time, we need to wait
|
||||||
case NFS4ERR_LOCKED:
|
case NFS4ERR_LOCKED:
|
||||||
@@ -48,9 +81,10 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
|||||||
fFileSystem->OpenOwnerSequenceUnlock(*sequence);
|
fFileSystem->OpenOwnerSequenceUnlock(*sequence);
|
||||||
|
|
||||||
if (cookie == NULL) {
|
if (cookie == NULL) {
|
||||||
snooze_etc(sSecToBigTime(5), B_SYSTEM_TIMEBASE,
|
snooze_etc(RetryDelay(attempt), B_SYSTEM_TIMEBASE,
|
||||||
B_RELATIVE_TIMEOUT);
|
B_RELATIVE_TIMEOUT);
|
||||||
|
|
||||||
|
|
||||||
if (sequence != NULL)
|
if (sequence != NULL)
|
||||||
*sequence = fFileSystem->OpenOwnerSequenceLock();
|
*sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
|
|
||||||
@@ -58,8 +92,8 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((cookie->fMode & O_NONBLOCK) == 0) {
|
if ((cookie->fMode & O_NONBLOCK) == 0) {
|
||||||
status_t result = acquire_sem_etc(cookie->fSnoozeCancel, 1,
|
result = acquire_sem_etc(cookie->fSnoozeCancel, 1,
|
||||||
B_RELATIVE_TIMEOUT, sSecToBigTime(5));
|
B_RELATIVE_TIMEOUT, RetryDelay(attempt));
|
||||||
|
|
||||||
if (sequence != NULL)
|
if (sequence != NULL)
|
||||||
*sequence = fFileSystem->OpenOwnerSequenceLock();
|
*sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
@@ -83,7 +117,7 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
|||||||
fFileSystem->OpenOwnerSequenceUnlock(*sequence);
|
fFileSystem->OpenOwnerSequenceUnlock(*sequence);
|
||||||
|
|
||||||
if (cookie == NULL) {
|
if (cookie == NULL) {
|
||||||
snooze_etc(sSecToBigTime(leaseTime) / 3, B_SYSTEM_TIMEBASE,
|
snooze_etc(RetryDelay(attempt, leaseTime), B_SYSTEM_TIMEBASE,
|
||||||
B_RELATIVE_TIMEOUT);
|
B_RELATIVE_TIMEOUT);
|
||||||
if (sequence != NULL)
|
if (sequence != NULL)
|
||||||
*sequence = fFileSystem->OpenOwnerSequenceLock();
|
*sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
@@ -91,8 +125,8 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((cookie->fMode & O_NONBLOCK) == 0) {
|
if ((cookie->fMode & O_NONBLOCK) == 0) {
|
||||||
status_t result = acquire_sem_etc(cookie->fSnoozeCancel, 1,
|
result = acquire_sem_etc(cookie->fSnoozeCancel, 1,
|
||||||
B_RELATIVE_TIMEOUT, sSecToBigTime(leaseTime) / 3);
|
B_RELATIVE_TIMEOUT, RetryDelay(attempt, leaseTime));
|
||||||
|
|
||||||
if (sequence != NULL)
|
if (sequence != NULL)
|
||||||
*sequence = fFileSystem->OpenOwnerSequenceLock();
|
*sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
@@ -125,7 +159,6 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// File Handle has expired, is invalid or the node has been deleted
|
// File Handle has expired, is invalid or the node has been deleted
|
||||||
case NFS4ERR_NOFILEHANDLE:
|
|
||||||
case NFS4ERR_BADHANDLE:
|
case NFS4ERR_BADHANDLE:
|
||||||
case NFS4ERR_FHEXPIRED:
|
case NFS4ERR_FHEXPIRED:
|
||||||
case NFS4ERR_STALE:
|
case NFS4ERR_STALE:
|
||||||
@@ -136,7 +169,7 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
|||||||
// filesystem has been moved
|
// filesystem has been moved
|
||||||
case NFS4ERR_LEASE_MOVED:
|
case NFS4ERR_LEASE_MOVED:
|
||||||
case NFS4ERR_MOVED:
|
case NFS4ERR_MOVED:
|
||||||
fFileSystem->Migrate(serv);
|
fFileSystem->Migrate(server);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// lease has expired
|
// lease has expired
|
||||||
@@ -160,6 +193,7 @@ NFS4Object::ConfirmOpen(const FileHandle& fh, OpenState* state,
|
|||||||
ASSERT(state != NULL);
|
ASSERT(state != NULL);
|
||||||
ASSERT(sequence != NULL);
|
ASSERT(sequence != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
Request request(serv, fFileSystem);
|
Request request(serv, fFileSystem);
|
||||||
@@ -177,7 +211,7 @@ NFS4Object::ConfirmOpen(const FileHandle& fh, OpenState* state,
|
|||||||
|
|
||||||
*sequence += IncrementSequence(reply.NFS4Error());
|
*sequence += IncrementSequence(reply.NFS4Error());
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, NULL, state))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, state))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class OpenState;
|
|||||||
|
|
||||||
class NFS4Object {
|
class NFS4Object {
|
||||||
public:
|
public:
|
||||||
bool HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
bool HandleErrors(uint32& attempt, uint32 nfs4Error,
|
||||||
OpenStateCookie* cookie = NULL,
|
RPC::Server* server, OpenStateCookie* cookie = NULL,
|
||||||
OpenState* state = NULL, uint32* sequence = NULL);
|
OpenState* state = NULL, uint32* sequence = NULL);
|
||||||
|
|
||||||
status_t ConfirmOpen(const FileHandle& fileHandle,
|
status_t ConfirmOpen(const FileHandle& fileHandle,
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ OpenState::_ReleaseLockOwner(LockOwner* owner)
|
|||||||
{
|
{
|
||||||
ASSERT(owner != NULL);
|
ASSERT(owner != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* server = fFileSystem->Server();
|
RPC::Server* server = fFileSystem->Server();
|
||||||
Request request(server, fFileSystem);
|
Request request(server, fFileSystem);
|
||||||
@@ -127,7 +128,7 @@ OpenState::_ReleaseLockOwner(LockOwner* owner)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), server))
|
if (HandleErrors(attempt, reply.NFS4Error(), server))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return reply.ReleaseLockOwner();
|
return reply.ReleaseLockOwner();
|
||||||
@@ -166,6 +167,7 @@ OpenState::_ReclaimOpen(uint64 newClientID)
|
|||||||
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
OpenDelegation delegType = fDelegation != NULL ? fDelegation->Type()
|
OpenDelegation delegType = fDelegation != NULL ? fDelegation->Type()
|
||||||
: OPEN_DELEGATE_NONE;
|
: OPEN_DELEGATE_NONE;
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* server = fFileSystem->Server();
|
RPC::Server* server = fFileSystem->Server();
|
||||||
Request request(server, fFileSystem);
|
Request request(server, fFileSystem);
|
||||||
@@ -187,7 +189,8 @@ OpenState::_ReclaimOpen(uint64 newClientID)
|
|||||||
sequence += IncrementSequence(reply.NFS4Error());
|
sequence += IncrementSequence(reply.NFS4Error());
|
||||||
|
|
||||||
if (reply.NFS4Error() != NFS4ERR_STALE_CLIENTID
|
if (reply.NFS4Error() != NFS4ERR_STALE_CLIENTID
|
||||||
&& HandleErrors(reply.NFS4Error(), server, NULL, NULL, &sequence)) {
|
&& HandleErrors(attempt, reply.NFS4Error(), server, NULL, NULL,
|
||||||
|
&sequence)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,6 +236,7 @@ OpenState::_ReclaimLocks(uint64 newClientID)
|
|||||||
linfo->fOwner->fClientId = newClientID;
|
linfo->fOwner->fClientId = newClientID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
do {
|
do {
|
||||||
RPC::Server* server = fFileSystem->Server();
|
RPC::Server* server = fFileSystem->Server();
|
||||||
@@ -254,7 +258,7 @@ OpenState::_ReclaimLocks(uint64 newClientID)
|
|||||||
|
|
||||||
if (reply.NFS4Error() != NFS4ERR_STALE_CLIENTID
|
if (reply.NFS4Error() != NFS4ERR_STALE_CLIENTID
|
||||||
&& reply.NFS4Error() != NFS4ERR_STALE_STATEID
|
&& reply.NFS4Error() != NFS4ERR_STALE_STATEID
|
||||||
&& HandleErrors(reply.NFS4Error(), server, NULL, NULL,
|
&& HandleErrors(attempt, reply.NFS4Error(), server, NULL, NULL,
|
||||||
&sequence)) {
|
&sequence)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -283,6 +287,7 @@ OpenState::Close()
|
|||||||
MutexLocker _(fLock);
|
MutexLocker _(fLock);
|
||||||
fOpened = false;
|
fOpened = false;
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
do {
|
do {
|
||||||
RPC::Server* serv = fFileSystem->Server();
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
@@ -310,8 +315,10 @@ OpenState::Close()
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv, NULL, this, &sequence))
|
if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, this,
|
||||||
|
&sequence)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
fFileSystem->OpenOwnerSequenceUnlock(sequence);
|
fFileSystem->OpenOwnerSequenceUnlock(sequence);
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ RootInode::_UpdateInfo(bool force)
|
|||||||
if (fInfoCacheExpire > time(NULL))
|
if (fInfoCacheExpire > time(NULL))
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* server = fFileSystem->Server();
|
RPC::Server* server = fFileSystem->Server();
|
||||||
Request request(server, fFileSystem);
|
Request request(server, fFileSystem);
|
||||||
@@ -75,7 +76,7 @@ RootInode::_UpdateInfo(bool force)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), server))
|
if (HandleErrors(attempt, reply.NFS4Error(), server))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
@@ -146,6 +147,7 @@ RootInode::_UpdateInfo(bool force)
|
|||||||
bool
|
bool
|
||||||
RootInode::ProbeMigration()
|
RootInode::ProbeMigration()
|
||||||
{
|
{
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* server = fFileSystem->Server();
|
RPC::Server* server = fFileSystem->Server();
|
||||||
Request request(server, fFileSystem);
|
Request request(server, fFileSystem);
|
||||||
@@ -163,7 +165,7 @@ RootInode::ProbeMigration()
|
|||||||
if (reply.NFS4Error() == NFS4ERR_MOVED)
|
if (reply.NFS4Error() == NFS4ERR_MOVED)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), server))
|
if (HandleErrors(attempt, reply.NFS4Error(), server))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -176,6 +178,7 @@ RootInode::GetLocations(AttrValue** attrv)
|
|||||||
{
|
{
|
||||||
ASSERT(attrv != NULL);
|
ASSERT(attrv != NULL);
|
||||||
|
|
||||||
|
uint32 attempt = 0;
|
||||||
do {
|
do {
|
||||||
RPC::Server* server = fFileSystem->Server();
|
RPC::Server* server = fFileSystem->Server();
|
||||||
Request request(server, fFileSystem);
|
Request request(server, fFileSystem);
|
||||||
@@ -191,7 +194,7 @@ RootInode::GetLocations(AttrValue** attrv)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), server))
|
if (HandleErrors(attempt, reply.NFS4Error(), server))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
reply.PutFH();
|
||||||
|
|||||||
Reference in New Issue
Block a user