nfs4: Use one open state per inode
This commit is contained in:
@@ -161,7 +161,6 @@ OpenFileCookie::GetLockOwner(uint32 owner)
|
|||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
current->fClientId = fClientID;
|
|
||||||
current->fNext = fLockOwners;
|
current->fNext = fLockOwners;
|
||||||
if (fLockOwners != NULL)
|
if (fLockOwners != NULL)
|
||||||
fLockOwners->fPrev = current;
|
fLockOwners->fPrev = current;
|
||||||
|
|||||||
@@ -71,10 +71,7 @@ struct Cookie {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct OpenFileCookie : public Cookie {
|
struct OpenFileCookie : public Cookie {
|
||||||
uint64 fClientID;
|
OpenState* fOpenState;
|
||||||
|
|
||||||
OpenState* fReadState;
|
|
||||||
OpenState* fWriteState;
|
|
||||||
|
|
||||||
uint32 fMode;
|
uint32 fMode;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Paweł Dziepak, [email protected]
|
||||||
|
*/
|
||||||
|
#ifndef DELEGATION_H
|
||||||
|
#define DELEGATION_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <lock.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include "NFS4Object.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Delegation : public NFS4Object {
|
||||||
|
public:
|
||||||
|
Delegation(OpenDelegationData data, Inode* inode,
|
||||||
|
uint64 clientID);
|
||||||
|
~Delegation();
|
||||||
|
|
||||||
|
status_t Write(void* buffer, uint32* size);
|
||||||
|
status_t Read(void* buffer, uint32* size);
|
||||||
|
|
||||||
|
// TODO: locks
|
||||||
|
|
||||||
|
status_t Reclaim(uint64 newClientID);
|
||||||
|
|
||||||
|
status_t GiveUp(bool flush);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint64 fClientID;
|
||||||
|
OpenDelegationData fData;
|
||||||
|
Inode* fInode;
|
||||||
|
|
||||||
|
rw_lock fLock;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DELEGATION_H
|
||||||
|
|
||||||
@@ -24,8 +24,7 @@ Inode::Inode()
|
|||||||
:
|
:
|
||||||
fCache(NULL),
|
fCache(NULL),
|
||||||
fFileCache(NULL),
|
fFileCache(NULL),
|
||||||
fWriteState(NULL),
|
fOpenState(NULL),
|
||||||
fReadState(NULL),
|
|
||||||
fWriteDirty(false)
|
fWriteDirty(false)
|
||||||
{
|
{
|
||||||
mutex_init(&fStateLock, NULL);
|
mutex_init(&fStateLock, NULL);
|
||||||
@@ -530,7 +529,7 @@ Inode::WriteStat(const struct stat* st, uint32 mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MutexLocker stateLocker(fStateLock);
|
MutexLocker stateLocker(fStateLock);
|
||||||
result = NFS4Inode::WriteStat(fWriteState, attr, i);
|
result = NFS4Inode::WriteStat(fOpenState, attr, i);
|
||||||
stateLocker.Unlock();
|
stateLocker.Unlock();
|
||||||
|
|
||||||
fMetaCache.InvalidateStat();
|
fMetaCache.InvalidateStat();
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
#include "OpenState.h"
|
#include "OpenState.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Delegation;
|
||||||
|
|
||||||
class Inode : public NFS4Inode {
|
class Inode : public NFS4Inode {
|
||||||
public:
|
public:
|
||||||
static status_t CreateInode(FileSystem* fs, const FileInfo& fi,
|
static status_t CreateInode(FileSystem* fs, const FileInfo& fi,
|
||||||
@@ -25,6 +27,8 @@ public:
|
|||||||
inline const char* Name() const;
|
inline const char* Name() const;
|
||||||
inline FileSystem* GetFileSystem() const;
|
inline FileSystem* GetFileSystem() const;
|
||||||
|
|
||||||
|
inline void SetOpenState(OpenState* state);
|
||||||
|
|
||||||
inline void* FileCache();
|
inline void* FileCache();
|
||||||
status_t RevalidateFileCache();
|
status_t RevalidateFileCache();
|
||||||
|
|
||||||
@@ -93,17 +97,20 @@ protected:
|
|||||||
|
|
||||||
static inline ino_t FileIdToInoT(uint64 fileid);
|
static inline ino_t FileIdToInoT(uint64 fileid);
|
||||||
|
|
||||||
|
private:
|
||||||
uint32 fType;
|
uint32 fType;
|
||||||
|
|
||||||
MetadataCache fMetaCache;
|
MetadataCache fMetaCache;
|
||||||
DirectoryCache* fCache;
|
DirectoryCache* fCache;
|
||||||
|
|
||||||
|
rw_lock fDelegationLock;
|
||||||
|
Delegation* fDelegation;
|
||||||
|
|
||||||
uint64 fChange;
|
uint64 fChange;
|
||||||
void* fFileCache;
|
void* fFileCache;
|
||||||
mutex fFileCacheLock;
|
mutex fFileCacheLock;
|
||||||
|
|
||||||
OpenState* fWriteState;
|
OpenState* fOpenState;
|
||||||
OpenState* fReadState;
|
|
||||||
mutex fStateLock;
|
mutex fStateLock;
|
||||||
|
|
||||||
bool fWriteDirty;
|
bool fWriteDirty;
|
||||||
@@ -156,5 +163,13 @@ Inode::FileCache()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
Inode::SetOpenState(OpenState* state)
|
||||||
|
{
|
||||||
|
MutexLocker _(fStateLock);
|
||||||
|
fOpenState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // INODE_H
|
#endif // INODE_H
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ inline status_t
|
|||||||
InodeIdMap::AddEntry(const FileInfo& fi, ino_t id)
|
InodeIdMap::AddEntry(const FileInfo& fi, ino_t id)
|
||||||
{
|
{
|
||||||
MutexLocker _(fLock);
|
MutexLocker _(fLock);
|
||||||
|
fMap.Remove(id);
|
||||||
return fMap.Insert(id, fi);
|
return fMap.Insert(id, fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,44 +70,19 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
|
|||||||
cookie->fLocks = NULL;
|
cookie->fLocks = NULL;
|
||||||
|
|
||||||
MutexLocker _(fStateLock);
|
MutexLocker _(fStateLock);
|
||||||
int openMode = mode & O_RWMASK;
|
|
||||||
|
|
||||||
if (openMode == O_WRONLY || openMode == O_RDWR) {
|
|
||||||
OpenState* state = new OpenState;
|
OpenState* state = new OpenState;
|
||||||
status_t result = CreateState(name, O_WRONLY, perms, state);
|
status_t result = CreateState(name, mode, perms, state);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
fWriteState = state;
|
cookie->fOpenState = state;
|
||||||
*id = FileIdToInoT(cookie->fWriteState->fInfo.fFileId);
|
fOpenState = state;
|
||||||
cookie->fWriteState = fWriteState;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (openMode == O_RDONLY || openMode == O_RDWR) {
|
*id = FileIdToInoT(state->fInfo.fFileId);
|
||||||
OpenState* state = new OpenState;
|
cookie->fOpenState = fOpenState;
|
||||||
state->fInfo = fInfo;
|
|
||||||
state->fFileSystem = fFileSystem;
|
|
||||||
|
|
||||||
status_t result;
|
|
||||||
if (openMode == O_RDWR)
|
|
||||||
result = OpenFile(state, O_RDONLY);
|
|
||||||
else
|
|
||||||
result = CreateState(name, O_RDONLY, perms, state);
|
|
||||||
|
|
||||||
if (result != B_OK) {
|
|
||||||
if (fWriteState != NULL)
|
|
||||||
if (fWriteState->ReleaseReference() == 1)
|
|
||||||
fWriteState = NULL;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
fReadState = state;
|
|
||||||
*id = FileIdToInoT(cookie->fReadState->fInfo.fFileId);
|
|
||||||
cookie->fReadState = fReadState;
|
|
||||||
}
|
|
||||||
|
|
||||||
cookie->fFileSystem = fFileSystem;
|
cookie->fFileSystem = fFileSystem;
|
||||||
cookie->fClientID = fFileSystem->NFSServer()->ClientId();
|
|
||||||
|
|
||||||
fFileSystem->AddOpenFile(cookie);
|
fFileSystem->AddOpenFile(cookie);
|
||||||
fFileSystem->Root()->MakeInfoInvalid();
|
fFileSystem->Root()->MakeInfoInvalid();
|
||||||
@@ -120,55 +95,33 @@ status_t
|
|||||||
Inode::Open(int mode, OpenFileCookie* cookie)
|
Inode::Open(int mode, OpenFileCookie* cookie)
|
||||||
{
|
{
|
||||||
MutexLocker _(fStateLock);
|
MutexLocker _(fStateLock);
|
||||||
int openMode = mode & O_RWMASK;
|
|
||||||
|
|
||||||
if (openMode == O_WRONLY || openMode == O_RDWR) {
|
if (fOpenState == NULL) {
|
||||||
if (fWriteState == NULL) {
|
|
||||||
OpenState* state = new OpenState;
|
OpenState* state = new OpenState;
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
state->fInfo = fInfo;
|
state->fInfo = fInfo;
|
||||||
state->fFileSystem = fFileSystem;
|
state->fFileSystem = fFileSystem;
|
||||||
status_t result = OpenFile(state, O_WRONLY);
|
status_t result = OpenFile(state, mode, NULL);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
fWriteState = state;
|
fOpenState = state;
|
||||||
} else
|
} else {
|
||||||
fWriteState->AcquireReference();
|
int newMode = mode & O_RWMASK;
|
||||||
|
int oldMode = fOpenState->fMode & O_RWMASK;
|
||||||
cookie->fWriteState = fWriteState;
|
if (oldMode != newMode && oldMode != O_RDWR) {
|
||||||
}
|
status_t result = OpenFile(fOpenState, O_RDWR, NULL);
|
||||||
|
if (result != B_OK)
|
||||||
if (openMode == O_RDONLY || openMode == O_RDWR) {
|
|
||||||
if (fReadState == NULL) {
|
|
||||||
OpenState* state = new OpenState;
|
|
||||||
if (state == NULL) {
|
|
||||||
if (fWriteState != NULL)
|
|
||||||
if (fWriteState->ReleaseReference() == 1)
|
|
||||||
fWriteState = NULL;
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
state->fInfo = fInfo;
|
|
||||||
state->fFileSystem = fFileSystem;
|
|
||||||
status_t result = OpenFile(state, O_RDONLY);
|
|
||||||
if (result != B_OK) {
|
|
||||||
if (fWriteState != NULL)
|
|
||||||
if (fWriteState->ReleaseReference() == 1)
|
|
||||||
fWriteState = NULL;
|
|
||||||
return result;
|
return result;
|
||||||
|
fOpenState->fMode = O_RDWR;
|
||||||
|
}
|
||||||
|
fOpenState->AcquireReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
fReadState = state;
|
cookie->fOpenState = fOpenState;
|
||||||
} else
|
|
||||||
fReadState->AcquireReference();
|
|
||||||
|
|
||||||
cookie->fReadState = fReadState;
|
|
||||||
}
|
|
||||||
|
|
||||||
cookie->fClientID = fFileSystem->NFSServer()->ClientId();
|
|
||||||
cookie->fFileSystem = fFileSystem;
|
cookie->fFileSystem = fFileSystem;
|
||||||
cookie->fMode = mode;
|
cookie->fMode = mode;
|
||||||
cookie->fLocks = NULL;
|
cookie->fLocks = NULL;
|
||||||
@@ -185,13 +138,9 @@ Inode::Close(OpenFileCookie* cookie)
|
|||||||
fFileSystem->RemoveOpenFile(cookie);
|
fFileSystem->RemoveOpenFile(cookie);
|
||||||
|
|
||||||
MutexLocker _(fStateLock);
|
MutexLocker _(fStateLock);
|
||||||
if (cookie->fWriteState != NULL)
|
if (cookie->fOpenState != NULL)
|
||||||
if (cookie->fWriteState->ReleaseReference() == 1)
|
if (cookie->fOpenState->ReleaseReference() == 1)
|
||||||
fWriteState = NULL;
|
fOpenState = NULL;
|
||||||
|
|
||||||
if (cookie->fReadState != NULL)
|
|
||||||
if (cookie->fReadState->ReleaseReference() == 1)
|
|
||||||
fReadState = NULL;
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -207,7 +156,7 @@ Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length,
|
|||||||
status_t result;
|
status_t result;
|
||||||
while (size < *_length && !*eof) {
|
while (size < *_length && !*eof) {
|
||||||
uint32 len = *_length - size;
|
uint32 len = *_length - size;
|
||||||
result = ReadFile(cookie, fReadState, pos + size, &len,
|
result = ReadFile(cookie, fOpenState, pos + size, &len,
|
||||||
reinterpret_cast<char*>(buffer) + size, eof);
|
reinterpret_cast<char*>(buffer) + size, eof);
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@@ -236,7 +185,7 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
|
|||||||
|
|
||||||
while (size < *_length) {
|
while (size < *_length) {
|
||||||
uint32 len = *_length - size;
|
uint32 len = *_length - size;
|
||||||
status_t result = WriteFile(cookie, fWriteState, pos + size, &len,
|
status_t result = WriteFile(cookie, fOpenState, pos + size, &len,
|
||||||
buffer + size);
|
buffer + size);
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
|||||||
@@ -493,9 +493,8 @@ 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)
|
||||||
{
|
{
|
||||||
OpenDelegationData delegation;
|
|
||||||
bool confirm;
|
bool confirm;
|
||||||
status_t result;
|
status_t result;
|
||||||
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
|
||||||
@@ -571,7 +570,7 @@ 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);
|
delegation);
|
||||||
|
|
||||||
FileHandle handle;
|
FileHandle handle;
|
||||||
reply.GetFH(&handle);
|
reply.GetFH(&handle);
|
||||||
@@ -587,9 +586,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ protected:
|
|||||||
status_t LookUp(const char* name, uint64* change, uint64* fileID,
|
status_t LookUp(const char* name, uint64* change, uint64* fileID,
|
||||||
FileHandle* handle);
|
FileHandle* handle);
|
||||||
|
|
||||||
status_t Link(Inode* dir, const char* name,
|
status_t Link(Inode* dir, const char* name,s
|
||||||
ChangeInfo* changeInfo);
|
ChangeInfo* changeInfo);
|
||||||
|
|
||||||
static status_t Rename(Inode* from, Inode* to, const char* fromName,
|
static status_t Rename(Inode* from, Inode* to, const char* fromName,
|
||||||
@@ -47,7 +47,8 @@ protected:
|
|||||||
status_t CreateFile(const char* name, int mode, int perms,
|
status_t CreateFile(const char* name, int mode, int perms,
|
||||||
OpenState* state, ChangeInfo* changeInfo,
|
OpenState* state, ChangeInfo* changeInfo,
|
||||||
uint64* fileID, FileHandle* handle);
|
uint64* fileID, FileHandle* handle);
|
||||||
status_t OpenFile(OpenState* state, int mode);
|
status_t OpenFile(OpenState* state, int mode,
|
||||||
|
OpenDelegationData* delegation);
|
||||||
|
|
||||||
status_t ReadFile(OpenFileCookie* cookie, OpenState* state,
|
status_t ReadFile(OpenFileCookie* cookie, OpenState* state,
|
||||||
uint64 position, uint32* length, void* buffer,
|
uint64 position, uint32* length, void* buffer,
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
|||||||
{
|
{
|
||||||
uint32 leaseTime;
|
uint32 leaseTime;
|
||||||
|
|
||||||
|
if (cookie != NULL)
|
||||||
|
state = cookie->fOpenState;
|
||||||
|
|
||||||
switch (nfs4Error) {
|
switch (nfs4Error) {
|
||||||
case NFS4_OK:
|
case NFS4_OK:
|
||||||
return false;
|
return false;
|
||||||
@@ -62,10 +65,7 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
|||||||
// server has rebooted, reclaim share and try again
|
// server has rebooted, reclaim share and try again
|
||||||
case NFS4ERR_STALE_CLIENTID:
|
case NFS4ERR_STALE_CLIENTID:
|
||||||
case NFS4ERR_STALE_STATEID:
|
case NFS4ERR_STALE_STATEID:
|
||||||
if (cookie != NULL) {
|
if (state != NULL) {
|
||||||
fFileSystem->NFSServer()->ServerRebooted(cookie->fClientID);
|
|
||||||
return true;
|
|
||||||
} else if (state != NULL) {
|
|
||||||
fFileSystem->NFSServer()->ServerRebooted(state->fClientID);
|
fFileSystem->NFSServer()->ServerRebooted(state->fClientID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -85,10 +85,7 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
|||||||
|
|
||||||
// lease has expired
|
// lease has expired
|
||||||
case NFS4ERR_EXPIRED:
|
case NFS4ERR_EXPIRED:
|
||||||
if (cookie != NULL) {
|
if (state != NULL) {
|
||||||
fFileSystem->NFSServer()->ClientId(cookie->fClientID, true);
|
|
||||||
return true;
|
|
||||||
} else if (state != NULL) {
|
|
||||||
fFileSystem->NFSServer()->ClientId(state->fClientID, true);
|
fFileSystem->NFSServer()->ClientId(state->fClientID, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -121,7 +118,7 @@ NFS4Object::ConfirmOpen(const FileHandle& fh, OpenState* state)
|
|||||||
|
|
||||||
ReplyInterpreter& reply = request.Reply();
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
if (HandleErrors(reply.NFS4Error(), serv))
|
if (HandleErrors(reply.NFS4Error(), serv, NULL, state))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fFileSystem->OpenOwnerSequenceUnlock();
|
fFileSystem->OpenOwnerSequenceUnlock();
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ NFS4Server::ServerRebooted(uint64 clientId)
|
|||||||
while (fs != NULL) {
|
while (fs != NULL) {
|
||||||
OpenFileCookie* current = fs->OpenFilesLock();
|
OpenFileCookie* current = fs->OpenFilesLock();
|
||||||
while (current != NULL) {
|
while (current != NULL) {
|
||||||
current->fClientID = fClientId;
|
|
||||||
_ReclaimOpen(current);
|
_ReclaimOpen(current);
|
||||||
_ReclaimLocks(current);
|
_ReclaimLocks(current);
|
||||||
current = current->fNext;
|
current = current->fNext;
|
||||||
@@ -75,10 +74,8 @@ NFS4Server::ServerRebooted(uint64 clientId)
|
|||||||
status_t
|
status_t
|
||||||
NFS4Server::_ReclaimOpen(OpenFileCookie* cookie)
|
NFS4Server::_ReclaimOpen(OpenFileCookie* cookie)
|
||||||
{
|
{
|
||||||
if (cookie->fWriteState != NULL)
|
if (cookie->fOpenState != NULL)
|
||||||
cookie->fWriteState->Reclaim(fClientId);
|
cookie->fOpenState->Reclaim(fClientId);
|
||||||
if (cookie->fReadState != NULL)
|
|
||||||
cookie->fReadState->Reclaim(fClientId);
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -100,10 +97,7 @@ NFS4Server::_ReclaimLocks(OpenFileCookie* cookie)
|
|||||||
Request request(fServer);
|
Request request(fServer);
|
||||||
RequestBuilder& req = request.Builder();
|
RequestBuilder& req = request.Builder();
|
||||||
|
|
||||||
if (cookie->fWriteState != NULL)
|
req.PutFH(cookie->fOpenState->fInfo.fHandle);
|
||||||
req.PutFH(cookie->fWriteState->fInfo.fHandle);
|
|
||||||
else
|
|
||||||
req.PutFH(cookie->fReadState->fInfo.fHandle);
|
|
||||||
req.Lock(cookie, linfo, true);
|
req.Lock(cookie, linfo, true);
|
||||||
|
|
||||||
status_t result = request.Send();
|
status_t result = request.Send();
|
||||||
|
|||||||
@@ -298,6 +298,10 @@ ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm,
|
|||||||
|
|
||||||
// delegation info
|
// delegation info
|
||||||
uint32 delegation = fReply->Stream().GetUInt();
|
uint32 delegation = fReply->Stream().GetUInt();
|
||||||
|
OpenDelegationData data;
|
||||||
|
if (delegData == NULL)
|
||||||
|
delegData = &data;
|
||||||
|
|
||||||
if (delegation == OPEN_DELEGATE_NONE) {
|
if (delegation == OPEN_DELEGATE_NONE) {
|
||||||
delegData->fType = OPEN_DELEGATE_NONE;
|
delegData->fType = OPEN_DELEGATE_NONE;
|
||||||
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||||
|
|||||||
@@ -173,14 +173,11 @@ void
|
|||||||
RequestBuilder::_GenerateLockOwner(XDR::WriteStream& stream,
|
RequestBuilder::_GenerateLockOwner(XDR::WriteStream& stream,
|
||||||
OpenFileCookie* cookie, LockOwner* owner)
|
OpenFileCookie* cookie, LockOwner* owner)
|
||||||
{
|
{
|
||||||
stream.AddUHyper(cookie->fClientID);
|
stream.AddUHyper(cookie->fOpenState->fClientID);
|
||||||
|
|
||||||
uint64 lockOwner[2];
|
uint64 lockOwner[2];
|
||||||
lockOwner[0] = owner->fOwner;
|
lockOwner[0] = owner->fOwner;
|
||||||
if (cookie->fWriteState != NULL)
|
lockOwner[1] = cookie->fOpenState->fInfo.fFileId;
|
||||||
lockOwner[1] = cookie->fWriteState->fInfo.fFileId;
|
|
||||||
else
|
|
||||||
lockOwner[1] = cookie->fReadState->fInfo.fFileId;
|
|
||||||
stream.AddOpaque(lockOwner, sizeof(lockOwner));
|
stream.AddOpaque(lockOwner, sizeof(lockOwner));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,11 +205,7 @@ RequestBuilder::Lock(OpenFileCookie* cookie, LockInfo* lock, uint32 sequence,
|
|||||||
fRequest->Stream().AddBoolean(true); // new lock owner
|
fRequest->Stream().AddBoolean(true); // new lock owner
|
||||||
|
|
||||||
// open seq stateid
|
// open seq stateid
|
||||||
OpenState* state;
|
OpenState* state = cookie->fOpenState;
|
||||||
if (lock->fType == READ_LT || lock->fType == READW_LT)
|
|
||||||
state = cookie->fReadState;
|
|
||||||
else
|
|
||||||
state = cookie->fWriteState;
|
|
||||||
|
|
||||||
fRequest->Stream().AddUInt(sequence);
|
fRequest->Stream().AddUInt(sequence);
|
||||||
fRequest->Stream().AddUInt(state->fStateSeq);
|
fRequest->Stream().AddUInt(state->fStateSeq);
|
||||||
@@ -258,7 +251,7 @@ RequestBuilder::LockT(LockType type, uint64 pos, uint64 len,
|
|||||||
fRequest->Stream().AddUHyper(pos);
|
fRequest->Stream().AddUHyper(pos);
|
||||||
fRequest->Stream().AddUHyper(len);
|
fRequest->Stream().AddUHyper(len);
|
||||||
|
|
||||||
fRequest->Stream().AddUHyper(cookie->fClientID);
|
fRequest->Stream().AddUHyper(cookie->fOpenState->fClientID);
|
||||||
|
|
||||||
uint32 owner = find_thread(NULL);
|
uint32 owner = find_thread(NULL);
|
||||||
fRequest->Stream().AddOpaque(&owner, sizeof(owner));
|
fRequest->Stream().AddOpaque(&owner, sizeof(owner));
|
||||||
|
|||||||
@@ -400,10 +400,24 @@ nfs4_create(fs_volume* volume, fs_vnode* dir, const char* name, int openMode,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ptr;
|
Inode* child;
|
||||||
result = get_vnode(volume, *_newVnodeID, &ptr);
|
result = get_vnode(volume, *_newVnodeID, reinterpret_cast<void**>(&child));
|
||||||
if (result != B_OK)
|
if (result != B_OK) {
|
||||||
|
result = inode->GetFileSystem()->GetInode(*_newVnodeID, &child);
|
||||||
|
if (result != B_OK) {
|
||||||
delete cookie;
|
delete cookie;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = new_vnode(volume, *_newVnodeID, child, &gNFSv4VnodeOps);
|
||||||
|
if (result != B_OK) {
|
||||||
|
delete child;
|
||||||
|
delete cookie;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
child->SetOpenState(cookie->fOpenState);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user