nfs4: Local creation of node should not invalidate the cache
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user