From e27b9ff74286c8ea666594ea0f6af5207ccca4ee Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Tue, 26 Jun 2012 20:55:53 +0200 Subject: [PATCH] nfs4: Improve handling errors in NFS replies --- .../kernel/file_systems/nfs4/Filesystem.cpp | 25 +-- .../kernel/file_systems/nfs4/Inode.cpp | 157 ++++-------------- .../kernel/file_systems/nfs4/NFS4Server.cpp | 13 +- .../file_systems/nfs4/ReplyInterpreter.cpp | 17 +- .../file_systems/nfs4/ReplyInterpreter.h | 3 + 5 files changed, 62 insertions(+), 153 deletions(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp b/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp index 3a561f05b5..55d91a1433 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp @@ -100,20 +100,13 @@ Filesystem::Mount(Filesystem** pfs, RPC::Server* serv, const char* fsPath, ReplyInterpreter& reply = request.Reply(); - result = reply.PutRootFH(); - if (result != B_OK) - return result; + reply.PutRootFH(); - for (uint32 i = 0; i < lookupCount; i++) { - result = reply.LookUp(); - if (result != B_OK) - return result; - } + for (uint32 i = 0; i < lookupCount; i++) + reply.LookUp(); Filehandle fh; - result = reply.GetFH(&fh); - if (result != B_OK) - return result; + reply.GetFH(&fh); uint32 allowed; result = reply.Access(NULL, &allowed); @@ -224,9 +217,7 @@ Filesystem::ReadInfo(struct fs_info* info) ReplyInterpreter& reply = request.Reply(); - result = reply.PutFH(); - if (result != B_OK) - return result; + reply.PutFH(); AttrValue* values; uint32 count, next = 0; @@ -301,11 +292,7 @@ Filesystem::Migrate(const Filehandle& fh, const RPC::Server* serv) ReplyInterpreter& reply = request.Reply(); - result = reply.PutFH(); - if (result != B_OK) { - mutex_unlock(&fMigrationLock); - return result; - } + reply.PutFH(); AttrValue* values; uint32 count; diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index 1253a3becb..961cfb1f77 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -52,9 +52,7 @@ Inode::CreateInode(Filesystem* fs, const FileInfo &fi, Inode** _inode) if (inode->_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; + reply.PutFH(); AttrValue* values; uint32 count; @@ -133,21 +131,14 @@ Inode::LookUp(const char* name, ino_t* id) if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; - + reply.PutFH(); if (!strcmp(name, "..")) - result = reply.LookUpUp(); + reply.LookUpUp(); else - result = reply.LookUp(); - if (result != B_OK) - return result; + reply.LookUp(); Filehandle fh; - result = reply.GetFH(&fh); - if (result != B_OK) - return result; + reply.GetFH(&fh); AttrValue* values; uint32 count; @@ -225,17 +216,9 @@ Inode::Link(Inode* dir, const char* name) continue; } - result = reply.PutFH(); - if (result != B_OK) - return result; - - result = reply.SaveFH(); - if (result != B_OK) - return result; - - result = reply.PutFH(); - if (result != B_OK) - return result; + reply.PutFH(); + reply.SaveFH(); + reply.PutFH(); return reply.Link(); } while (true); @@ -273,13 +256,8 @@ Inode::Remove(const char* name, FileType type) if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; - - result = reply.LookUp(); - if (result != B_OK) - return result; + reply.PutFH(); + reply.LookUp(); result = reply.Verify(); if (result == NFS4ERR_NOT_SAME && type == NF4REG) @@ -289,10 +267,7 @@ Inode::Remove(const char* name, FileType type) if (result != B_OK) return result; - result = reply.PutFH(); - if (result != B_OK) - return result; - + reply.PutFH(); return reply.Remove(); } while (true); } @@ -338,18 +313,9 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName) continue; } - result = reply.PutFH(); - if (result != B_OK) - return result; - - result = reply.SaveFH(); - if (result != B_OK) - return result; - - result = reply.PutFH(); - if (result != B_OK) - return result; - + reply.PutFH(); + reply.SaveFH(); + reply.PutFH(); return reply.Rename(); } while (true); @@ -381,9 +347,7 @@ Inode::CreateLink(const char* name, const char* path, int mode) if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; + reply.PutFH(); return reply.Create(); } while (true); @@ -413,9 +377,7 @@ Inode::ReadLink(void* buffer, size_t* length) if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; + reply.PutFH(); uint32 size; result = reply.ReadLink(buffer, &size, *length); @@ -446,9 +408,7 @@ Inode::Access(int mode) if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; + reply.PutFH(); uint32 allowed; result = reply.Access(NULL, &allowed); @@ -500,9 +460,7 @@ Inode::Stat(struct stat* st) if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; + reply.PutFH(); AttrValue* values; uint32 count; @@ -530,9 +488,7 @@ Inode::Stat(struct stat* st) result = request.Send(); if (result != B_OK) return result; - result = request.Reply().PutFH(); - if (result != B_OK) - return result; + request.Reply().PutFH(); uint32 prvl; result = request.Reply().Access(NULL, &prvl); if (result != B_OK) @@ -626,11 +582,7 @@ sConfirmOpen(Filesystem* fs, Filehandle& fh, OpenFileCookie* cookie) ReplyInterpreter& reply = request.Reply(); - result = reply.PutFH(); - if (result != B_OK) { - fs->NFSServer()->RemoveOpenFile(cookie); - return result; - } + reply.PutFH(); result = reply.OpenConfirm(&cookie->fStateSeq); if (result != B_OK) { @@ -695,17 +647,9 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie, if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; - - result = reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm); - if (result != B_OK) - return result; - - result = reply.GetFH(&fh); - if (result != B_OK) - return result; + reply.PutFH(); + reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm); + reply.GetFH(&fh); AttrValue* values; uint32 count; @@ -798,10 +742,7 @@ Inode::Open(int mode, OpenFileCookie* cookie) if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; - + reply.PutFH(); result = reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm); if (result != B_OK) return result; @@ -841,10 +782,7 @@ Inode::Close(OpenFileCookie* cookie) if (_HandleErrors(reply.NFS4Error(), serv, cookie)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; - + reply.PutFH(); result = reply.Close(); if (result != B_OK) return result; @@ -884,10 +822,7 @@ Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length) if (_HandleErrors(reply.NFS4Error(), serv, cookie)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; - + reply.PutFH(); result = reply.Read(reinterpret_cast(buffer) + size, &len, &eof); if (result != B_OK) @@ -960,9 +895,7 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer, if (_HandleErrors(reply.NFS4Error(), serv, cookie)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; + reply.PutFH(); if ((cookie->fMode & O_APPEND) == O_APPEND) { result = reply.Verify(); @@ -1009,9 +942,7 @@ Inode::OpenDir(OpenDirCookie* cookie) if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; + reply.PutFH(); uint32 allowed; result = reply.Access(NULL, &allowed); @@ -1054,10 +985,7 @@ Inode::_ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie, if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; - + reply.PutFH(); return reply.ReadDir(&cookie->fCookie, &cookie->fCookieVerf, dirents, count, eof); } while (true); @@ -1109,22 +1037,15 @@ Inode::_ReadDirUp(struct dirent* de, uint32 pos, uint32 size) if (_HandleErrors(reply.NFS4Error(), serv)) continue; - result = reply.PutFH(); - if (result != B_OK) - return result; - - result = reply.LookUpUp(); - if (result != B_OK) - return result; + reply.PutFH(); + reply.LookUpUp(); Filehandle fh; - result = reply.GetFH(&fh); - if (result != B_OK) - return result; + reply.GetFH(&fh); AttrValue* values; uint32 count; - result = reply.GetAttr(&values, &count); + reply.GetAttr(&values, &count); if (result != B_OK) return result; @@ -1314,15 +1235,9 @@ Inode::_LookUpFilehandle() ReplyInterpreter& reply = request.Reply(); - result = reply.PutRootFH(); - if (result != B_OK) - return result; - - for (uint32 i = 0; i < lookupCount; i++) { - result = reply.LookUp(); - if (result != B_OK) - return result; - } + reply.PutRootFH(); + for (uint32 i = 0; i < lookupCount; i++) + reply.LookUp(); return reply.GetFH(&fHandle); } diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp index 2a0d7b1e49..7874a949a9 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp @@ -80,9 +80,7 @@ NFS4Server::_ReclaimOpen(OpenFileCookie* cookie) ReplyInterpreter& reply = request.Reply(); - result = reply.PutFH(); - if (result != B_OK) - return result; + reply.PutFH(); bool confirm; result = reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm); @@ -100,10 +98,7 @@ NFS4Server::_ReclaimOpen(OpenFileCookie* cookie) if (result != B_OK) return result; - result = reply.PutFH(); - if (result != B_OK) - return result; - + reply.PutFH(); result = reply.OpenConfirm(&cookie->fStateSeq); if (result != B_OK) return result; @@ -203,9 +198,7 @@ NFS4Server::_GetLeaseTime() ReplyInterpreter& reply = request.Reply(); - result = reply.PutRootFH(); - if (result != B_OK) - return result; + reply.PutRootFH(); AttrValue* values; uint32 count; diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp index 81359239f1..088a50db98 100644 --- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp @@ -65,6 +65,7 @@ DirEntry::~DirEntry() ReplyInterpreter::ReplyInterpreter(RPC::Reply* reply) : fNFS4Error(NFS4_OK), + fDecodeError(false), fReply(reply) { if (reply != NULL) @@ -618,16 +619,26 @@ ReplyInterpreter::_DecodeAttrs(XDR::ReadStream& str, AttrValue** attrs, status_t ReplyInterpreter::_OperationError(Opcode op) { + if (fDecodeError) + return B_BAD_VALUE; + if (fReply == NULL) 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(); + } - if (fReply->Stream().GetInt() != op) + if (fReply->Stream().GetInt() != op) { + fDecodeError = true; return B_BAD_VALUE; + } - return _NFS4ErrorToHaiku(fReply->Stream().GetUInt()); + status_t result = _NFS4ErrorToHaiku(fReply->Stream().GetUInt()); + if (result != B_OK) + fDecodeError = true; + return result; } diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h index e7c7a566a2..3c54a28769 100644 --- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h +++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h @@ -99,6 +99,7 @@ private: static status_t _NFS4ErrorToHaiku(uint32 x); uint32 fNFS4Error; + bool fDecodeError; RPC::Reply* fReply; }; @@ -109,6 +110,7 @@ ReplyInterpreter::SetTo(RPC::Reply* _reply) if (fReply != NULL) return B_DONT_DO_THAT; + fDecodeError = false; fReply = _reply; if (fReply != NULL) @@ -123,6 +125,7 @@ ReplyInterpreter::Reset() { delete fReply; fReply = NULL; + fDecodeError = false; }