nfs4: Add read() hook
This commit is contained in:
@@ -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
|
status_t
|
||||||
Inode::OpenDir(uint64* cookie)
|
Inode::OpenDir(uint64* cookie)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ public:
|
|||||||
status_t Stat(struct stat* st);
|
status_t Stat(struct stat* st);
|
||||||
|
|
||||||
status_t Open(int mode, OpenFileCookie* cookie);
|
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 OpenDir(uint64* cookie);
|
||||||
status_t ReadDir(void* buffer, uint32 size,
|
status_t ReadDir(void* buffer, uint32 size,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ enum Opcode {
|
|||||||
OpOpenConfirm = 20,
|
OpOpenConfirm = 20,
|
||||||
OpPutFH = 22,
|
OpPutFH = 22,
|
||||||
OpPutRootFH = 24,
|
OpPutRootFH = 24,
|
||||||
|
OpRead = 25,
|
||||||
OpReadDir = 26,
|
OpReadDir = 26,
|
||||||
OpSetClientID = 35,
|
OpSetClientID = 35,
|
||||||
OpSetClientIDConfirm = 36
|
OpSetClientIDConfirm = 36
|
||||||
|
|||||||
@@ -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
|
status_t
|
||||||
ReplyInterpreter::ReadDir(uint64* cookie, DirEntry** dirents, uint32* _count,
|
ReplyInterpreter::ReadDir(uint64* cookie, DirEntry** dirents, uint32* _count,
|
||||||
bool* eof)
|
bool* eof)
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ public:
|
|||||||
status_t OpenConfirm(uint32* stateSeq);
|
status_t OpenConfirm(uint32* stateSeq);
|
||||||
inline status_t PutFH();
|
inline status_t PutFH();
|
||||||
inline status_t PutRootFH();
|
inline status_t PutRootFH();
|
||||||
|
status_t Read(void* buffer, uint32* size, bool* eof);
|
||||||
status_t ReadDir(uint64* cookie, DirEntry** dirents,
|
status_t ReadDir(uint64* cookie, DirEntry** dirents,
|
||||||
uint32* count, bool* eof);
|
uint32* count, bool* eof);
|
||||||
status_t SetClientID(uint64* clientid, uint64* verifier);
|
status_t SetClientID(uint64* clientid, uint64* verifier);
|
||||||
|
|||||||
@@ -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
|
status_t
|
||||||
RequestBuilder::ReadDir(uint32 count, uint64* cookie, Attribute* attrs,
|
RequestBuilder::ReadDir(uint32 count, uint64* cookie, Attribute* attrs,
|
||||||
uint32 attr_count)
|
uint32 attr_count)
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public:
|
|||||||
uint32 stateSeq);
|
uint32 stateSeq);
|
||||||
status_t PutFH(const Filehandle& fh);
|
status_t PutFH(const Filehandle& fh);
|
||||||
status_t PutRootFH();
|
status_t PutRootFH();
|
||||||
|
status_t Read(const uint32* id, uint32 stateSeq,
|
||||||
|
uint64 pos, uint32 len);
|
||||||
status_t ReadDir(uint32 count, uint64* cookie,
|
status_t ReadDir(uint32 count, uint64* cookie,
|
||||||
Attribute* attrs, uint32 attr_count);
|
Attribute* attrs, uint32 attr_count);
|
||||||
status_t SetClientID(const RPC::Server* serv);
|
status_t SetClientID(const RPC::Server* serv);
|
||||||
|
|||||||
@@ -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
|
static status_t
|
||||||
nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie)
|
nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie)
|
||||||
{
|
{
|
||||||
@@ -299,7 +310,7 @@ fs_vnode_ops gNFSv4VnodeOps = {
|
|||||||
nfs4_open,
|
nfs4_open,
|
||||||
NULL, // close()
|
NULL, // close()
|
||||||
NULL, // free_cookie()
|
NULL, // free_cookie()
|
||||||
NULL, // read()
|
nfs4_read,
|
||||||
NULL, // write,
|
NULL, // write,
|
||||||
|
|
||||||
/* directory operations */
|
/* directory operations */
|
||||||
|
|||||||
Reference in New Issue
Block a user