nfs4: Use global open owner, check whether delegation was granted

This commit is contained in:
Pawel Dziepak
2012-08-05 19:37:58 +02:00
parent 5a9212d612
commit 990922235b
13 changed files with 182 additions and 55 deletions
@@ -551,7 +551,7 @@ ConnectionBase::Disconnect()
status_t status_t
ConnectionListener::Listen(ConnectionListener** _listener, uint16 port) ConnectionListener::Listen(ConnectionListener** listener, uint16 port)
{ {
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) if (sock < 0)
@@ -577,16 +577,13 @@ ConnectionListener::Listen(ConnectionListener** _listener, uint16 port)
address.fProtocol = IPPROTO_TCP; address.fProtocol = IPPROTO_TCP;
memset(&address.fAddress, 0, sizeof(address.fAddress)); memset(&address.fAddress, 0, sizeof(address.fAddress));
ConnectionListener* listener; *listener = new(std::nothrow) ConnectionListener(address);
listener = new(std::nothrow) ConnectionListener(address); if (*listener == NULL) {
if (listener == NULL) {
close(sock); close(sock);
return B_NO_MEMORY; return B_NO_MEMORY;
} }
listener->fSocket = sock; (*listener)->fSocket = sock;
*_listener = listener;
return B_OK; return B_OK;
} }
@@ -27,10 +27,16 @@ FileSystem::FileSystem()
fPrev(NULL), fPrev(NULL),
fOpenFiles(NULL), fOpenFiles(NULL),
fOpenCount(0), fOpenCount(0),
fOpenOwnerSequence(0),
fPath(NULL), fPath(NULL),
fRoot(NULL), fRoot(NULL),
fId(1) fId(1)
{ {
fOpenOwner = rand();
fOpenOwner <<= 32;
fOpenOwner |= rand();
mutex_init(&fOpenOwnerLock, NULL);
mutex_init(&fOpenLock, NULL); mutex_init(&fOpenLock, NULL);
} }
@@ -40,6 +46,7 @@ FileSystem::~FileSystem()
NFSServer()->RemoveFileSystem(this); NFSServer()->RemoveFileSystem(this);
mutex_destroy(&fOpenLock); mutex_destroy(&fOpenLock);
mutex_destroy(&fOpenOwnerLock);
free(const_cast<char*>(fPath)); free(const_cast<char*>(fPath));
delete fRoot; delete fRoot;
@@ -51,6 +51,10 @@ public:
inline dev_t DevId() const; inline dev_t DevId() const;
inline InodeIdMap* InoIdMap(); inline InodeIdMap* InoIdMap();
inline uint64 OpenOwner() const;
inline uint32 OpenOwnerSequenceLock();
inline void OpenOwnerSequenceUnlock(bool increment = true);
FileSystem* fNext; FileSystem* fNext;
FileSystem* fPrev; FileSystem* fPrev;
private: private:
@@ -62,6 +66,10 @@ private:
uint32 fOpenCount; uint32 fOpenCount;
mutex fOpenLock; mutex fOpenLock;
uint64 fOpenOwner;
uint32 fOpenOwnerSequence;
mutex fOpenOwnerLock;
uint32 fExpireType; uint32 fExpireType;
uint32 fSupAttrs[2]; uint32 fSupAttrs[2];
@@ -163,5 +171,29 @@ FileSystem::InoIdMap()
} }
inline uint64
FileSystem::OpenOwner() const
{
return fOpenOwner;
}
inline uint32
FileSystem::OpenOwnerSequenceLock()
{
mutex_lock(&fOpenOwnerLock);
return fOpenOwnerSequence;
}
inline void
FileSystem::OpenOwnerSequenceUnlock(bool increment = true)
{
if (increment)
fOpenOwnerSequence++;
mutex_unlock(&fOpenOwnerLock);
}
#endif // FILESYSTEM_H #endif // FILESYSTEM_H
@@ -207,11 +207,32 @@ enum OpenClaim {
CLAIM_DELEGATE_PREV = 3 CLAIM_DELEGATE_PREV = 3
}; };
enum OpenDelegation {
OPEN_DELEGATE_NONE = 0,
OPEN_DELEGATE_READ = 1,
OPEN_DELEGATE_WRITE = 2
};
struct OpenDelegationData {
OpenDelegation fType;
uint32 fStateSeq;
uint32 fStateID[3];
bool fRecall;
uint64 fSpaceLimit;
};
enum OpenFlags { enum OpenFlags {
OPEN4_RESULT_CONFIRM = 2, OPEN4_RESULT_CONFIRM = 2,
OPEN4_RESULT_LOCKTYPE_POSIX = 4 OPEN4_RESULT_LOCKTYPE_POSIX = 4
}; };
enum {
NFS_LIMIT_SIZE = 1,
NFS_LIMIT_BLOCKS = 2
};
struct ChangeInfo { struct ChangeInfo {
bool fAtomic; bool fAtomic;
uint64 fBefore; uint64 fBefore;
@@ -389,6 +389,8 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms,
status_t result; status_t result;
bool badOwner = false; bool badOwner = false;
OpenDelegationData delegation;
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
do { do {
state->fClientID = fFileSystem->NFSServer()->ClientId(); state->fClientID = fFileSystem->NFSServer()->ClientId();
@@ -396,8 +398,6 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms,
Request request(serv); Request request(serv);
RequestBuilder& req = request.Builder(); RequestBuilder& req = request.Builder();
state->fOwnerID = atomic_add64(&state->fLastOwnerID, 1);
req.PutFH(fInfo.fHandle); req.PutFH(fInfo.fHandle);
AttrValue cattr[4]; AttrValue cattr[4];
@@ -427,9 +427,9 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms,
i++; i++;
} }
req.Open(CLAIM_NULL, state->fSequence++, sModeToAccess(mode), req.Open(CLAIM_NULL, sequence, sModeToAccess(mode),
state->fClientID, OPEN4_CREATE, state->fOwnerID, name, cattr, state->fClientID, OPEN4_CREATE, fFileSystem->OpenOwner(), name,
i, (mode & O_EXCL) == O_EXCL); cattr, i, (mode & O_EXCL) == O_EXCL);
req.GetFH(); req.GetFH();
@@ -439,22 +439,29 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms,
} }
result = request.Send(); result = request.Send();
if (result != B_OK) if (result != B_OK) {
fFileSystem->OpenOwnerSequenceUnlock(false);
return result; return result;
}
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
if (reply.NFS4Error() == NFS4ERR_BADOWNER) { if (reply.NFS4Error() == NFS4ERR_BADOWNER) {
fFileSystem->OpenOwnerSequenceUnlock();
sequence = fFileSystem->OpenOwnerSequenceLock();
badOwner = true; badOwner = true;
continue; continue;
} }
if (HandleErrors(reply.NFS4Error(), serv)) if (HandleErrors(reply.NFS4Error(), serv))
continue; continue;
fFileSystem->OpenOwnerSequenceUnlock();
reply.PutFH(); reply.PutFH();
result = reply.Open(state->fStateID, &state->fStateSeq, &confirm, result = reply.Open(state->fStateID, &state->fStateSeq, &confirm,
&changeInfo->fBefore, &changeInfo->fAfter, &changeInfo->fAtomic); &delegation, changeInfo);
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -488,8 +495,10 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms,
status_t status_t
NFS4Inode::OpenFile(OpenState* state, int mode) NFS4Inode::OpenFile(OpenState* state, int mode)
{ {
OpenDelegationData delegation;
bool confirm; bool confirm;
status_t result; status_t result;
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
do { do {
state->fClientID = fFileSystem->NFSServer()->ClientId(); state->fClientID = fFileSystem->NFSServer()->ClientId();
@@ -497,8 +506,6 @@ NFS4Inode::OpenFile(OpenState* state, int mode)
Request request(serv); Request request(serv);
RequestBuilder& req = request.Builder(); RequestBuilder& req = request.Builder();
state->fOwnerID = atomic_add64(&state->fLastOwnerID, 1);
// Since we are opening the file using a pair (parentFH, name) we // Since we are opening the file using a pair (parentFH, name) we
// need to check for race conditions. // need to check for race conditions.
if (fFileSystem->IsAttrSupported(FATTR4_FILEID)) { if (fFileSystem->IsAttrSupported(FATTR4_FILEID)) {
@@ -526,22 +533,27 @@ NFS4Inode::OpenFile(OpenState* state, int mode)
attr.fAttribute = FATTR4_SIZE; attr.fAttribute = FATTR4_SIZE;
attr.fFreePointer = false; attr.fFreePointer = false;
attr.fData.fValue64 = 0; attr.fData.fValue64 = 0;
req.Open(CLAIM_NULL, state->fSequence++, sModeToAccess(mode), req.Open(CLAIM_NULL, sequence, sModeToAccess(mode),
state->fClientID, OPEN4_CREATE, state->fOwnerID, fInfo.fName, state->fClientID, OPEN4_CREATE, fFileSystem->OpenOwner(),
&attr, 1, false); fInfo.fName, &attr, 1, false);
} else } else
req.Open(CLAIM_NULL, state->fSequence++, sModeToAccess(mode), req.Open(CLAIM_NULL, sequence, sModeToAccess(mode), state->fClientID,
state->fClientID, OPEN4_NOCREATE, state->fOwnerID, fInfo.fName); OPEN4_NOCREATE, fFileSystem->OpenOwner(), fInfo.fName);
req.GetFH();
result = request.Send(); result = request.Send();
if (result != B_OK) if (result != B_OK) {
fFileSystem->OpenOwnerSequenceUnlock(false);
return result; return result;
}
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
if (HandleErrors(reply.NFS4Error(), serv, NULL, state)) if (HandleErrors(reply.NFS4Error(), serv, NULL, state))
continue; continue;
fFileSystem->OpenOwnerSequenceUnlock();
// Verify if the file we want to open is the file this Inode // Verify if the file we want to open is the file this Inode
// represents. // represents.
if (fFileSystem->IsAttrSupported(FATTR4_FILEID) || if (fFileSystem->IsAttrSupported(FATTR4_FILEID) ||
@@ -558,7 +570,12 @@ NFS4Inode::OpenFile(OpenState* state, int mode)
} }
reply.PutFH(); reply.PutFH();
result = reply.Open(state->fStateID, &state->fStateSeq, &confirm); result = reply.Open(state->fStateID, &state->fStateSeq, &confirm,
&delegation);
FileHandle handle;
reply.GetFH(&handle);
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -570,6 +587,9 @@ NFS4Inode::OpenFile(OpenState* state, int mode)
if (confirm) if (confirm)
return ConfirmOpen(fInfo.fHandle, state); return ConfirmOpen(fInfo.fHandle, state);
if (delegation.fType != OPEN_DELEGATE_NONE)
dprintf("GOT A DELEGATION!\n");
return B_OK; return B_OK;
} }
@@ -891,6 +911,7 @@ NFS4Inode::TestLock(OpenFileCookie* cookie, LockType* type, uint64* position,
status_t status_t
NFS4Inode::AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo, bool wait) NFS4Inode::AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo, bool wait)
{ {
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
do { do {
MutexLocker ownerLocker(lockInfo->fOwner->fLock); MutexLocker ownerLocker(lockInfo->fOwner->fLock);
@@ -899,11 +920,13 @@ NFS4Inode::AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo, bool wait)
RequestBuilder& req = request.Builder(); RequestBuilder& req = request.Builder();
req.PutFH(fInfo.fHandle); req.PutFH(fInfo.fHandle);
req.Lock(cookie, lockInfo); req.Lock(cookie, lockInfo, sequence);
status_t result = request.Send(); status_t result = request.Send();
if (result != B_OK) if (result != B_OK) {
fFileSystem->OpenOwnerSequenceUnlock(false);
return result; return result;
}
ReplyInterpreter &reply = request.Reply(); ReplyInterpreter &reply = request.Reply();
@@ -912,13 +935,16 @@ NFS4Inode::AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo, bool wait)
ownerLocker.Unlock(); ownerLocker.Unlock();
if (wait && reply.NFS4Error() == NFS4ERR_DENIED) { if (wait && reply.NFS4Error() == NFS4ERR_DENIED) {
fFileSystem->OpenOwnerSequenceUnlock();
snooze_etc(sSecToBigTime(5), B_SYSTEM_TIMEBASE, snooze_etc(sSecToBigTime(5), B_SYSTEM_TIMEBASE,
B_RELATIVE_TIMEOUT); B_RELATIVE_TIMEOUT);
sequence = fFileSystem->OpenOwnerSequenceLock();
continue; continue;
} }
if (HandleErrors(reply.NFS4Error(), serv, cookie)) if (HandleErrors(reply.NFS4Error(), serv, cookie))
continue; continue;
fFileSystem->OpenOwnerSequenceUnlock();
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -103,6 +103,7 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
status_t status_t
NFS4Object::ConfirmOpen(const FileHandle& fh, OpenState* state) NFS4Object::ConfirmOpen(const FileHandle& fh, OpenState* state)
{ {
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
do { do {
RPC::Server* serv = fFileSystem->Server(); RPC::Server* serv = fFileSystem->Server();
Request request(serv); Request request(serv);
@@ -110,17 +111,21 @@ NFS4Object::ConfirmOpen(const FileHandle& fh, OpenState* state)
RequestBuilder& req = request.Builder(); RequestBuilder& req = request.Builder();
req.PutFH(fh); req.PutFH(fh);
req.OpenConfirm(state->fSequence++, state->fStateID, state->fStateSeq); req.OpenConfirm(sequence, state->fStateID, state->fStateSeq);
status_t result = request.Send(); status_t result = request.Send();
if (result != B_OK) if (result != B_OK) {
fFileSystem->OpenOwnerSequenceUnlock(false);
return result; return result;
}
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
if (HandleErrors(reply.NFS4Error(), serv)) if (HandleErrors(reply.NFS4Error(), serv))
continue; continue;
fFileSystem->OpenOwnerSequenceUnlock();
reply.PutFH(); reply.PutFH();
result = reply.OpenConfirm(&state->fStateSeq); result = reply.OpenConfirm(&state->fStateSeq);
if (result != B_OK) if (result != B_OK)
@@ -15,11 +15,8 @@
#include "Request.h" #include "Request.h"
vint64 OpenState::fLastOwnerID = 0;
OpenState::OpenState() OpenState::OpenState()
: :
fSequence(0),
fOpened(false) fOpened(false)
{ {
mutex_init(&fLock, NULL); mutex_init(&fLock, NULL);
@@ -46,27 +43,34 @@ OpenState::Reclaim(uint64 newClientID)
fClientID = newClientID; fClientID = newClientID;
bool confirm; bool confirm;
OpenDelegationData delegation;
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
do { do {
RPC::Server* server = fFileSystem->Server(); RPC::Server* server = fFileSystem->Server();
Request request(server); Request request(server);
RequestBuilder& req = request.Builder(); RequestBuilder& req = request.Builder();
req.PutFH(fInfo.fHandle); req.PutFH(fInfo.fHandle);
req.Open(CLAIM_PREVIOUS, fSequence++, sModeToAccess(fMode), newClientID, req.Open(CLAIM_PREVIOUS, sequence, sModeToAccess(fMode), newClientID,
OPEN4_NOCREATE, fOwnerID, NULL); OPEN4_NOCREATE, fFileSystem->OpenOwner(), NULL);
status_t result = request.Send(); status_t result = request.Send();
if (result != B_OK) if (result != B_OK) {
fFileSystem->OpenOwnerSequenceUnlock(false);
return result; return result;
}
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
if (HandleErrors(reply.NFS4Error(), server)) if (HandleErrors(reply.NFS4Error(), server))
continue; continue;
fFileSystem->OpenOwnerSequenceUnlock();
reply.PutFH(); reply.PutFH();
result = reply.Open(fStateID, &fStateSeq, &confirm); result = reply.Open(fStateID, &fStateSeq, &confirm, &delegation);
if (result != B_OK) if (result != B_OK)
return result; return result;
} while (true); } while (true);
@@ -87,24 +91,29 @@ OpenState::Close()
MutexLocker _(fLock); MutexLocker _(fLock);
fOpened = false; fOpened = false;
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
do { do {
RPC::Server* serv = fFileSystem->Server(); RPC::Server* serv = fFileSystem->Server();
Request request(serv); Request request(serv);
RequestBuilder& req = request.Builder(); RequestBuilder& req = request.Builder();
req.PutFH(fInfo.fHandle); req.PutFH(fInfo.fHandle);
req.Close(fSequence++, fStateID, fStateSeq); req.Close(sequence, fStateID, fStateSeq);
status_t result = request.Send(); status_t result = request.Send();
if (result != B_OK) if (result != B_OK) {
fFileSystem->OpenOwnerSequenceUnlock(false);
return result; return result;
}
ReplyInterpreter& reply = request.Reply(); ReplyInterpreter& reply = request.Reply();
if (HandleErrors(reply.NFS4Error(), serv, NULL, this)) if (HandleErrors(reply.NFS4Error(), serv, NULL, this))
continue; continue;
fFileSystem->OpenOwnerSequenceUnlock();
reply.PutFH(); reply.PutFH();
return reply.Close(); return reply.Close();
} while (true); } while (true);
} }
@@ -28,14 +28,8 @@ struct OpenState : public NFS4Object, public KernelReferenceable {
uint32 fStateID[3]; uint32 fStateID[3];
uint32 fStateSeq; uint32 fStateSeq;
uint32 fSequence;
uint64 fOwnerID;
static vint64 fLastOwnerID;
bool fOpened; bool fOpened;
status_t Reclaim(uint64 newClientID); status_t Reclaim(uint64 newClientID);
status_t Close(); status_t Close();
@@ -287,6 +287,7 @@ CallbackServer::ListenerThread()
{ {
while (fThreadRunning) { while (fThreadRunning) {
Connection* connection; Connection* connection;
status_t result = fListener->AcceptConnection(&connection); status_t result = fListener->AcceptConnection(&connection);
if (result != B_OK) { if (result != B_OK) {
fThreadRunning = false; fThreadRunning = false;
@@ -266,8 +266,8 @@ ReplyInterpreter::LockU(LockInfo* linfo)
status_t status_t
ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm, uint64* _before, ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm,
uint64* _after, bool* _atomic) OpenDelegationData* delegData, ChangeInfo* changeInfo)
{ {
status_t res = _OperationError(OpOpen); status_t res = _OperationError(OpOpen);
if (res != B_OK) if (res != B_OK)
@@ -280,14 +280,13 @@ ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm, uint64* _before,
// change info // change info
bool atomic = fReply->Stream().GetBoolean(); bool atomic = fReply->Stream().GetBoolean();
if (_atomic != NULL)
*_atomic = atomic;
uint64 before = fReply->Stream().GetUHyper(); uint64 before = fReply->Stream().GetUHyper();
if (_before != NULL)
*_before = before;
uint64 after = fReply->Stream().GetUHyper(); uint64 after = fReply->Stream().GetUHyper();
if (_after != NULL) if (changeInfo != NULL) {
*_after = after; changeInfo->fAtomic = atomic;
changeInfo->fBefore = before;
changeInfo->fAfter = after;
}
uint32 flags = fReply->Stream().GetUInt(); uint32 flags = fReply->Stream().GetUInt();
*confirm = (flags & OPEN4_RESULT_CONFIRM) == OPEN4_RESULT_CONFIRM; *confirm = (flags & OPEN4_RESULT_CONFIRM) == OPEN4_RESULT_CONFIRM;
@@ -298,7 +297,41 @@ ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm, uint64* _before,
fReply->Stream().GetUInt(); fReply->Stream().GetUInt();
// delegation info // delegation info
uint32 delegation = fReply->Stream().GetUInt();
if (delegation == OPEN_DELEGATE_NONE) {
delegData->fType = OPEN_DELEGATE_NONE;
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
}
delegData->fStateSeq = fReply->Stream().GetUInt();
delegData->fStateID[0] = fReply->Stream().GetUInt();
delegData->fStateID[1] = fReply->Stream().GetUInt();
delegData->fStateID[2] = fReply->Stream().GetUInt();
delegData->fRecall = fReply->Stream().GetBoolean();
switch (delegation) {
case OPEN_DELEGATE_READ:
delegData->fType = OPEN_DELEGATE_READ;
break;
case OPEN_DELEGATE_WRITE:
delegData->fType = OPEN_DELEGATE_WRITE;
int32 limitBy = fReply->Stream().GetInt();
if (limitBy == NFS_LIMIT_SIZE)
delegData->fSpaceLimit = fReply->Stream().GetUHyper();
else if (limitBy == NFS_LIMIT_BLOCKS) {
uint32 numBlocks = fReply->Stream().GetUInt();
delegData->fSpaceLimit = fReply->Stream().GetUInt() * numBlocks;
}
break;
}
// ACE data
fReply->Stream().GetUInt(); fReply->Stream().GetUInt();
fReply->Stream().GetUInt();
fReply->Stream().GetUInt();
fReply->Stream().GetOpaque(NULL);
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK; return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
} }
@@ -81,8 +81,8 @@ public:
inline status_t LookUpUp(); inline status_t LookUpUp();
inline status_t Nverify(); inline status_t Nverify();
status_t Open(uint32* id, uint32* seq, bool* confirm, status_t Open(uint32* id, uint32* seq, bool* confirm,
uint64* before = NULL, uint64* after = NULL, OpenDelegationData* delegData,
bool* atomic = NULL); ChangeInfo* changeInfo = NULL);
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();
@@ -186,7 +186,8 @@ RequestBuilder::_GenerateLockOwner(XDR::WriteStream& stream,
status_t status_t
RequestBuilder::Lock(OpenFileCookie* cookie, LockInfo* lock, bool reclaim) RequestBuilder::Lock(OpenFileCookie* cookie, LockInfo* lock, uint32 sequence,
bool reclaim)
{ {
if (fProcedure != ProcCompound) if (fProcedure != ProcCompound)
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -213,7 +214,7 @@ RequestBuilder::Lock(OpenFileCookie* cookie, LockInfo* lock, bool reclaim)
else else
state = cookie->fWriteState; state = cookie->fWriteState;
fRequest->Stream().AddUInt(state->fSequence++); fRequest->Stream().AddUInt(sequence);
fRequest->Stream().AddUInt(state->fStateSeq); fRequest->Stream().AddUInt(state->fStateSeq);
fRequest->Stream().AddUInt(state->fStateID[0]); fRequest->Stream().AddUInt(state->fStateID[0]);
fRequest->Stream().AddUInt(state->fStateID[1]); fRequest->Stream().AddUInt(state->fStateID[1]);
@@ -41,7 +41,8 @@ public:
status_t GetFH(); status_t GetFH();
status_t Link(const char* name); status_t Link(const char* name);
status_t Lock(OpenFileCookie* cookie, status_t Lock(OpenFileCookie* cookie,
LockInfo* lock, bool reclaim = false); LockInfo* lock, uint32 sequence,
bool reclaim = false);
status_t LockT(LockType type, uint64 pos, status_t LockT(LockType type, uint64 pos,
uint64 len, OpenFileCookie* cookie); uint64 len, OpenFileCookie* cookie);
status_t LockU(LockInfo* lock); status_t LockU(LockInfo* lock);