diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index e5d90c267e..68928bf941 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -59,7 +59,8 @@ public: status_t WriteStat(const struct stat* st, uint32 mask); status_t Create(const char* name, int mode, int perms, - OpenFileCookie* cookie, ino_t* id); + OpenFileCookie* cookie, + OpenDelegationData* data, ino_t* id); status_t Open(int mode, OpenFileCookie* cookie); status_t Close(OpenFileCookie* cookie); status_t Read(OpenFileCookie* cookie, off_t pos, @@ -89,7 +90,8 @@ protected: Inode(); status_t CreateState(const char* name, int mode, - int perms, OpenState* state); + int perms, OpenState* state, + OpenDelegationData* data); status_t ReadDirUp(struct dirent* de, uint32 pos, uint32 size); diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp index 0056512c9e..452648779a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp @@ -20,13 +20,14 @@ status_t -Inode::CreateState(const char* name, int mode, int perms, OpenState* state) { +Inode::CreateState(const char* name, int mode, int perms, OpenState* state, + OpenDelegationData* delegationData) { uint64 fileID; FileHandle handle; ChangeInfo changeInfo; status_t result = CreateFile(name, mode, perms, state, &changeInfo, - &fileID, &handle); + &fileID, &handle, delegationData); if (result != B_OK) return result; @@ -64,7 +65,7 @@ Inode::CreateState(const char* name, int mode, int perms, OpenState* state) { status_t Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie, - ino_t* id) + OpenDelegationData* data, ino_t* id) { cookie->fMode = mode; cookie->fLocks = NULL; @@ -72,7 +73,7 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie, MutexLocker _(fStateLock); OpenState* state = new OpenState; - status_t result = CreateState(name, mode, perms, state); + status_t result = CreateState(name, mode, perms, state, data); if (result != B_OK) return result; @@ -99,6 +100,8 @@ Inode::Open(int mode, OpenFileCookie* cookie) OpenDelegationData data; data.fType = OPEN_DELEGATE_NONE; if (fOpenState == NULL) { + // TODO: revalidate cache + OpenState* state = new OpenState; if (state == NULL) return B_NO_MEMORY; diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp index e45f08f4f2..67649d998a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp @@ -381,15 +381,14 @@ NFS4Inode::Rename(Inode* from, Inode* to, const char* fromName, status_t -NFS4Inode::CreateFile(const char* name, int mode, int perms, - OpenState* state, ChangeInfo* changeInfo, uint64* fileID, - FileHandle* handle) +NFS4Inode::CreateFile(const char* name, int mode, int perms, OpenState* state, + ChangeInfo* changeInfo, uint64* fileID, FileHandle* handle, + OpenDelegationData* delegation) { bool confirm; status_t result; bool badOwner = false; - OpenDelegationData delegation; uint32 sequence = fFileSystem->OpenOwnerSequenceLock(); do { state->fClientID = fFileSystem->NFSServer()->ClientId(); @@ -461,7 +460,7 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms, reply.PutFH(); result = reply.Open(state->fStateID, &state->fStateSeq, &confirm, - &delegation, changeInfo); + delegation, changeInfo); if (result != B_OK) return result; diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h index 968e6705b5..3e1bedb429 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h @@ -46,7 +46,8 @@ protected: status_t CreateFile(const char* name, int mode, int perms, OpenState* state, ChangeInfo* changeInfo, - uint64* fileID, FileHandle* handle); + uint64* fileID, FileHandle* handle, + OpenDelegationData* delegation); status_t OpenFile(OpenState* state, int mode, OpenDelegationData* delegation); diff --git a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp index 6da6cd15f1..9a9f8b9c23 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -392,7 +392,10 @@ nfs4_create(fs_volume* volume, fs_vnode* dir, const char* name, int openMode, *_cookie = cookie; Inode* inode = reinterpret_cast(dir->private_node); - status_t result = inode->Create(name, openMode, perms, cookie, _newVnodeID); + + OpenDelegationData data; + status_t result = inode->Create(name, openMode, perms, cookie, &data, + _newVnodeID); if (result != B_OK) { delete cookie; return result; @@ -417,6 +420,17 @@ nfs4_create(fs_volume* volume, fs_vnode* dir, const char* name, int openMode, child->SetOpenState(cookie->fOpenState); + if (data.fType != OPEN_DELEGATE_NONE) { + Delegation* delegation + = new(std::nothrow) Delegation(data, child, + cookie->fOpenState->fClientID); + if (delegation != NULL) { + delegation->fInfo = cookie->fOpenState->fInfo; + delegation->fFileSystem = child->GetFileSystem(); + child->SetDelegation(delegation); + } + } + return result; }