nfs4: Fix some cache revalidator problems

This commit is contained in:
Pawel Dziepak
2012-09-14 19:00:30 +02:00
parent e422d059c8
commit cae470f922
7 changed files with 47 additions and 33 deletions
@@ -86,8 +86,12 @@ CacheRevalidator::_DirectoryCacheRevalidator()
continue;
}
if (current->Lock() != B_OK)
current->Lock();
if (!current->Valid()) {
RemoveDirectory(current);
current->Unlock();
continue;
}
if (current->ExpireTime() > system_time()) {
current->Unlock();
@@ -110,7 +114,6 @@ CacheRevalidator::_DirectoryCacheRevalidator()
if (current->Revalidate() == B_OK)
AddDirectory(current);
locker.Unlock();
current->Unlock();
}
}
@@ -58,8 +58,10 @@ CacheRevalidator::Unlock()
inline void
CacheRevalidator::AddDirectory(DirectoryCache* cache)
{
if (!cache->fRevalidated) {
cache->fRevalidated = true;
fDirectoryCaches.InsertAfter(fDirectoryCaches.Tail(), cache);
}
}
@@ -70,9 +70,8 @@ DirectoryCache::~DirectoryCache()
void
DirectoryCache::ResetAndLock()
DirectoryCache::Reset()
{
mutex_lock(&fLock);
Trash();
fExpireTime = system_time() + kExpirationTime;
fTrashed = false;
@@ -40,11 +40,12 @@ public:
DirectoryCache(Inode* inode, bool attr = false);
~DirectoryCache();
inline status_t Lock();
inline void Lock();
inline void Unlock();
void ResetAndLock();
void Reset();
void Trash();
inline bool Valid();
status_t AddEntry(const char* name, ino_t node,
bool created = false);
@@ -87,18 +88,13 @@ private:
};
inline status_t
inline void
DirectoryCache::Lock()
{
mutex_lock(&fLock);
if (fTrashed) {
mutex_unlock(&fLock);
return B_ERROR;
}
return B_OK;
}
inline void
DirectoryCache::Unlock()
{
@@ -106,6 +102,13 @@ DirectoryCache::Unlock()
}
inline bool
DirectoryCache::Valid()
{
return !fTrashed;
}
inline DirectoryCacheSnapshot*
DirectoryCache::GetSnapshot()
{
+18 -12
View File
@@ -197,8 +197,9 @@ Inode::LookUp(const char* name, ino_t* id)
return result;
fFileSystem->Revalidator().Lock();
if (fCache->Lock() != B_OK) {
fCache->ResetAndLock();
fCache->Lock();
if (!fCache->Valid()) {
fCache->Reset();
fCache->SetChangeInfo(change);
} else {
fFileSystem->Revalidator().RemoveDirectory(fCache);
@@ -232,15 +233,16 @@ Inode::Link(Inode* dir, const char* name)
fFileSystem->InoIdMap()->AddEntry(fi, fInfo.fFileId);
if (dir->fCache->Lock() == B_OK) {
dir->fCache->Lock();
if (dir->fCache->Valid()) {
if (changeInfo.fAtomic
&& dir->fCache->ChangeInfo() == changeInfo.fBefore) {
dir->fCache->AddEntry(name, fInfo.fFileId, true);
dir->fCache->SetChangeInfo(changeInfo.fAfter);
} else if (dir->fCache->ChangeInfo() != changeInfo.fBefore)
dir->fCache->Trash();
dir->fCache->Unlock();
}
dir->fCache->Unlock();
notify_entry_created(fFileSystem->DevId(), dir->ID(), name, ID());
@@ -270,15 +272,16 @@ Inode::Remove(const char* name, FileType type, ino_t* id)
return result;
DirectoryCache* cache = type != NF4NAMEDATTR ? fCache : fAttrCache;
if (cache->Lock() == B_OK) {
cache->Lock();
if (cache->Valid()) {
if (changeInfo.fAtomic
&& fCache->ChangeInfo() == changeInfo.fBefore) {
cache->RemoveEntry(name);
cache->SetChangeInfo(changeInfo.fAfter);
} else if (cache->ChangeInfo() != changeInfo.fBefore)
cache->Trash();
cache->Unlock();
}
cache->Unlock();
fFileSystem->Root()->MakeInfoInvalid();
if (id != NULL)
@@ -333,29 +336,31 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName,
from->fFileSystem->Root()->MakeInfoInvalid();
DirectoryCache* cache = attribute ? from->fAttrCache : from->fCache;
if (cache->Lock() == B_OK) {
cache->Lock();
if (cache->Valid()) {
if (fromChange.fAtomic
&& cache->ChangeInfo() == fromChange.fBefore) {
cache->RemoveEntry(fromName);
cache->SetChangeInfo(fromChange.fAfter);
} else if (cache->ChangeInfo() != fromChange.fBefore)
cache->Trash();
cache->Unlock();
}
cache->Unlock();
if (id != NULL)
*id = FileIdToInoT(fileID);
cache = attribute ? to->fAttrCache : to->fCache;
if (cache->Lock() == B_OK) {
cache->Lock();
if (cache->Valid()) {
if (toChange.fAtomic
&& cache->ChangeInfo() == toChange.fBefore) {
cache->AddEntry(toName, fileID, true);
cache->SetChangeInfo(toChange.fAfter);
} else if (to->fCache->ChangeInfo() != toChange.fBefore)
cache->Trash();
cache->Unlock();
}
cache->Unlock();
if (attribute) {
notify_attribute_changed(from->fFileSystem->DevId(), from->ID(),
@@ -396,14 +401,15 @@ Inode::CreateObject(const char* name, const char* path, int mode, FileType type)
if (result != B_OK)
return B_OK;
if (fCache->Lock() == B_OK) {
fCache->Lock();
if (fCache->Valid()) {
if (changeInfo.fAtomic && fCache->ChangeInfo() == changeInfo.fBefore) {
fCache->AddEntry(name, fileID, true);
fCache->SetChangeInfo(changeInfo.fAfter);
} else if (fCache->ChangeInfo() != changeInfo.fBefore)
fCache->Trash();
fCache->Unlock();
}
fCache->Unlock();
notify_entry_created(fFileSystem->DevId(), ID(), name,
FileIdToInoT(fileID));
@@ -302,11 +302,11 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count,
DirectoryCache* cache = cookie->fAttrDir ? fAttrCache : fCache;
if (cookie->fSnapshot == NULL) {
fFileSystem->Revalidator().Lock();
if (cache->Lock() != B_OK) {
cache->ResetAndLock();
} else {
cache->Lock();
if (!cache->Valid())
cache->Reset();
else
fFileSystem->Revalidator().RemoveDirectory(cache);
}
cookie->fSnapshot = cache->GetSnapshot();
if (cookie->fSnapshot == NULL) {
@@ -42,15 +42,16 @@ Inode::CreateState(const char* name, int mode, int perms, OpenState* state,
fFileSystem->InoIdMap()->AddEntry(fi, FileIdToInoT(fileID));
if (fCache->Lock() == B_OK) {
fCache->Lock();
if (fCache->Valid()) {
if (changeInfo.fAtomic
&& fCache->ChangeInfo() == changeInfo.fBefore) {
fCache->AddEntry(name, fileID, true);
fCache->SetChangeInfo(changeInfo.fAfter);
} else if (fCache->ChangeInfo() != changeInfo.fBefore)
fCache->Trash();
fCache->Unlock();
}
fCache->Unlock();
state->fFileSystem = fFileSystem;
state->fInfo = fi;