nfs4: Improve handling errors in NFS replies

This commit is contained in:
Pawel Dziepak
2012-06-29 02:15:11 +02:00
parent 07f2e2d2b8
commit e27b9ff742
5 changed files with 62 additions and 153 deletions
@@ -100,20 +100,13 @@ Filesystem::Mount(Filesystem** pfs, RPC::Server* serv, const char* fsPath,
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
result = reply.PutRootFH(); reply.PutRootFH();
if (result != B_OK)
return result;
for (uint32 i = 0; i < lookupCount; i++) { for (uint32 i = 0; i < lookupCount; i++)
result = reply.LookUp(); reply.LookUp();
if (result != B_OK)
return result;
}
Filehandle fh; Filehandle fh;
result = reply.GetFH(&fh); reply.GetFH(&fh);
if (result != B_OK)
return result;
uint32 allowed; uint32 allowed;
result = reply.Access(NULL, &allowed); result = reply.Access(NULL, &allowed);
@@ -224,9 +217,7 @@ Filesystem::ReadInfo(struct fs_info* info)
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
AttrValue* values; AttrValue* values;
uint32 count, next = 0; uint32 count, next = 0;
@@ -301,11 +292,7 @@ Filesystem::Migrate(const Filehandle& fh, const RPC::Server* serv)
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
result = reply.PutFH(); reply.PutFH();
if (result != B_OK) {
mutex_unlock(&fMigrationLock);
return result;
}
AttrValue* values; AttrValue* values;
uint32 count; uint32 count;
+36 -121
View File
@@ -52,9 +52,7 @@ Inode::CreateInode(Filesystem* fs, const FileInfo &fi, Inode** _inode)
if (inode->_HandleErrors(reply.NFS4Error(), serv)) if (inode->_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
AttrValue* values; AttrValue* values;
uint32 count; uint32 count;
@@ -133,21 +131,14 @@ Inode::LookUp(const char* name, ino_t* id)
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
if (!strcmp(name, "..")) if (!strcmp(name, ".."))
result = reply.LookUpUp(); reply.LookUpUp();
else else
result = reply.LookUp(); reply.LookUp();
if (result != B_OK)
return result;
Filehandle fh; Filehandle fh;
result = reply.GetFH(&fh); reply.GetFH(&fh);
if (result != B_OK)
return result;
AttrValue* values; AttrValue* values;
uint32 count; uint32 count;
@@ -225,17 +216,9 @@ Inode::Link(Inode* dir, const char* name)
continue; continue;
} }
result = reply.PutFH(); reply.PutFH();
if (result != B_OK) reply.SaveFH();
return result; reply.PutFH();
result = reply.SaveFH();
if (result != B_OK)
return result;
result = reply.PutFH();
if (result != B_OK)
return result;
return reply.Link(); return reply.Link();
} while (true); } while (true);
@@ -273,13 +256,8 @@ Inode::Remove(const char* name, FileType type)
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK) reply.LookUp();
return result;
result = reply.LookUp();
if (result != B_OK)
return result;
result = reply.Verify(); result = reply.Verify();
if (result == NFS4ERR_NOT_SAME && type == NF4REG) if (result == NFS4ERR_NOT_SAME && type == NF4REG)
@@ -289,10 +267,7 @@ Inode::Remove(const char* name, FileType type)
if (result != B_OK) if (result != B_OK)
return result; return result;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
return reply.Remove(); return reply.Remove();
} while (true); } while (true);
} }
@@ -338,18 +313,9 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName)
continue; continue;
} }
result = reply.PutFH(); reply.PutFH();
if (result != B_OK) reply.SaveFH();
return result; reply.PutFH();
result = reply.SaveFH();
if (result != B_OK)
return result;
result = reply.PutFH();
if (result != B_OK)
return result;
return reply.Rename(); return reply.Rename();
} while (true); } while (true);
@@ -381,9 +347,7 @@ Inode::CreateLink(const char* name, const char* path, int mode)
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
return reply.Create(); return reply.Create();
} while (true); } while (true);
@@ -413,9 +377,7 @@ Inode::ReadLink(void* buffer, size_t* length)
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
uint32 size; uint32 size;
result = reply.ReadLink(buffer, &size, *length); result = reply.ReadLink(buffer, &size, *length);
@@ -446,9 +408,7 @@ Inode::Access(int mode)
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
uint32 allowed; uint32 allowed;
result = reply.Access(NULL, &allowed); result = reply.Access(NULL, &allowed);
@@ -500,9 +460,7 @@ Inode::Stat(struct stat* st)
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
AttrValue* values; AttrValue* values;
uint32 count; uint32 count;
@@ -530,9 +488,7 @@ Inode::Stat(struct stat* st)
result = request.Send(); result = request.Send();
if (result != B_OK) if (result != B_OK)
return result; return result;
result = request.Reply().PutFH(); request.Reply().PutFH();
if (result != B_OK)
return result;
uint32 prvl; uint32 prvl;
result = request.Reply().Access(NULL, &prvl); result = request.Reply().Access(NULL, &prvl);
if (result != B_OK) if (result != B_OK)
@@ -626,11 +582,7 @@ sConfirmOpen(Filesystem* fs, Filehandle& fh, OpenFileCookie* cookie)
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
result = reply.PutFH(); reply.PutFH();
if (result != B_OK) {
fs->NFSServer()->RemoveOpenFile(cookie);
return result;
}
result = reply.OpenConfirm(&cookie->fStateSeq); result = reply.OpenConfirm(&cookie->fStateSeq);
if (result != B_OK) { if (result != B_OK) {
@@ -695,17 +647,9 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK) reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm);
return result; reply.GetFH(&fh);
result = reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm);
if (result != B_OK)
return result;
result = reply.GetFH(&fh);
if (result != B_OK)
return result;
AttrValue* values; AttrValue* values;
uint32 count; uint32 count;
@@ -798,10 +742,7 @@ Inode::Open(int mode, OpenFileCookie* cookie)
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
result = reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm); result = reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm);
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -841,10 +782,7 @@ Inode::Close(OpenFileCookie* cookie)
if (_HandleErrors(reply.NFS4Error(), serv, cookie)) if (_HandleErrors(reply.NFS4Error(), serv, cookie))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
result = reply.Close(); result = reply.Close();
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -884,10 +822,7 @@ Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length)
if (_HandleErrors(reply.NFS4Error(), serv, cookie)) if (_HandleErrors(reply.NFS4Error(), serv, cookie))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
result = reply.Read(reinterpret_cast<char*>(buffer) + size, &len, result = reply.Read(reinterpret_cast<char*>(buffer) + size, &len,
&eof); &eof);
if (result != B_OK) if (result != B_OK)
@@ -960,9 +895,7 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
if (_HandleErrors(reply.NFS4Error(), serv, cookie)) if (_HandleErrors(reply.NFS4Error(), serv, cookie))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
if ((cookie->fMode & O_APPEND) == O_APPEND) { if ((cookie->fMode & O_APPEND) == O_APPEND) {
result = reply.Verify(); result = reply.Verify();
@@ -1009,9 +942,7 @@ Inode::OpenDir(OpenDirCookie* cookie)
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
uint32 allowed; uint32 allowed;
result = reply.Access(NULL, &allowed); result = reply.Access(NULL, &allowed);
@@ -1054,10 +985,7 @@ Inode::_ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie,
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
return reply.ReadDir(&cookie->fCookie, &cookie->fCookieVerf, dirents, return reply.ReadDir(&cookie->fCookie, &cookie->fCookieVerf, dirents,
count, eof); count, eof);
} while (true); } while (true);
@@ -1109,22 +1037,15 @@ Inode::_ReadDirUp(struct dirent* de, uint32 pos, uint32 size)
if (_HandleErrors(reply.NFS4Error(), serv)) if (_HandleErrors(reply.NFS4Error(), serv))
continue; continue;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK) reply.LookUpUp();
return result;
result = reply.LookUpUp();
if (result != B_OK)
return result;
Filehandle fh; Filehandle fh;
result = reply.GetFH(&fh); reply.GetFH(&fh);
if (result != B_OK)
return result;
AttrValue* values; AttrValue* values;
uint32 count; uint32 count;
result = reply.GetAttr(&values, &count); reply.GetAttr(&values, &count);
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -1314,15 +1235,9 @@ Inode::_LookUpFilehandle()
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
result = reply.PutRootFH(); reply.PutRootFH();
if (result != B_OK) for (uint32 i = 0; i < lookupCount; i++)
return result; reply.LookUp();
for (uint32 i = 0; i < lookupCount; i++) {
result = reply.LookUp();
if (result != B_OK)
return result;
}
return reply.GetFH(&fHandle); return reply.GetFH(&fHandle);
} }
@@ -80,9 +80,7 @@ NFS4Server::_ReclaimOpen(OpenFileCookie* cookie)
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
bool confirm; bool confirm;
result = reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm); result = reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm);
@@ -100,10 +98,7 @@ NFS4Server::_ReclaimOpen(OpenFileCookie* cookie)
if (result != B_OK) if (result != B_OK)
return result; return result;
result = reply.PutFH(); reply.PutFH();
if (result != B_OK)
return result;
result = reply.OpenConfirm(&cookie->fStateSeq); result = reply.OpenConfirm(&cookie->fStateSeq);
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -203,9 +198,7 @@ NFS4Server::_GetLeaseTime()
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
result = reply.PutRootFH(); reply.PutRootFH();
if (result != B_OK)
return result;
AttrValue* values; AttrValue* values;
uint32 count; uint32 count;
@@ -65,6 +65,7 @@ DirEntry::~DirEntry()
ReplyInterpreter::ReplyInterpreter(RPC::Reply* reply) ReplyInterpreter::ReplyInterpreter(RPC::Reply* reply)
: :
fNFS4Error(NFS4_OK), fNFS4Error(NFS4_OK),
fDecodeError(false),
fReply(reply) fReply(reply)
{ {
if (reply != NULL) if (reply != NULL)
@@ -618,16 +619,26 @@ ReplyInterpreter::_DecodeAttrs(XDR::ReadStream& str, AttrValue** attrs,
status_t status_t
ReplyInterpreter::_OperationError(Opcode op) ReplyInterpreter::_OperationError(Opcode op)
{ {
if (fDecodeError)
return B_BAD_VALUE;
if (fReply == NULL) if (fReply == NULL)
return B_NOT_INITIALIZED; return B_NOT_INITIALIZED;
if (fReply->Error() != B_OK || fReply->Stream().IsEOF()) if (fReply->Error() != B_OK || fReply->Stream().IsEOF()) {
fDecodeError = true;
return fReply->Error(); return fReply->Error();
}
if (fReply->Stream().GetInt() != op) if (fReply->Stream().GetInt() != op) {
fDecodeError = true;
return B_BAD_VALUE; return B_BAD_VALUE;
}
return _NFS4ErrorToHaiku(fReply->Stream().GetUInt()); status_t result = _NFS4ErrorToHaiku(fReply->Stream().GetUInt());
if (result != B_OK)
fDecodeError = true;
return result;
} }
@@ -99,6 +99,7 @@ private:
static status_t _NFS4ErrorToHaiku(uint32 x); static status_t _NFS4ErrorToHaiku(uint32 x);
uint32 fNFS4Error; uint32 fNFS4Error;
bool fDecodeError;
RPC::Reply* fReply; RPC::Reply* fReply;
}; };
@@ -109,6 +110,7 @@ ReplyInterpreter::SetTo(RPC::Reply* _reply)
if (fReply != NULL) if (fReply != NULL)
return B_DONT_DO_THAT; return B_DONT_DO_THAT;
fDecodeError = false;
fReply = _reply; fReply = _reply;
if (fReply != NULL) if (fReply != NULL)
@@ -123,6 +125,7 @@ ReplyInterpreter::Reset()
{ {
delete fReply; delete fReply;
fReply = NULL; fReply = NULL;
fDecodeError = false;
} }