nfs4: Add read() hook

This commit is contained in:
Pawel Dziepak 2012-06-05 22:56:33 +02:00
parent 2a292557d4
commit 2f2e57d035
8 changed files with 90 additions and 1 deletions

View File

@ -249,6 +249,41 @@ Inode::Open(int mode, OpenFileCookie* cookie)
}
status_t
Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length)
{
bool eof = false;
uint32 size = 0;
uint32 len = 0;
while (size < *_length && !eof) {
RequestBuilder req(ProcCompound);
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;
result = reply.PutFH();
if (result != B_OK)
return result;
result = reply.Read(reinterpret_cast<char*>(buffer) + size, &len, &eof);
if (result != B_OK)
return result;
size += len;
}
*_length = size;
return B_OK;
}
status_t
Inode::OpenDir(uint64* cookie)
{

View File

@ -37,6 +37,8 @@ public:
status_t Stat(struct stat* st);
status_t Open(int mode, OpenFileCookie* cookie);
status_t Read(OpenFileCookie* cookie, off_t pos,
void* buffer, size_t* length);
status_t OpenDir(uint64* cookie);
status_t ReadDir(void* buffer, uint32 size,

View File

@ -30,6 +30,7 @@ enum Opcode {
OpOpenConfirm = 20,
OpPutFH = 22,
OpPutRootFH = 24,
OpRead = 25,
OpReadDir = 26,
OpSetClientID = 35,
OpSetClientIDConfirm = 36

View File

@ -164,6 +164,21 @@ ReplyInterpreter::OpenConfirm(uint32* stateSeq)
}
status_t
ReplyInterpreter::Read(void* buffer, uint32* size, bool* eof)
{
status_t res = _OperationError(OpRead);
if (res != B_OK)
return res;
*eof = fReply->Stream().GetBoolean();
const void* ptr = fReply->Stream().GetOpaque(size);
memcpy(buffer, ptr, *size);
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
}
status_t
ReplyInterpreter::ReadDir(uint64* cookie, DirEntry** dirents, uint32* _count,
bool* eof)

View File

@ -47,6 +47,7 @@ public:
status_t OpenConfirm(uint32* stateSeq);
inline status_t PutFH();
inline status_t PutRootFH();
status_t Read(void* buffer, uint32* size, bool* eof);
status_t ReadDir(uint64* cookie, DirEntry** dirents,
uint32* count, bool* eof);
status_t SetClientID(uint64* clientid, uint64* verifier);

View File

@ -205,6 +205,28 @@ RequestBuilder::PutRootFH()
}
status_t
RequestBuilder::Read(const uint32* id, uint32 stateSeq, uint64 pos, uint32 len)
{
if (fProcedure != ProcCompound)
return B_BAD_VALUE;
if (fRequest == NULL)
return B_NO_MEMORY;
fRequest->Stream().AddUInt(OpRead);
fRequest->Stream().AddUInt(stateSeq);
fRequest->Stream().AddUInt(id[0]);
fRequest->Stream().AddUInt(id[1]);
fRequest->Stream().AddUInt(id[2]);
fRequest->Stream().AddUHyper(pos);
fRequest->Stream().AddUInt(len);
fOpCount++;
return B_OK;
}
status_t
RequestBuilder::ReadDir(uint32 count, uint64* cookie, Attribute* attrs,
uint32 attr_count)

View File

@ -33,6 +33,8 @@ public:
uint32 stateSeq);
status_t PutFH(const Filehandle& fh);
status_t PutRootFH();
status_t Read(const uint32* id, uint32 stateSeq,
uint64 pos, uint32 len);
status_t ReadDir(uint32 count, uint64* cookie,
Attribute* attrs, uint32 attr_count);
status_t SetClientID(const RPC::Server* serv);

View File

@ -156,6 +156,17 @@ nfs4_open(fs_volume* volume, fs_vnode* vnode, int openMode, void** _cookie)
}
status_t
nfs4_read(fs_volume* volume, fs_vnode* vnode, void* _cookie, off_t pos,
void* buffer, size_t* length)
{
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
return inode->Read(cookie, pos, buffer, length);
}
static status_t
nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie)
{
@ -299,7 +310,7 @@ fs_vnode_ops gNFSv4VnodeOps = {
nfs4_open,
NULL, // close()
NULL, // free_cookie()
NULL, // read()
nfs4_read,
NULL, // write,
/* directory operations */