diff --git a/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp b/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp index aa9748c42c..6502c0f2f5 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp @@ -11,8 +11,7 @@ #include -#include "ReplyInterpreter.h" -#include "RequestBuilder.h" +#include "Request.h" #include "Inode.h" @@ -33,7 +32,9 @@ status_t Filesystem::Mount(Filesystem** pfs, RPC::Server* serv, const char* fsPath, dev_t id) { - RequestBuilder req(ProcCompound); + Request request(serv); + RequestBuilder& req = request.Builder(); + req.PutRootFH(); // Better way of doing this will be needed @@ -62,11 +63,11 @@ Filesystem::Mount(Filesystem** pfs, RPC::Server* serv, const char* fsPath, Attribute attr[] = { FATTR4_FH_EXPIRE_TYPE }; req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); - RPC::Reply *rpl; - serv->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + status_t result = request.Send(); + if (result != B_OK) + return result; - status_t result; + ReplyInterpreter& reply = request.Reply(); result = reply.PutRootFH(); if (result != B_OK) diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index 4b0981f067..a7e92285f7 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -12,8 +12,7 @@ #include #include -#include "ReplyInterpreter.h" -#include "RequestBuilder.h" +#include "Request.h" // Creating Inode object from Filehandle probably is not a good idea when @@ -25,17 +24,20 @@ Inode::Inode(Filesystem* fs, const FileInfo &fi) fParentFH(fi.fParent), fName(strdup(fi.fName)) { - RequestBuilder req(ProcCompound); + Request request(fFilesystem->Server()); + RequestBuilder& req = request.Builder(); + req.PutFH(fHandle); Attribute attr[] = { FATTR4_TYPE, FATTR4_FILEID }; req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); - RPC::Reply *rpl; - fs->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + status_t result = request.Send(); + if (result != B_OK) + return; + + ReplyInterpreter& reply = request.Reply(); - status_t result; result = reply.PutFH(); if (result != B_OK) return; @@ -79,7 +81,9 @@ Inode::LookUp(const char* name, ino_t* id) return B_OK; } - RequestBuilder req(ProcCompound); + Request request(fFilesystem->Server()); + RequestBuilder& req = request.Builder(); + req.PutFH(fHandle); if (!strcmp(name, "..")) @@ -92,11 +96,13 @@ Inode::LookUp(const char* name, ino_t* id) Attribute attr[] = { FATTR4_FILEID }; req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); - RPC::Reply *rpl; - fFilesystem->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + status_t result = request.Send(); + if (result != B_OK) + return result; - status_t result = reply.PutFH(); + ReplyInterpreter& reply = request.Reply(); + + result = reply.PutFH(); if (result != B_OK) return result; @@ -135,15 +141,18 @@ Inode::LookUp(const char* name, ino_t* id) status_t Inode::Access(int mode) { - RequestBuilder req(ProcCompound); + Request request(fFilesystem->Server()); + RequestBuilder& req = request.Builder(); + req.PutFH(fHandle); req.Access(); - RPC::Reply *rpl; - fFilesystem->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + status_t result = request.Send(); + if (result != B_OK) + return result; + + ReplyInterpreter& reply = request.Reply(); - status_t result; result = reply.PutFH(); if (result != B_OK) return result; @@ -176,17 +185,20 @@ Inode::Access(int mode) status_t Inode::Stat(struct stat* st) { - RequestBuilder req(ProcCompound); + Request request(fFilesystem->Server()); + RequestBuilder& req = request.Builder(); + req.PutFH(fHandle); Attribute attr[] = { FATTR4_SIZE, FATTR4_MODE, FATTR4_NUMLINKS }; req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); - RPC::Reply *rpl; - fFilesystem->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + status_t result = request.Send(); + if (result != B_OK) + return result; + + ReplyInterpreter& reply = request.Reply(); - status_t result; result = reply.PutFH(); if (result != B_OK) return result; @@ -231,34 +243,41 @@ Inode::Open(int mode, OpenFileCookie* cookie) { cookie->fSeq = 0; - RequestBuilder req_setid(ProcCompound); - req_setid.SetClientID(fFilesystem->Server()); + Request request(fFilesystem->Server()); + request.Builder().SetClientID(fFilesystem->Server()); - RPC::Reply *rpl; - fFilesystem->Server()->SendCall(req_setid.Request(), &rpl); - ReplyInterpreter setid(rpl); + status_t result = request.Send(); + if (result != B_OK) + return result; uint64 id, ver; - status_t result = setid.SetClientID(&id, &ver); + result = request.Reply().SetClientID(&id, &ver); if (result != B_OK) return result; - RequestBuilder req_conf(ProcCompound); - req_conf.SetClientIDConfirm(id, ver); + request.Reset(); + request.Builder().SetClientIDConfirm(id, ver); - fFilesystem->Server()->SendCall(req_conf.Request(), &rpl); - ReplyInterpreter conf(rpl); - - result = conf.SetClientIDConfirm(); + result = request.Send(); if (result != B_OK) return result; - RequestBuilder req(ProcCompound); + result = request.Reply().SetClientIDConfirm(); + if (result != B_OK) + return result; + + request.Reset(); + RequestBuilder& req = request.Builder(); + req.PutFH(fParentFH); req.Open(cookie->fSeq, OPEN4_SHARE_ACCESS_READ, id, OPEN4_NOCREATE, fName); cookie->fSeq++; - fFilesystem->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + + result = request.Send(); + if (result != B_OK) + return result; + + ReplyInterpreter& reply = request.Reply(); result = reply.PutFH(); if (result != B_OK) @@ -270,12 +289,14 @@ Inode::Open(int mode, OpenFileCookie* cookie) return result; if (confirm) { - RequestBuilder req(ProcCompound); + request.Reset(); req.PutFH(fHandle); req.OpenConfirm(cookie->fSeq, cookie->fStateId, cookie->fStateSeq); cookie->fSeq++; - fFilesystem->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + + result = request.Send(); + if (result != B_OK) + return result; result = reply.PutFH(); if (result != B_OK) @@ -293,15 +314,18 @@ Inode::Open(int mode, OpenFileCookie* cookie) status_t Inode::Close(OpenFileCookie* cookie) { - RequestBuilder req(ProcCompound); + Request request(fFilesystem->Server()); + RequestBuilder& req = request.Builder(); + req.PutFH(fHandle); req.Close(cookie->fSeq, cookie->fStateId, cookie->fStateSeq); - RPC::Reply *rpl; - fFilesystem->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + status_t result = request.Send(); + if (result != B_OK) + return result; + + ReplyInterpreter& reply = request.Reply(); - status_t result; result = reply.PutFH(); if (result != B_OK) return result; @@ -322,16 +346,19 @@ Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length) uint32 len = 0; while (size < *_length && !eof) { - RequestBuilder req(ProcCompound); + Request request(fFilesystem->Server()); + RequestBuilder& req = request.Builder(); + req.PutFH(fHandle); req.Read(cookie->fStateId, cookie->fStateSeq, pos + size, *_length - size); - RPC::Reply *rpl; - fFilesystem->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + status_t result = request.Send(); + if (result != B_OK) + return result; + + ReplyInterpreter& reply = request.Reply(); - status_t result; result = reply.PutFH(); if (result != B_OK) return result; @@ -355,15 +382,18 @@ Inode::OpenDir(uint64* cookie) if (fType != NF4DIR) return B_NOT_A_DIRECTORY; - RequestBuilder req(ProcCompound); + Request request(fFilesystem->Server()); + RequestBuilder& req = request.Builder(); + req.PutFH(fHandle); req.Access(); - RPC::Reply *rpl; - fFilesystem->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + status_t result = request.Send(); + if (result != B_OK) + return result; + + ReplyInterpreter& reply = request.Reply(); - status_t result; result = reply.PutFH(); if (result != B_OK) return result; @@ -387,17 +417,20 @@ status_t Inode::_ReadDirOnce(DirEntry** dirents, uint32* count, uint64* cookie, bool* eof) { - RequestBuilder req(ProcCompound); + Request request(fFilesystem->Server()); + RequestBuilder& req = request.Builder(); + req.PutFH(fHandle); Attribute attr[] = { FATTR4_FILEID }; req.ReadDir(*count, cookie, attr, sizeof(attr) / sizeof(Attribute)); - RPC::Reply *rpl; - fFilesystem->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + status_t result = request.Send(); + if (result != B_OK) + return result; + + ReplyInterpreter& reply = request.Reply(); - status_t result; result = reply.PutFH(); if (result != B_OK) return result; @@ -431,18 +464,21 @@ Inode::_FillDirEntry(struct dirent* de, ino_t id, const char* name, uint32 pos, status_t Inode::_ReadDirUp(struct dirent* de, uint32 pos, uint32 size) { - RequestBuilder req(ProcCompound); + Request request(fFilesystem->Server()); + RequestBuilder& req = request.Builder(); + req.PutFH(fHandle); req.LookUpUp(); req.GetFH(); Attribute attr[] = { FATTR4_FILEID }; req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); - RPC::Reply *rpl; - fFilesystem->Server()->SendCall(req.Request(), &rpl); - ReplyInterpreter reply(rpl); + status_t result = request.Send(); + if (result != B_OK) + return result; + + ReplyInterpreter& reply = request.Reply(); - status_t result; result = reply.PutFH(); if (result != B_OK) return result; diff --git a/src/add-ons/kernel/file_systems/nfs4/Jamfile b/src/add-ons/kernel/file_systems/nfs4/Jamfile index 81f3f46b8a..e1b56c1186 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Jamfile +++ b/src/add-ons/kernel/file_systems/nfs4/Jamfile @@ -8,6 +8,7 @@ KernelAddon nfs4 : Inode.cpp kernel_interface.cpp ReplyInterpreter.cpp + Request.cpp RequestBuilder.cpp RPCAuth.cpp RPCCall.cpp diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp index fc020c0f81..5782247493 100644 --- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp @@ -34,9 +34,8 @@ ReplyInterpreter::ReplyInterpreter(RPC::Reply* reply) : fReply(reply) { - fReply->Stream().GetUInt(); - fReply->Stream().GetOpaque(NULL); - fReply->Stream().GetUInt(); + if (reply != NULL) + _ParseHeader(); } @@ -46,6 +45,15 @@ ReplyInterpreter::~ReplyInterpreter() } +void +ReplyInterpreter::_ParseHeader() +{ + fReply->Stream().GetUInt(); + fReply->Stream().GetOpaque(NULL); + fReply->Stream().GetUInt(); +} + + status_t ReplyInterpreter::Access(uint32* supported, uint32* allowed) { @@ -330,6 +338,9 @@ ReplyInterpreter::_DecodeAttrs(XDR::ReadStream& str, AttrValue** attrs, status_t ReplyInterpreter::_OperationError(Opcode op) { + if (fReply == NULL) + return B_NOT_INITIALIZED; + if (fReply->Error() != B_OK || fReply->Stream().IsEOF()) return fReply->Error(); diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h index 594e45b3fd..e0c56f6297 100644 --- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h +++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h @@ -35,9 +35,12 @@ struct DirEntry { class ReplyInterpreter { public: - ReplyInterpreter(RPC::Reply* reply); + ReplyInterpreter(RPC::Reply* reply = NULL); ~ReplyInterpreter(); + inline status_t SetTo(RPC::Reply* reply); + inline void Reset(); + status_t Access(uint32* supported, uint32* allowed); status_t Close(); status_t GetAttr(AttrValue** attrs, uint32* count); @@ -55,6 +58,8 @@ public: inline status_t SetClientIDConfirm(); private: + void _ParseHeader(); + status_t _DecodeAttrs(XDR::ReadStream& stream, AttrValue** attrs, uint32* count); status_t _OperationError(Opcode op); @@ -65,6 +70,29 @@ private: }; +inline status_t +ReplyInterpreter::SetTo(RPC::Reply* _reply) +{ + if (fReply != NULL) + return B_DONT_DO_THAT; + + fReply = _reply; + + if (fReply != NULL) + _ParseHeader(); + + return B_OK; +} + + +inline void +ReplyInterpreter::Reset() +{ + delete fReply; + fReply = NULL; +} + + inline status_t ReplyInterpreter::LookUp() { diff --git a/src/add-ons/kernel/file_systems/nfs4/Request.cpp b/src/add-ons/kernel/file_systems/nfs4/Request.cpp new file mode 100644 index 0000000000..83760ba01f --- /dev/null +++ b/src/add-ons/kernel/file_systems/nfs4/Request.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ + + +#include "Request.h" + + +status_t +Request::Send() +{ + RPC::Reply *rpl; + status_t result = fServer->SendCall(fBuilder.Request(), &rpl); + if (result != B_OK) + return result; + + return fReply.SetTo(rpl); +} + + +void +Request::Reset() +{ + fBuilder.Reset(); + fReply.Reset(); +} + diff --git a/src/add-ons/kernel/file_systems/nfs4/Request.h b/src/add-ons/kernel/file_systems/nfs4/Request.h new file mode 100644 index 0000000000..3db4e42e10 --- /dev/null +++ b/src/add-ons/kernel/file_systems/nfs4/Request.h @@ -0,0 +1,58 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ +#ifndef REQUEST_H +#define REQUEST_H + + +#include "ReplyInterpreter.h" +#include "RequestBuilder.h" +#include "RPCServer.h" + + +class Request { +public: + inline Request(RPC::Server* serv); + + inline RequestBuilder& Builder(); + inline ReplyInterpreter& Reply(); + + status_t Send(); + void Reset(); + +private: + RPC::Server* fServer; + + RequestBuilder fBuilder; + ReplyInterpreter fReply; +}; + + +inline +Request::Request(RPC::Server* serv) + : + fServer(serv) +{ +} + + +inline RequestBuilder& +Request::Builder() +{ + return fBuilder; +} + + +inline ReplyInterpreter& +Request::Reply() +{ + return fReply; +} + + +#endif // REQUEST_H + diff --git a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp index 578605140e..414322fd3a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp @@ -16,9 +16,27 @@ RequestBuilder::RequestBuilder(Procedure proc) : fOpCount(0), fProcedure(proc), - fRequest(RPC::Call::Create(proc, RPC::Auth::CreateSys(), - RPC::Auth::CreateNone())) + fRequest(NULL) { + _InitHeader(); +} + + +RequestBuilder::~RequestBuilder() +{ + delete fRequest; +} + + +void +RequestBuilder::_InitHeader() +{ + fRequest = RPC::Call::Create(fProcedure, RPC::Auth::CreateSys(), + RPC::Auth::CreateNone()); + + if (fRequest == NULL) + return; + if (fProcedure == ProcCompound) { fRequest->Stream().AddOpaque(NULL, 0); fRequest->Stream().AddUInt(0); @@ -29,12 +47,6 @@ RequestBuilder::RequestBuilder(Procedure proc) } -RequestBuilder::~RequestBuilder() -{ - delete fRequest; -} - - status_t RequestBuilder::Access() { diff --git a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h index 2e8be8c0cf..86f5070e71 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h +++ b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h @@ -19,9 +19,11 @@ class RequestBuilder { public: - RequestBuilder(Procedure proc); + RequestBuilder(Procedure p = ProcCompound); ~RequestBuilder(); + inline void Reset(Procedure proc = ProcCompound); + status_t Access(); status_t Close(uint32 seq, const uint32* id, uint32 stateSeq); @@ -45,6 +47,8 @@ public: RPC::Call* Request(); private: + void _InitHeader(); + void _AttrBitmap(XDR::WriteStream& stream, Attribute* attrs, uint32 count); @@ -57,5 +61,17 @@ private: }; +inline void +RequestBuilder::Reset(Procedure proc) +{ + fRequest->Stream().Clear(); + fOpCount = 0; + fProcedure = proc; + delete fRequest; + + _InitHeader(); +} + + #endif // REQUESTBUILDER_H diff --git a/src/add-ons/kernel/file_systems/nfs4/XDR.cpp b/src/add-ons/kernel/file_systems/nfs4/XDR.cpp index 6d6dd0d90e..73455c99b0 100644 --- a/src/add-ons/kernel/file_systems/nfs4/XDR.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/XDR.cpp @@ -190,6 +190,17 @@ WriteStream::~WriteStream() } +void +WriteStream::Clear() +{ + free(fBuffer); + fSize = kInitialSize; + fBuffer = reinterpret_cast(malloc(fSize)); + fError = B_OK; + fPosition = 0; +} + + status_t WriteStream::InsertUInt(Stream::Position pos, uint32 x) { diff --git a/src/add-ons/kernel/file_systems/nfs4/XDR.h b/src/add-ons/kernel/file_systems/nfs4/XDR.h index 00cfce3a9e..6f9aee292b 100644 --- a/src/add-ons/kernel/file_systems/nfs4/XDR.h +++ b/src/add-ons/kernel/file_systems/nfs4/XDR.h @@ -65,6 +65,7 @@ public: virtual ~WriteStream(); inline int Size() const; + void Clear(); status_t InsertUInt(Stream::Position pos, uint32 x);