added 3 changesets to branch 'refs/remotes/pdziepak-github/nfs4' old head: 9c1d983eab87868914f3d1621fc028b883901cd5 new head: ce851e2bac9dba986b6e4243e4cccd6f4e59380c overview: https://github.com/pdziepak/Haiku/compare/9c1d983...ce851e2 ---------------------------------------------------------------------------- 1c6f502: nfs4: Add not null assertions for Inode::fOpenState and fDelegation 65edbee: nfs4: DirectoryCache::GetSnapshot may return NULL ce851e2: nfs4: Fix few Inode::fOpenState related race conditions [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ] ---------------------------------------------------------------------------- 8 files changed, 37 insertions(+), 16 deletions(-) src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h | 14 +++++++++----- src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp | 2 ++ src/add-ons/kernel/file_systems/nfs4/FileSystem.h | 10 ++++++++++ src/add-ons/kernel/file_systems/nfs4/Inode.cpp | 4 ++++ src/add-ons/kernel/file_systems/nfs4/Inode.h | 1 - src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp | 8 ++++++-- src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp | 11 +++-------- .../kernel/file_systems/nfs4/kernel_interface.cpp | 3 +++ ############################################################################ Commit: 1c6f50254980bd074b0035b6bf459a3dec2ce4ee Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Wed Jan 16 08:52:10 2013 UTC nfs4: Add not null assertions for Inode::fOpenState and fDelegation ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index 795a2a2..e2f3241 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -917,6 +917,8 @@ Inode::RecallReadDelegation() void Inode::ReturnDelegation(bool truncate) { + ASSERT(fDelegation != NULL); + fDelegation->GiveUp(truncate); fMetaCache.UnlockValid(); @@ -934,6 +936,8 @@ Inode::ReturnDelegation(bool truncate) void Inode::ReleaseOpenState() { + ASSERT(fOpenState != NULL); + if (fOpenState->ReleaseReference() == 1) fOpenState = NULL; } ############################################################################ Commit: 65edbee7c8940db313544516950b88bb5381fa70 Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Wed Jan 16 09:47:35 2013 UTC nfs4: DirectoryCache::GetSnapshot may return NULL ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h index 7abefb7..357ec6e 100644 --- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h +++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h @@ -54,7 +54,7 @@ public: bool created = false); void RemoveEntry(const char* name); - inline DirectoryCacheSnapshot* GetSnapshot(); + inline status_t GetSnapshot(DirectoryCacheSnapshot** snapshot); inline SinglyLinkedList<NameCacheEntry>& EntriesList(); @@ -113,12 +113,16 @@ DirectoryCache::Valid() } -inline DirectoryCacheSnapshot* -DirectoryCache::GetSnapshot() +inline status_t +DirectoryCache::GetSnapshot(DirectoryCacheSnapshot** snapshot) { + ASSERT(snapshot != NULL); + + status_t result = B_OK; if (fDirectoryCache == NULL) - _LoadSnapshot(false); - return fDirectoryCache; + result = _LoadSnapshot(false); + *snapshot = fDirectoryCache; + return result; } diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp index 10d2943..1b38517 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp @@ -324,8 +324,12 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, return result; } - DirectoryCacheSnapshot* snapshot = cache->GetSnapshot(); - ASSERT(snapshot != NULL); + DirectoryCacheSnapshot* snapshot; + result = cache->GetSnapshot(&snapshot); + if (result != B_OK) { + cache->Unlock(); + return result; + } cookie->fSnapshot = new DirectoryCacheSnapshot(*snapshot); cache->Unlock(); ############################################################################ Commit: ce851e2bac9dba986b6e4243e4cccd6f4e59380c Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Wed Jan 16 23:42:13 2013 UTC nfs4: Fix few Inode::fOpenState related race conditions ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp index 1d3d096..e76a010 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp @@ -39,6 +39,7 @@ FileSystem::FileSystem(const MountConfiguration& configuration) mutex_init(&fOpenOwnerLock, NULL); mutex_init(&fOpenLock, NULL); mutex_init(&fDelegationLock, NULL); + mutex_init(&fCreateFileLock, NULL); } @@ -51,6 +52,7 @@ FileSystem::~FileSystem() mutex_destroy(&fDelegationLock); mutex_destroy(&fOpenLock); mutex_destroy(&fOpenOwnerLock); + mutex_destroy(&fCreateFileLock); free(const_cast<char*>(fPath)); delete fRoot; diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.h b/src/add-ons/kernel/file_systems/nfs4/FileSystem.h index 87fa4b9..2d961b4 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.h +++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.h @@ -74,9 +74,12 @@ public: inline const MountConfiguration& GetConfiguration(); + inline mutex& CreateFileLock(); private: FileSystem(const MountConfiguration& config); + mutex fCreateFileLock; + mutex fDelegationLock; DoublyLinkedList<Delegation> fDelegationList; AVLTreeMap<FileHandle, Delegation*> fHandleToDelegation; @@ -233,5 +236,12 @@ FileSystem::GetConfiguration() } +inline mutex& +FileSystem::CreateFileLock() +{ + return fCreateFileLock; +} + + #endif // FILESYSTEM_H diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index da4802f..6fd5d77 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -221,7 +221,6 @@ inline void Inode::SetOpenState(OpenState* state) { ASSERT(state != NULL); - MutexLocker _(fStateLock); fOpenState = state; } diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp index 6c9d0a7..be6f926 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp @@ -76,20 +76,15 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie, cookie->fMode = mode; cookie->fLocks = NULL; - MutexLocker _(fStateLock); - OpenState* state = new OpenState; status_t result = CreateState(name, mode, perms, state, data); if (result != B_OK) return result; cookie->fOpenState = state; - fOpenState = state; + cookie->fFileSystem = fFileSystem; *id = FileIdToInoT(state->fInfo.fFileId); - cookie->fOpenState = fOpenState; - - cookie->fFileSystem = fFileSystem; fFileSystem->AddOpenFile(state); fFileSystem->Root()->MakeInfoInvalid(); @@ -125,9 +120,11 @@ Inode::Open(int mode, OpenFileCookie* cookie) fFileSystem->AddOpenFile(state); fOpenState = state; + cookie->fOpenState = state; locker.Unlock(); } else { fOpenState->AcquireReference(); + cookie->fOpenState = fOpenState; locker.Unlock(); int newMode = mode & O_RWMASK; @@ -167,8 +164,6 @@ Inode::Open(int mode, OpenFileCookie* cookie) file_cache_set_size(fFileCache, 0); } - cookie->fOpenState = fOpenState; - cookie->fFileSystem = fFileSystem; cookie->fMode = mode; cookie->fLocks = NULL; 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 af25fde..7abba1c 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -743,6 +743,9 @@ nfs4_create(fs_volume* volume, fs_vnode* dir, const char* name, int openMode, if (inode == NULL) return B_ENTRY_NOT_FOUND; + FileSystem* fs = reinterpret_cast<FileSystem*>(volume->private_volume); + MutexLocker createLocker(fs->CreateFileLock()); + OpenDelegationData data; status_t result = inode->Create(name, openMode, perms, cookie, &data, _newVnodeID);