nfs4: Local creation of node should not invalidate the cache

This commit is contained in:
Pawel Dziepak
2012-07-20 04:09:16 +02:00
parent 6b9a91eb66
commit 7cac2f6e50
4 changed files with 105 additions and 16 deletions
@@ -87,9 +87,9 @@ DirectoryCache::Trash()
fTrashed = true; fTrashed = true;
} }
// TODO: separate AddEntry() for Name and Directory Cache are needed
status_t status_t
DirectoryCache::AddEntry(const char* name, ino_t node) DirectoryCache::AddEntry(const char* name, ino_t node, bool created)
{ {
NameCacheEntry* entry = new(std::nothrow) NameCacheEntry(name, node); NameCacheEntry* entry = new(std::nothrow) NameCacheEntry(name, node);
if (entry == NULL) if (entry == NULL)
@@ -101,6 +101,19 @@ DirectoryCache::AddEntry(const char* name, ino_t node)
fNameCache.Add(entry); fNameCache.Add(entry);
if (created && fDirectoryCache != NULL) {
MutexLocker _(fDirectoryCache->fLock);
NameCacheEntry* entry = new(std::nothrow) NameCacheEntry(name, node);
if (entry == NULL)
return B_NO_MEMORY;
if (entry->fName == NULL) {
delete entry;
return B_NO_MEMORY;
}
fDirectoryCache->fEntries.Add(entry);
}
return entry_cache_add(fInode->GetFileSystem()->DevId(), fInode->ID(), name, return entry_cache_add(fInode->GetFileSystem()->DevId(), fInode->ID(), name,
node); node);
} }
@@ -46,7 +46,8 @@ public:
void ResetAndLock(); void ResetAndLock();
void Trash(); void Trash();
status_t AddEntry(const char* name, ino_t node); status_t AddEntry(const char* name, ino_t node,
bool created = false);
void RemoveEntry(const char* name); void RemoveEntry(const char* name);
void SetSnapshot(DirectoryCacheSnapshot* snapshot); void SetSnapshot(DirectoryCacheSnapshot* snapshot);
@@ -68,7 +69,6 @@ private:
SinglyLinkedList<NameCacheEntry> fNameCache; SinglyLinkedList<NameCacheEntry> fNameCache;
DirectoryCacheSnapshot* fDirectoryCache; DirectoryCacheSnapshot* fDirectoryCache;
//mutex fDirectoryCacheLock;
Inode* fInode; Inode* fInode;
+69 -9
View File
@@ -281,6 +281,10 @@ Inode::Link(Inode* dir, const char* name)
req.PutFH(dir->fInfo.fHandle); req.PutFH(dir->fInfo.fHandle);
req.Link(name); req.Link(name);
req.LookUp(name);
Attribute attr[] = { FATTR4_FILEID };
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
status_t result = request.Send(); status_t result = request.Send();
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -310,10 +314,27 @@ Inode::Link(Inode* dir, const char* name)
if (result != B_OK) if (result != B_OK)
return result; return result;
result = reply.LookUp();
if (result != B_OK)
return result;
AttrValue* values;
uint32 count;
result = reply.GetAttr(&values, &count);
if (result != B_OK)
return result;
uint32 fileID;
if (count == 0)
fileID = fFileSystem->AllocFileId();
else
fileID = values[1].fData.fValue64;
fFileSystem->Root()->MakeInfoInvalid();
if (fCache->Lock() == B_OK) { if (fCache->Lock() == B_OK) {
if (atomic && fCache->ChangeInfo() == before) { if (atomic && fCache->ChangeInfo() == before) {
// TODO: update cache fCache->AddEntry(name, fileID, true);
//fCache->AddEntry(name, );
fCache->SetChangeInfo(after); fCache->SetChangeInfo(after);
} else if (fCache->ChangeInfo() != before) } else if (fCache->ChangeInfo() != before)
fCache->Trash(); fCache->Trash();
@@ -418,6 +439,10 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName)
req.PutFH(to->fInfo.fHandle); req.PutFH(to->fInfo.fHandle);
req.Rename(fromName, toName); req.Rename(fromName, toName);
Attribute attr[] = { FATTR4_FILEID };
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
req.LookUp(toName);
status_t result = request.Send(); status_t result = request.Send();
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -445,6 +470,26 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName)
bool fromAtomic, toAtomic; bool fromAtomic, toAtomic;
result = reply.Rename(&fromBefore, &fromAfter, fromAtomic, &toBefore, result = reply.Rename(&fromBefore, &fromAfter, fromAtomic, &toBefore,
&toAfter, toAtomic); &toAfter, toAtomic);
if (result != B_OK)
return result;
result = reply.LookUp();
if (result != B_OK)
return result;
AttrValue* values;
uint32 count;
result = reply.GetAttr(&values, &count);
if (result != B_OK)
return result;
uint32 fileID;
if (count == 0)
fileID = from->fFileSystem->AllocFileId();
else
fileID = values[1].fData.fValue64;
from->fFileSystem->Root()->MakeInfoInvalid();
if (from->fCache->Lock() == B_OK) { if (from->fCache->Lock() == B_OK) {
if (fromAtomic && from->fCache->ChangeInfo() == fromBefore) { if (fromAtomic && from->fCache->ChangeInfo() == fromBefore) {
@@ -457,15 +502,14 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName)
if (to->fCache->Lock() == B_OK) { if (to->fCache->Lock() == B_OK) {
if (toAtomic && to->fCache->ChangeInfo() == toBefore) { if (toAtomic && to->fCache->ChangeInfo() == toBefore) {
// TODO: update cache to->fCache->AddEntry(toName, fileID, true);
//fCache->AddEntry(toName, );
to->fCache->SetChangeInfo(toAfter); to->fCache->SetChangeInfo(toAfter);
} else if (to->fCache->ChangeInfo() != toBefore) } else if (to->fCache->ChangeInfo() != toBefore)
to->fCache->Trash(); to->fCache->Trash();
to->fCache->Unlock(); to->fCache->Unlock();
}; }
return result; return B_OK;
} while (true); } while (true);
} }
@@ -505,6 +549,9 @@ Inode::CreateLink(const char* name, const char* path, int mode)
req.Create(NF4LNK, name, cattr, i, path); req.Create(NF4LNK, name, cattr, i, path);
Attribute attr[] = { FATTR4_FILEID };
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
status_t result = request.Send(); status_t result = request.Send();
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -523,20 +570,33 @@ Inode::CreateLink(const char* name, const char* path, int mode)
uint64 before, after; uint64 before, after;
bool atomic; bool atomic;
result = reply.Create(&before, &after, atomic); result = reply.Create(&before, &after, atomic);
if (result != B_OK)
return result;
AttrValue* values;
uint32 count;
result = reply.GetAttr(&values, &count);
if (result != B_OK)
return result;
uint32 fileID;
if (count == 0)
fileID = fFileSystem->AllocFileId();
else
fileID = values[1].fData.fValue64;
fFileSystem->Root()->MakeInfoInvalid(); fFileSystem->Root()->MakeInfoInvalid();
if (fCache->Lock() == B_OK) { if (fCache->Lock() == B_OK) {
if (atomic && fCache->ChangeInfo() == before) { if (atomic && fCache->ChangeInfo() == before) {
// TODO: update cache fCache->AddEntry(name, fileID, true);
//fCache->AddEntry(name, );
fCache->SetChangeInfo(after); fCache->SetChangeInfo(after);
} else if (fCache->ChangeInfo() != before) } else if (fCache->ChangeInfo() != before)
fCache->Trash(); fCache->Trash();
fCache->Unlock(); fCache->Unlock();
} }
return result; return B_OK;
} while (true); } while (true);
} }
@@ -52,6 +52,9 @@ Inode::CreateDir(const char* name, int mode)
req.Create(NF4DIR, name, cattr, i); req.Create(NF4DIR, name, cattr, i);
Attribute attr[] = { FATTR4_FILEID };
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
status_t result = request.Send(); status_t result = request.Send();
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -70,20 +73,33 @@ Inode::CreateDir(const char* name, int mode)
uint64 before, after; uint64 before, after;
bool atomic; bool atomic;
result = reply.Create(&before, &after, atomic); result = reply.Create(&before, &after, atomic);
if (result != B_OK)
return result;
AttrValue* values;
uint32 count;
result = reply.GetAttr(&values, &count);
if (result != B_OK)
return result;
uint32 fileID;
if (count == 0)
fileID = fFileSystem->AllocFileId();
else
fileID = values[1].fData.fValue64;
fFileSystem->Root()->MakeInfoInvalid(); fFileSystem->Root()->MakeInfoInvalid();
if (fCache->Lock() == B_OK) { if (fCache->Lock() == B_OK) {
if (atomic && fCache->ChangeInfo() == before) { if (atomic && fCache->ChangeInfo() == before) {
// TODO: update cache fCache->AddEntry(name, fileID, true);
//fCache->AddEntry(name, );
fCache->SetChangeInfo(after); fCache->SetChangeInfo(after);
} else if (fCache->ChangeInfo() != before) } else if (fCache->ChangeInfo() != before)
fCache->Trash(); fCache->Trash();
fCache->Unlock(); fCache->Unlock();
} }
return result; return B_OK;
} while (true); } while (true);
} }