nfs4: Fix minor private cache issues
* Allow Inode::LookUp to handle the case in which the inode number in a DirectoryCache entry has no corresponding entry in the InoIdMap. This situation can occur after an unused node is freed (due to low system resources), since ~VnodeToInode will remove the node's InoIdMap entry. * When a file is overwritten by a rename operation, remove the overwritten file's entry from the parent DirectoryCache (although a file with this name is still present in the directory, the old DirectoryCache entry is now invalid because the name is now linked to a different inode). * Invalidate the cached stat info, including the number of links, in Inode::fMetaCache when linking to that inode. * Make a correction to the assert added in https://review.haiku-os.org/c/haiku/+/9282. Entries may still be left in this client's InoIdMap if the file was deleted by another client. Change-Id: Id437be32e51a4b324eb818b398d7facd23b7be56 Reviewed-on: https://review.haiku-os.org/c/haiku/+/9308 Tested-by: Commit checker robot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
@@ -212,15 +212,15 @@ Inode::LookUp(const char* name, ino_t* id)
|
|||||||
entry = entriesList.GetNext(entry);
|
entry = entriesList.GetNext(entry);
|
||||||
}
|
}
|
||||||
if (entry != NULL) {
|
if (entry != NULL) {
|
||||||
// we are skipping ChildAdded(); verify that it is not needed because the InoIdMap
|
// Verify that the InoIdMap already has an entry for this inode.
|
||||||
// already has this entry
|
// If not, we need to get the file handle from the server and call ChildAdded().
|
||||||
FileInfo info;
|
FileInfo info;
|
||||||
result = fFileSystem->InoIdMap()->GetFileInfo(&info, entry->fNode);
|
result = fFileSystem->InoIdMap()->GetFileInfo(&info, entry->fNode);
|
||||||
ASSERT(result == B_OK);
|
if (result == B_OK) {
|
||||||
|
*id = entry->fNode;
|
||||||
*id = entry->fNode;
|
fCache->Unlock();
|
||||||
fCache->Unlock();
|
return B_OK;
|
||||||
return B_OK;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fCache->Unlock();
|
fCache->Unlock();
|
||||||
@@ -265,6 +265,7 @@ Inode::Link(Inode* dir, const char* name)
|
|||||||
|
|
||||||
fFileSystem->Root()->MakeInfoInvalid();
|
fFileSystem->Root()->MakeInfoInvalid();
|
||||||
fInfo.fNames->AddName(dir->fInfo.fNames, name);
|
fInfo.fNames->AddName(dir->fInfo.fNames, name);
|
||||||
|
fMetaCache.InvalidateStat();
|
||||||
|
|
||||||
dir->fCache->Lock();
|
dir->fCache->Lock();
|
||||||
if (dir->fCache->Valid()) {
|
if (dir->fCache->Valid()) {
|
||||||
@@ -385,7 +386,24 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName,
|
|||||||
if (oldID != NULL)
|
if (oldID != NULL)
|
||||||
*oldID = FileIdToInoT(oldFileID);
|
*oldID = FileIdToInoT(oldFileID);
|
||||||
|
|
||||||
DirectoryCache* cache = attribute ? from->fAttrCache : from->fCache;
|
DirectoryCache* cache = NULL;
|
||||||
|
if (*oldID != 0) {
|
||||||
|
// If we overwrote an existing file, remove the DirectoryCache entry of
|
||||||
|
// the overwritten file, which now contains an incorrect inode value.
|
||||||
|
cache = attribute ? to->fAttrCache : to->fCache;
|
||||||
|
cache->Lock();
|
||||||
|
if (cache->Valid()) {
|
||||||
|
if (toChange.fAtomic
|
||||||
|
&& (cache->ChangeInfo() == toChange.fBefore)) {
|
||||||
|
cache->RemoveEntry(toName);
|
||||||
|
} else {
|
||||||
|
cache->Trash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cache->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
cache = attribute ? from->fAttrCache : from->fCache;
|
||||||
cache->Lock();
|
cache->Lock();
|
||||||
if (cache->Valid()) {
|
if (cache->Valid()) {
|
||||||
if (fromChange.fAtomic && cache->ChangeInfo() == fromChange.fBefore) {
|
if (fromChange.fAtomic && cache->ChangeInfo() == fromChange.fBefore) {
|
||||||
|
|||||||
@@ -341,9 +341,12 @@ nfs4_remove_vnode(fs_volume* volume, fs_vnode* vnode, bool reenter)
|
|||||||
if (node == fs->Root())
|
if (node == fs->Root())
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
// Verify that all known names have been unlinked.
|
// Unless the file was deleted by someone else, verify that all known names have been
|
||||||
FileInfo fileInfo;
|
// unlinked.
|
||||||
ASSERT(fs->InoIdMap()->GetFileInfo(&fileInfo, vti->ID()) == B_ENTRY_NOT_FOUND);
|
if (node->IsStale() == false) {
|
||||||
|
FileInfo fileInfo;
|
||||||
|
ASSERT(fs->InoIdMap()->GetFileInfo(&fileInfo, vti->ID()) == B_ENTRY_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
delete vti;
|
delete vti;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user