nfs4: Add open() hook
This commit is contained in:
@@ -42,6 +42,16 @@ ServerAddress::operator<(const ServerAddress& x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ServerAddress&
|
||||||
|
ServerAddress::operator=(const ServerAddress& x)
|
||||||
|
{
|
||||||
|
fAddress = x.fAddress;
|
||||||
|
fPort = x.fPort;
|
||||||
|
fProtocol = x.fProtocol;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Connection::Connection(const sockaddr_in& addr, Transport proto, bool markers)
|
Connection::Connection(const sockaddr_in& addr, Transport proto, bool markers)
|
||||||
:
|
:
|
||||||
fSock(-1),
|
fSock(-1),
|
||||||
@@ -61,6 +71,23 @@ Connection::~Connection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Connection::GetLocalID(ServerAddress* addr)
|
||||||
|
{
|
||||||
|
struct sockaddr_in saddr;
|
||||||
|
socklen_t slen = sizeof(addr);
|
||||||
|
status_t result = kgetsockname(fSock, (struct sockaddr*)&saddr, &slen);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
addr->fProtocol = fProtocol;
|
||||||
|
addr->fPort = ntohs(saddr.sin_port);
|
||||||
|
addr->fAddress = ntohl(saddr.sin_addr.s_addr);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Connection::_SendStream(const void* buffer, uint32 size)
|
Connection::_SendStream(const void* buffer, uint32 size)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ struct ServerAddress {
|
|||||||
|
|
||||||
bool operator==(const ServerAddress& x);
|
bool operator==(const ServerAddress& x);
|
||||||
bool operator<(const ServerAddress& x);
|
bool operator<(const ServerAddress& x);
|
||||||
|
|
||||||
|
ServerAddress& operator=(const ServerAddress& x);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Connection {
|
class Connection {
|
||||||
@@ -38,6 +40,8 @@ public:
|
|||||||
inline status_t Send(const void* buffer, uint32 size);
|
inline status_t Send(const void* buffer, uint32 size);
|
||||||
inline status_t Receive(void** buffer, uint32* size);
|
inline status_t Receive(void** buffer, uint32* size);
|
||||||
|
|
||||||
|
status_t GetLocalID(ServerAddress* addr);
|
||||||
|
|
||||||
status_t Reconnect();
|
status_t Reconnect();
|
||||||
void Disconnect();
|
void Disconnect();
|
||||||
|
|
||||||
|
|||||||
@@ -185,6 +185,70 @@ Inode::Stat(struct stat* st)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Inode::Open(int mode, OpenFileCookie* cookie)
|
||||||
|
{
|
||||||
|
cookie->fSeq = 0;
|
||||||
|
|
||||||
|
RequestBuilder req_setid(ProcCompound);
|
||||||
|
req_setid.SetClientID(fFilesystem->Server());
|
||||||
|
|
||||||
|
RPC::Reply *rpl;
|
||||||
|
fFilesystem->Server()->SendCall(req_setid.Request(), &rpl);
|
||||||
|
ReplyInterpreter setid(rpl);
|
||||||
|
|
||||||
|
uint64 id, ver;
|
||||||
|
status_t result = setid.SetClientID(&id, &ver);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
RequestBuilder req_conf(ProcCompound);
|
||||||
|
req_conf.SetClientIDConfirm(id, ver);
|
||||||
|
|
||||||
|
fFilesystem->Server()->SendCall(req_conf.Request(), &rpl);
|
||||||
|
ReplyInterpreter conf(rpl);
|
||||||
|
|
||||||
|
result = conf.SetClientIDConfirm();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
RequestBuilder req(ProcCompound);
|
||||||
|
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 = reply.PutFH();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
bool confirm;
|
||||||
|
result = reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (confirm) {
|
||||||
|
RequestBuilder req(ProcCompound);
|
||||||
|
req.PutFH(fHandle);
|
||||||
|
req.OpenConfirm(cookie->fSeq, cookie->fStateId, cookie->fStateSeq);
|
||||||
|
cookie->fSeq++;
|
||||||
|
fFilesystem->Server()->SendCall(req.Request(), &rpl);
|
||||||
|
ReplyInterpreter reply(rpl);
|
||||||
|
|
||||||
|
result = reply.PutFH();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = reply.OpenConfirm(&cookie->fStateSeq);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Inode::OpenDir(uint64* cookie)
|
Inode::OpenDir(uint64* cookie)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,6 +18,12 @@
|
|||||||
#include "ReplyInterpreter.h"
|
#include "ReplyInterpreter.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct OpenFileCookie {
|
||||||
|
uint32 fStateId[3];
|
||||||
|
uint32 fStateSeq;
|
||||||
|
uint32 fSeq;
|
||||||
|
};
|
||||||
|
|
||||||
class Inode {
|
class Inode {
|
||||||
public:
|
public:
|
||||||
Inode(Filesystem* fs, const FileInfo& fi);
|
Inode(Filesystem* fs, const FileInfo& fi);
|
||||||
@@ -30,6 +36,8 @@ public:
|
|||||||
status_t LookUp(const char* name, ino_t* id);
|
status_t LookUp(const char* name, ino_t* id);
|
||||||
status_t Stat(struct stat* st);
|
status_t Stat(struct stat* st);
|
||||||
|
|
||||||
|
status_t Open(int mode, OpenFileCookie* cookie);
|
||||||
|
|
||||||
status_t OpenDir(uint64* cookie);
|
status_t OpenDir(uint64* cookie);
|
||||||
status_t ReadDir(void* buffer, uint32 size,
|
status_t ReadDir(void* buffer, uint32 size,
|
||||||
uint32* count, uint64* cookie);
|
uint32* count, uint64* cookie);
|
||||||
|
|||||||
@@ -21,14 +21,18 @@ enum Procedure {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum Opcode {
|
enum Opcode {
|
||||||
OpAccess = 3,
|
OpAccess = 3,
|
||||||
OpGetAttr = 9,
|
OpGetAttr = 9,
|
||||||
OpGetFH = 10,
|
OpGetFH = 10,
|
||||||
OpLookUp = 15,
|
OpLookUp = 15,
|
||||||
OpLookUpUp = 16,
|
OpLookUpUp = 16,
|
||||||
OpPutFH = 22,
|
OpOpen = 18,
|
||||||
OpPutRootFH = 24,
|
OpOpenConfirm = 20,
|
||||||
OpReadDir = 26
|
OpPutFH = 22,
|
||||||
|
OpPutRootFH = 24,
|
||||||
|
OpReadDir = 26,
|
||||||
|
OpSetClientID = 35,
|
||||||
|
OpSetClientIDConfirm = 36
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Access {
|
enum Access {
|
||||||
@@ -128,6 +132,21 @@ enum FileHandleExpiryType {
|
|||||||
FH4_VOL_RENAME = 0x08
|
FH4_VOL_RENAME = 0x08
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum OpenAccess {
|
||||||
|
OPEN4_SHARE_ACCESS_READ = 1,
|
||||||
|
OPEN4_SHARE_ACCESS_WRITE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OpenCreate {
|
||||||
|
OPEN4_NOCREATE = 0,
|
||||||
|
OPEN4_CREATE = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OpenFlags {
|
||||||
|
OPEN4_RESULT_CONFIRM = 2,
|
||||||
|
OPEN4_RESULT_LOCKTYPE_POSIX = 4
|
||||||
|
};
|
||||||
|
|
||||||
enum Errors {
|
enum Errors {
|
||||||
NFS4_OK = 0,
|
NFS4_OK = 0,
|
||||||
NFS4ERR_PERM = 1,
|
NFS4ERR_PERM = 1,
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public:
|
|||||||
status_t Repair();
|
status_t Repair();
|
||||||
|
|
||||||
inline const ServerAddress& ID() const;
|
inline const ServerAddress& ID() const;
|
||||||
|
inline ServerAddress LocalID() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline uint32 _GetXID();
|
inline uint32 _GetXID();
|
||||||
@@ -80,6 +81,17 @@ Server::ID() const
|
|||||||
return *fAddress;
|
return *fAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline ServerAddress
|
||||||
|
Server::LocalID() const
|
||||||
|
{
|
||||||
|
ServerAddress addr;
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
fConnection->GetLocalID(&addr);
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ServerNode {
|
struct ServerNode {
|
||||||
ServerAddress fID;
|
ServerAddress fID;
|
||||||
Server* fServer;
|
Server* fServer;
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ ReplyInterpreter::Access(uint32* supported, uint32* allowed)
|
|||||||
if (allowed != NULL)
|
if (allowed != NULL)
|
||||||
*allowed = allow;
|
*allowed = allow;
|
||||||
|
|
||||||
return B_OK;
|
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -112,7 +112,55 @@ ReplyInterpreter::GetFH(Filehandle* fh)
|
|||||||
memcpy(fh->fFH, ptr, size);
|
memcpy(fh->fFH, ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm)
|
||||||
|
{
|
||||||
|
status_t res = _OperationError(OpOpen);
|
||||||
|
if (res != B_OK)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
*seq = fReply->Stream().GetUInt();
|
||||||
|
id[0] = fReply->Stream().GetUInt();
|
||||||
|
id[1] = fReply->Stream().GetUInt();
|
||||||
|
id[2] = fReply->Stream().GetUInt();
|
||||||
|
|
||||||
|
// change info
|
||||||
|
fReply->Stream().GetBoolean();
|
||||||
|
fReply->Stream().GetUHyper();
|
||||||
|
fReply->Stream().GetUHyper();
|
||||||
|
|
||||||
|
uint32 flags = fReply->Stream().GetUInt();
|
||||||
|
*confirm = (flags & OPEN4_RESULT_CONFIRM) == OPEN4_RESULT_CONFIRM;
|
||||||
|
|
||||||
|
// attrmask
|
||||||
|
uint32 bcount = fReply->Stream().GetUInt();
|
||||||
|
for (uint32 i = 0; i < bcount; i++)
|
||||||
|
fReply->Stream().GetUInt();
|
||||||
|
|
||||||
|
// delegation info
|
||||||
|
fReply->Stream().GetUInt();
|
||||||
|
|
||||||
|
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ReplyInterpreter::OpenConfirm(uint32* stateSeq)
|
||||||
|
{
|
||||||
|
status_t res = _OperationError(OpOpenConfirm);
|
||||||
|
if (res != B_OK)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
*stateSeq = fReply->Stream().GetUInt();
|
||||||
|
fReply->Stream().GetUInt();
|
||||||
|
fReply->Stream().GetUInt();
|
||||||
|
fReply->Stream().GetUInt();
|
||||||
|
|
||||||
|
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -152,7 +200,21 @@ ReplyInterpreter::ReadDir(uint64* cookie, DirEntry** dirents, uint32* _count,
|
|||||||
*_count = count;
|
*_count = count;
|
||||||
*dirents = entries;
|
*dirents = entries;
|
||||||
|
|
||||||
return B_OK;
|
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ReplyInterpreter::SetClientID(uint64* clientid, uint64* verifier)
|
||||||
|
{
|
||||||
|
status_t res = _OperationError(OpSetClientID);
|
||||||
|
if (res != B_OK)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
*clientid = fReply->Stream().GetUHyper();
|
||||||
|
*verifier = fReply->Stream().GetUHyper();
|
||||||
|
|
||||||
|
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -230,7 +292,7 @@ ReplyInterpreter::_DecodeAttrs(XDR::ReadStream& str, AttrValue** attrs,
|
|||||||
|
|
||||||
*count = attr_count;
|
*count = attr_count;
|
||||||
*attrs = values;
|
*attrs = values;
|
||||||
return B_OK;
|
return str.IsEOF() ? B_BAD_VALUE : B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,14 @@ public:
|
|||||||
status_t GetFH(Filehandle* fh);
|
status_t GetFH(Filehandle* fh);
|
||||||
inline status_t LookUp();
|
inline status_t LookUp();
|
||||||
inline status_t LookUpUp();
|
inline status_t LookUpUp();
|
||||||
|
status_t Open(uint32* id, uint32* seq, bool* confirm);
|
||||||
|
status_t OpenConfirm(uint32* stateSeq);
|
||||||
inline status_t PutFH();
|
inline status_t PutFH();
|
||||||
inline status_t PutRootFH();
|
inline status_t PutRootFH();
|
||||||
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);
|
||||||
|
inline status_t SetClientIDConfirm();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _DecodeAttrs(XDR::ReadStream& stream, AttrValue** attrs,
|
status_t _DecodeAttrs(XDR::ReadStream& stream, AttrValue** attrs,
|
||||||
@@ -87,5 +91,12 @@ ReplyInterpreter::PutRootFH()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline status_t
|
||||||
|
ReplyInterpreter::SetClientIDConfirm()
|
||||||
|
{
|
||||||
|
return _OperationError(OpSetClientIDConfirm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // REPLYINTERPRETER_H
|
#endif // REPLYINTERPRETER_H
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,62 @@ RequestBuilder::LookUpUp()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RequestBuilder::Open(uint32 seq, uint32 access, uint64 id, OpenCreate oc,
|
||||||
|
const char* name)
|
||||||
|
{
|
||||||
|
if (fProcedure != ProcCompound)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
if (fRequest == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
fRequest->Stream().AddUInt(OpOpen);
|
||||||
|
fRequest->Stream().AddUInt(seq);
|
||||||
|
fRequest->Stream().AddUInt(access);
|
||||||
|
fRequest->Stream().AddUInt(0); // deny none
|
||||||
|
fRequest->Stream().AddUHyper(id);
|
||||||
|
|
||||||
|
char owner[128];
|
||||||
|
int pos = 0;
|
||||||
|
*(uint32*)(owner + pos) = time(NULL);
|
||||||
|
pos += sizeof(uint32);
|
||||||
|
|
||||||
|
*(uint32*)(owner + pos) = find_thread(NULL);
|
||||||
|
pos += sizeof(uint32);
|
||||||
|
|
||||||
|
fRequest->Stream().AddOpaque(owner, pos);
|
||||||
|
|
||||||
|
fRequest->Stream().AddUInt(oc);
|
||||||
|
fRequest->Stream().AddUInt(0); // claim null
|
||||||
|
fRequest->Stream().AddString(name, strlen(name));
|
||||||
|
|
||||||
|
fOpCount++;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RequestBuilder::OpenConfirm(uint32 seq, const uint32* id, uint32 stateSeq)
|
||||||
|
{
|
||||||
|
if (fProcedure != ProcCompound)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
if (fRequest == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
fRequest->Stream().AddUInt(OpOpenConfirm);
|
||||||
|
fRequest->Stream().AddUInt(stateSeq);
|
||||||
|
fRequest->Stream().AddUInt(id[0]);
|
||||||
|
fRequest->Stream().AddUInt(id[1]);
|
||||||
|
fRequest->Stream().AddUInt(id[2]);
|
||||||
|
fRequest->Stream().AddUInt(seq);
|
||||||
|
|
||||||
|
fOpCount++;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RequestBuilder::PutFH(const Filehandle& fh)
|
RequestBuilder::PutFH(const Filehandle& fh)
|
||||||
{
|
{
|
||||||
@@ -175,6 +231,63 @@ RequestBuilder::ReadDir(uint32 count, uint64* cookie, Attribute* attrs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RequestBuilder::SetClientID(const RPC::Server* serv)
|
||||||
|
{
|
||||||
|
if (fProcedure != ProcCompound)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
if (fRequest == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
fRequest->Stream().AddUInt(OpSetClientID);
|
||||||
|
uint64 verifier = rand();
|
||||||
|
verifier = verifier << 32 | rand();
|
||||||
|
fRequest->Stream().AddUHyper(verifier);
|
||||||
|
|
||||||
|
char id[128] = "HAIKU:kernel:";
|
||||||
|
int pos = strlen(id);
|
||||||
|
*(uint32*)(id + pos) = serv->ID().fAddress;
|
||||||
|
pos += sizeof(uint32);
|
||||||
|
*(uint16*)(id + pos) = serv->ID().fPort;
|
||||||
|
pos += sizeof(uint16);
|
||||||
|
*(uint16*)(id + pos) = serv->ID().fProtocol;
|
||||||
|
pos += sizeof(uint16);
|
||||||
|
|
||||||
|
*(uint32*)(id + pos) = serv->LocalID().fAddress;
|
||||||
|
pos += sizeof(uint32);
|
||||||
|
|
||||||
|
fRequest->Stream().AddOpaque(id, pos);
|
||||||
|
|
||||||
|
// Callbacks are currently not supported
|
||||||
|
fRequest->Stream().AddUInt(0);
|
||||||
|
fRequest->Stream().AddOpaque(NULL, 0);
|
||||||
|
fRequest->Stream().AddOpaque(NULL, 0);
|
||||||
|
fRequest->Stream().AddUInt(0);
|
||||||
|
|
||||||
|
fOpCount++;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RequestBuilder::SetClientIDConfirm(uint64 id, uint64 ver)
|
||||||
|
{
|
||||||
|
if (fProcedure != ProcCompound)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
if (fRequest == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
fRequest->Stream().AddUInt(OpSetClientIDConfirm);
|
||||||
|
fRequest->Stream().AddUHyper(id);
|
||||||
|
fRequest->Stream().AddUHyper(ver);
|
||||||
|
|
||||||
|
fOpCount++;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
RPC::Call*
|
RPC::Call*
|
||||||
RequestBuilder::Request()
|
RequestBuilder::Request()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "NFS4Defs.h"
|
#include "NFS4Defs.h"
|
||||||
#include "RPCCall.h"
|
#include "RPCCall.h"
|
||||||
|
#include "RPCServer.h"
|
||||||
#include "XDR.h"
|
#include "XDR.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -26,10 +27,16 @@ public:
|
|||||||
status_t GetFH();
|
status_t GetFH();
|
||||||
status_t LookUp(const char* name);
|
status_t LookUp(const char* name);
|
||||||
status_t LookUpUp();
|
status_t LookUpUp();
|
||||||
|
status_t Open(uint32 seq, uint32 access, uint64 id,
|
||||||
|
OpenCreate oc, const char* name);
|
||||||
|
status_t OpenConfirm(uint32 seq, const uint32* id,
|
||||||
|
uint32 stateSeq);
|
||||||
status_t PutFH(const Filehandle& fh);
|
status_t PutFH(const Filehandle& fh);
|
||||||
status_t PutRootFH();
|
status_t PutRootFH();
|
||||||
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 SetClientIDConfirm(uint64 id, uint64 ver);
|
||||||
|
|
||||||
RPC::Call* Request();
|
RPC::Call* Request();
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,17 @@ nfs4_read_stat(fs_volume* volume, fs_vnode* vnode, struct stat* stat)
|
|||||||
static status_t
|
static status_t
|
||||||
nfs4_open(fs_volume* volume, fs_vnode* vnode, int openMode, void** _cookie)
|
nfs4_open(fs_volume* volume, fs_vnode* vnode, int openMode, void** _cookie)
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
OpenFileCookie* cookie = new OpenFileCookie;
|
||||||
|
if (cookie == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
*_cookie = cookie;
|
||||||
|
|
||||||
|
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
|
||||||
|
status_t result = inode->Open(openMode, cookie);
|
||||||
|
if (result != B_OK)
|
||||||
|
delete cookie;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user