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);
|
||||
}
|
||||
if (entry != NULL) {
|
||||
// we are skipping ChildAdded(); verify that it is not needed because the InoIdMap
|
||||
// already has this entry
|
||||
// Verify that the InoIdMap already has an entry for this inode.
|
||||
// If not, we need to get the file handle from the server and call ChildAdded().
|
||||
FileInfo info;
|
||||
result = fFileSystem->InoIdMap()->GetFileInfo(&info, entry->fNode);
|
||||
ASSERT(result == B_OK);
|
||||
|
||||
*id = entry->fNode;
|
||||
fCache->Unlock();
|
||||
return B_OK;
|
||||
if (result == B_OK) {
|
||||
*id = entry->fNode;
|
||||
fCache->Unlock();
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
fCache->Unlock();
|
||||
@@ -265,6 +265,7 @@ Inode::Link(Inode* dir, const char* name)
|
||||
|
||||
fFileSystem->Root()->MakeInfoInvalid();
|
||||
fInfo.fNames->AddName(dir->fInfo.fNames, name);
|
||||
fMetaCache.InvalidateStat();
|
||||
|
||||
dir->fCache->Lock();
|
||||
if (dir->fCache->Valid()) {
|
||||
@@ -385,7 +386,24 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName,
|
||||
if (oldID != NULL)
|
||||
*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();
|
||||
if (cache->Valid()) {
|
||||
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())
|
||||
return B_OK;
|
||||
|
||||
// Verify that all known names have been unlinked.
|
||||
FileInfo fileInfo;
|
||||
ASSERT(fs->InoIdMap()->GetFileInfo(&fileInfo, vti->ID()) == B_ENTRY_NOT_FOUND);
|
||||
// Unless the file was deleted by someone else, verify that all known names have been
|
||||
// unlinked.
|
||||
if (node->IsStale() == false) {
|
||||
FileInfo fileInfo;
|
||||
ASSERT(fs->InoIdMap()->GetFileInfo(&fileInfo, vti->ID()) == B_ENTRY_NOT_FOUND);
|
||||
}
|
||||
|
||||
delete vti;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user