diff --git a/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.cpp b/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.cpp deleted file mode 100644 index 5391c1264e..0000000000 --- a/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2012 Haiku, Inc. All rights reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Paweł Dziepak, pdziepak@quarnos.org - */ - - -#include "CacheRevalidator.h" - -#include - -#include "NFS4Defs.h" - - -CacheRevalidator::CacheRevalidator() - : - fThreadCancel(false), - fWaitCancel(create_sem(0, NULL)) -{ - mutex_init(&fDirectoryCachesLock, NULL); - - _StartRevalidator(); -} - - -CacheRevalidator::~CacheRevalidator() -{ - fThreadCancel = true; - release_sem(fWaitCancel); - status_t result; - wait_for_thread(fThread, &result); - - delete_sem(fThreadCancel); - mutex_destroy(&fDirectoryCachesLock); -} - - -status_t -CacheRevalidator::_StartRevalidator() -{ - fThreadCancel = false; - fThread = spawn_kernel_thread(&CacheRevalidator::_DirectoryRevalidatorStart, - "NFSv4 Cache Revalidator", B_NORMAL_PRIORITY, this); - if (fThread < B_OK) - return fThread; - - status_t result = resume_thread(fThread); - if (result != B_OK) { - kill_thread(fThread); - return result; - } - - return B_OK; -} - - -status_t -CacheRevalidator::_DirectoryRevalidatorStart(void* object) -{ - ASSERT(object != NULL); - - CacheRevalidator* revalidator = reinterpret_cast(object); - revalidator->_DirectoryCacheRevalidator(); - return B_OK; -} - - -void -CacheRevalidator::_DirectoryCacheRevalidator() -{ - while (!fThreadCancel) { - MutexLocker locker(fDirectoryCachesLock); - DirectoryCache* current = fDirectoryCaches.Head(); - - if (current == NULL) { - locker.Unlock(); - - status_t result = acquire_sem_etc(fWaitCancel, 1, - B_RELATIVE_TIMEOUT, DirectoryCache::kExpirationTime); - - if (result != B_TIMED_OUT) { - if (result == B_OK) - release_sem(fWaitCancel); - return; - } - continue; - } - - current->Lock(); - if (!current->Valid()) { - RemoveDirectory(current); - current->Unlock(); - continue; - } - - if (current->ExpireTime() > system_time()) { - current->Unlock(); - locker.Unlock(); - - status_t result = acquire_sem_etc(fWaitCancel, 1, - B_ABSOLUTE_TIMEOUT, current->ExpireTime()); - if (result != B_TIMED_OUT) { - if (result == B_OK) - release_sem(fWaitCancel); - return; - } - - continue; - } - - fDirectoryCaches.RemoveHead(); - current->fRevalidated = false; - - if (current->Revalidate() == B_OK) - AddDirectory(current); - - current->Unlock(); - } -} - diff --git a/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.h b/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.h deleted file mode 100644 index a4764dcdbf..0000000000 --- a/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012 Haiku, Inc. All rights reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Paweł Dziepak, pdziepak@quarnos.org - */ -#ifndef CACHEREVALIDATOR_H -#define CACHEREVALIDATOR_H - - -#include -#include -#include - -#include "DirectoryCache.h" - - -class CacheRevalidator { -public: - CacheRevalidator(); - ~CacheRevalidator(); - - inline void Lock(); - inline void Unlock(); - - - inline void AddDirectory(DirectoryCache* cache); - inline void RemoveDirectory(DirectoryCache* cache); - -private: - void _DirectoryCacheRevalidator(); - static status_t _DirectoryRevalidatorStart(void* object); - status_t _StartRevalidator(); - - thread_id fThread; - bool fThreadCancel; - sem_id fWaitCancel; - - DoublyLinkedList fDirectoryCaches; - mutex fDirectoryCachesLock; -}; - - -inline void -CacheRevalidator::Lock() -{ - mutex_lock(&fDirectoryCachesLock); -} - - -inline void -CacheRevalidator::Unlock() -{ - mutex_unlock(&fDirectoryCachesLock); -} - - -inline void -CacheRevalidator::AddDirectory(DirectoryCache* cache) -{ - ASSERT(cache != NULL); - - if (!cache->fRevalidated) { - cache->fRevalidated = true; - fDirectoryCaches.InsertAfter(fDirectoryCaches.Tail(), cache); - } -} - - -inline void -CacheRevalidator::RemoveDirectory(DirectoryCache* cache) -{ - ASSERT(cache != NULL); - - if (cache->fRevalidated == true) - fDirectoryCaches.Remove(cache); - cache->fRevalidated = false; -} - - -#endif // CACHEREVALIDATOR_H - diff --git a/src/add-ons/kernel/file_systems/nfs4/Cookie.h b/src/add-ons/kernel/file_systems/nfs4/Cookie.h index c8956eec58..a3d36c9c8c 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Cookie.h +++ b/src/add-ons/kernel/file_systems/nfs4/Cookie.h @@ -11,6 +11,7 @@ #include +#include "DirectoryCache.h" #include "FileSystem.h" diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp index 923ae53e75..c40707a35d 100644 --- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp @@ -92,10 +92,6 @@ DirectoryCache::DirectoryCache(Inode* inode, bool attr) DirectoryCache::~DirectoryCache() { - fInode->GetFileSystem()->Revalidator().Lock(); - fInode->GetFileSystem()->Revalidator().RemoveDirectory(this); - fInode->GetFileSystem()->Revalidator().Unlock(); - mutex_destroy(&fLock); } @@ -119,7 +115,7 @@ DirectoryCache::Trash() delete current; } - SetSnapshot(NULL); + _SetSnapshot(NULL); fTrashed = true; } @@ -207,7 +203,7 @@ DirectoryCache::RemoveEntry(const char* name) void -DirectoryCache::SetSnapshot(DirectoryCacheSnapshot* snapshot) +DirectoryCache::_SetSnapshot(DirectoryCacheSnapshot* snapshot) { if (fDirectoryCache != NULL) fDirectoryCache->ReleaseReference(); @@ -215,9 +211,48 @@ DirectoryCache::SetSnapshot(DirectoryCacheSnapshot* snapshot) } +status_t +DirectoryCache::_LoadSnapshot(bool trash) +{ + DirectoryCacheSnapshot* oldSnapshot = fDirectoryCache; + if (oldSnapshot != NULL) + oldSnapshot->AcquireReference(); + + if (trash) + Trash(); + + DirectoryCacheSnapshot* newSnapshot; + status_t result = fInode->GetDirSnapshot(&newSnapshot, NULL, &fChange, + fAttrDir); + if (result != B_OK) { + if (oldSnapshot != NULL) + oldSnapshot->ReleaseReference(); + return result; + } + newSnapshot->AcquireReference(); + + _SetSnapshot(newSnapshot); + fExpireTime = system_time() + kExpirationTime; + + fTrashed = false; + + if (oldSnapshot != NULL) + NotifyChanges(oldSnapshot, newSnapshot); + + if (oldSnapshot != NULL) + oldSnapshot->ReleaseReference(); + + newSnapshot->ReleaseReference(); + return B_OK; +} + + status_t DirectoryCache::Revalidate() { + if (fExpireTime < system_time()) + return B_OK; + uint64 change; if (fInode->GetChangeInfo(&change, fAttrDir) != B_OK) { Trash(); @@ -229,34 +264,7 @@ DirectoryCache::Revalidate() return B_OK; } - DirectoryCacheSnapshot* oldSnapshot = fDirectoryCache; - if (oldSnapshot == NULL) { - Trash(); - return B_ERROR; - } - - oldSnapshot->AcquireReference(); - - Trash(); - - DirectoryCacheSnapshot* newSnapshot; - status_t result = fInode->GetDirSnapshot(&newSnapshot, NULL, &fChange, - fAttrDir); - if (result != B_OK) { - oldSnapshot->ReleaseReference(); - return B_ERROR; - } - newSnapshot->AcquireReference(); - - SetSnapshot(newSnapshot); - fExpireTime = system_time() + kExpirationTime; - fTrashed = false; - - NotifyChanges(oldSnapshot, newSnapshot); - oldSnapshot->ReleaseReference(); - newSnapshot->ReleaseReference(); - - return B_OK; + return _LoadSnapshot(true); } diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h index 5cc68545e4..7abefb7d91 100644 --- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h +++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h @@ -38,7 +38,7 @@ struct DirectoryCacheSnapshot : public KernelReferenceable { ~DirectoryCacheSnapshot(); }; -class DirectoryCache : public DoublyLinkedListLinkImpl { +class DirectoryCache { public: DirectoryCache(Inode* inode, bool attr = false); ~DirectoryCache(); @@ -54,7 +54,6 @@ public: bool created = false); void RemoveEntry(const char* name); - void SetSnapshot(DirectoryCacheSnapshot* snapshot); inline DirectoryCacheSnapshot* GetSnapshot(); inline SinglyLinkedList& EntriesList(); @@ -66,7 +65,6 @@ public: inline uint64 ChangeInfo(); inline Inode* GetInode(); - inline time_t ExpireTime(); static const bigtime_t kExpirationTime = 15000000; @@ -76,6 +74,9 @@ protected: DirectoryCacheSnapshot* newSnapshot); private: + void _SetSnapshot(DirectoryCacheSnapshot* snapshot); + status_t _LoadSnapshot(bool trash); + SinglyLinkedList fNameCache; DirectoryCacheSnapshot* fDirectoryCache; @@ -115,6 +116,8 @@ DirectoryCache::Valid() inline DirectoryCacheSnapshot* DirectoryCache::GetSnapshot() { + if (fDirectoryCache == NULL) + _LoadSnapshot(false); return fDirectoryCache; } @@ -164,12 +167,5 @@ DirectoryCache::GetInode() } -inline time_t -DirectoryCache::ExpireTime() -{ - return fExpireTime; -} - - #endif // DIRECTORYCACHE_H diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.h b/src/add-ons/kernel/file_systems/nfs4/FileSystem.h index d1f0c8b343..67e39967d4 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.h +++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.h @@ -9,7 +9,6 @@ #define FILESYSTEM_H -#include "CacheRevalidator.h" #include "Delegation.h" #include "InodeIdMap.h" #include "NFS4Defs.h" @@ -51,8 +50,6 @@ public: void RemoveDelegation(Delegation* delegation); Delegation* GetDelegation(const FileHandle& handle); - inline CacheRevalidator& Revalidator(); - inline bool IsAttrSupported(Attribute attr) const; inline uint32 ExpireType() const; @@ -79,8 +76,6 @@ public: private: FileSystem(const MountConfiguration& config); - CacheRevalidator fCacheRevalidator; - mutex fDelegationLock; DoublyLinkedList fDelegationList; AVLTreeMap fHandleToDelegation; @@ -113,13 +108,6 @@ private: }; -inline CacheRevalidator& -FileSystem::Revalidator() -{ - return fCacheRevalidator; -} - - inline RootInode* FileSystem::Root() { diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index be79b53f70..795a2a206b 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -204,20 +204,15 @@ Inode::LookUp(const char* name, ino_t* id) if (result != B_OK) return result; - fFileSystem->Revalidator().Lock(); fCache->Lock(); if (!fCache->Valid()) { fCache->Reset(); fCache->SetChangeInfo(change); - } else { - fFileSystem->Revalidator().RemoveDirectory(fCache); + } else fCache->ValidateChangeInfo(change); - } fCache->AddEntry(name, *id); - fFileSystem->Revalidator().AddDirectory(fCache); fCache->Unlock(); - fFileSystem->Revalidator().Unlock(); return B_OK; } diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index e72aadbc46..da4802fe8c 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -9,6 +9,7 @@ #define INODE_H +#include "DirectoryCache.h" #include "MetadataCache.h" #include "NFS4Inode.h" #include "OpenState.h" diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp index 2b71dce1e3..10d2943a6c 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp @@ -317,30 +317,21 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, status_t result; DirectoryCache* cache = cookie->fAttrDir ? fAttrCache : fCache; if (cookie->fSnapshot == NULL) { - fFileSystem->Revalidator().Lock(); cache->Lock(); - if (!cache->Valid()) - cache->Reset(); - else - fFileSystem->Revalidator().RemoveDirectory(cache); + result = cache->Revalidate(); + if (result != B_OK) { + cache->Unlock(); + return result; + } DirectoryCacheSnapshot* snapshot = cache->GetSnapshot(); - if (snapshot == NULL) { - uint64 change; - result = GetDirSnapshot(&snapshot, cookie, &change, - cookie->fAttrDir); - if (result != B_OK) { - cache->Unlock(); - fFileSystem->Revalidator().Unlock(); - return result; - } - cache->ValidateChangeInfo(change); - cache->SetSnapshot(snapshot); - } + ASSERT(snapshot != NULL); + cookie->fSnapshot = new DirectoryCacheSnapshot(*snapshot); - fFileSystem->Revalidator().AddDirectory(cache); cache->Unlock(); - fFileSystem->Revalidator().Unlock(); + + if (cookie->fSnapshot == NULL) + return B_NO_MEMORY; } char* buffer = reinterpret_cast(_buffer); diff --git a/src/add-ons/kernel/file_systems/nfs4/Jamfile b/src/add-ons/kernel/file_systems/nfs4/Jamfile index c77e63402f..3d678a9001 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Jamfile +++ b/src/add-ons/kernel/file_systems/nfs4/Jamfile @@ -4,7 +4,6 @@ UsePrivateKernelHeaders ; UsePrivateHeaders shared ; KernelAddon nfs4 : - CacheRevalidator.cpp Cookie.cpp Connection.cpp Delegation.cpp