nfs4: Add NFS4 request builder

Currently supports only the following operations: ACCESS, GETATTR, GETFH
LOOKUP and PUTROOTFH.
This commit is contained in:
Pawel Dziepak 2012-05-29 23:39:56 +02:00
parent 4aeb595207
commit d08c284cec
3 changed files with 187 additions and 0 deletions

View File

@ -5,6 +5,7 @@ UsePrivateHeaders kernel ;
KernelAddon nfs4 :
Connection.cpp
kernel_interface.cpp
RequestBuilder.cpp
RPCAuth.cpp
RPCCall.cpp
RPCReply.cpp

View File

@ -0,0 +1,143 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, pdziepak@quarnos.org
*/
#include "RequestBuilder.h"
#include <string.h>
RequestBuilder::RequestBuilder(Procedure proc)
:
fOpCount(0),
fProcedure(proc),
fRequest(RPC::Call::Create(proc, RPC::Auth::CreateSys(),
RPC::Auth::CreateNone()))
{
if (fProcedure == ProcCompound) {
fRequest->Stream().AddOpaque(NULL, 0);
fRequest->Stream().AddUInt(0);
fOpCountPosition = fRequest->Stream().Current();
fRequest->Stream().AddUInt(0);
}
}
RequestBuilder::~RequestBuilder()
{
delete fRequest;
}
status_t
RequestBuilder::Access()
{
if (fProcedure != ProcCompound)
return B_BAD_VALUE;
if (fRequest == NULL)
return B_NO_MEMORY;
fRequest->Stream().AddUInt(OpAccess);
fRequest->Stream().AddUInt(ACCESS4_READ | ACCESS4_LOOKUP | ACCESS4_MODIFY
| ACCESS4_EXTEND | ACCESS4_DELETE
| ACCESS4_EXECUTE);
fOpCount++;
return B_OK;
}
status_t
RequestBuilder::GetAttr(Attribute* attrs, uint32 count)
{
if (fProcedure != ProcCompound)
return B_BAD_VALUE;
if (fRequest == NULL)
return B_NO_MEMORY;
fRequest->Stream().AddUInt(OpGetAttr);
// 2 is safe in NFS4, not in NFS4.1 though
uint32 bitmap[2];
memset(bitmap, 0, sizeof(bitmap));
for (uint32 i = 0; i < count; i++) {
bitmap[(int)attrs[i] / 32] |= 1 << (int)attrs[i] % 32;
}
uint32 bcount = bitmap[1] != 0 ? 2 : 1;
fRequest->Stream().AddUInt(bcount);
for (uint32 i = 0; i < bcount; i++)
fRequest->Stream().AddUInt(bitmap[i]);
fOpCount++;
return B_OK;
}
status_t
RequestBuilder::GetFH()
{
if (fProcedure != ProcCompound)
return B_BAD_VALUE;
if (fRequest == NULL)
return B_NO_MEMORY;
fRequest->Stream().AddUInt(OpGetFH);
fOpCount++;
return B_OK;
}
status_t
RequestBuilder::LookUp(const char* name)
{
if (fProcedure != ProcCompound)
return B_BAD_VALUE;
if (fRequest == NULL)
return B_NO_MEMORY;
if (name == NULL)
return B_BAD_VALUE;
fRequest->Stream().AddUInt(OpLookUp);
fRequest->Stream().AddString(name, strlen(name));
fOpCount++;
return B_OK;
}
status_t
RequestBuilder::PutRootFH()
{
if (fProcedure != ProcCompound)
return B_BAD_VALUE;
if (fRequest == NULL)
return B_NO_MEMORY;
fRequest->Stream().AddUInt(OpPutRootFH);
fOpCount++;
return B_OK;
}
RPC::Call*
RequestBuilder::Request()
{
if (fProcedure == ProcCompound)
fRequest->Stream().InsertUInt(fOpCountPosition, fOpCount);
if (fRequest == NULL || fRequest->Stream().Error() == B_OK)
return fRequest;
else
return NULL;
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, pdziepak@quarnos.org
*/
#ifndef REQUESTBUILDER_H
#define REQUESTBUILDER_H
#include <SupportDefs.h>
#include "NFS4Defs.h"
#include "RPCCall.h"
#include "XDR.h"
class RequestBuilder {
public:
RequestBuilder(Procedure proc);
~RequestBuilder();
status_t Access();
status_t GetAttr(Attribute* attrs, uint32 count);
status_t GetFH();
status_t LookUp(const char* name);
status_t PutRootFH();
RPC::Call* Request();
private:
uint32 fOpCount;
XDR::Stream::Position fOpCountPosition;
Procedure fProcedure;
RPC::Call* fRequest;
};
#endif // REQUESTBUILDER_H