diff --git a/eden/fs/inodes/TreeInode.cpp b/eden/fs/inodes/TreeInode.cpp index 8b94f2aaae..696645b283 100644 --- a/eden/fs/inodes/TreeInode.cpp +++ b/eden/fs/inodes/TreeInode.cpp @@ -1284,13 +1284,15 @@ int TreeInode::tryRemoveChild( deletedInode.reset(); #ifdef _WIN32 - cleanupPrjfsCache(name); + // TODO(xavierd): remove the ifdef once we know if we are called from + // ProjectedFS + invalidateChannelEntryCache(name); #else // We have successfully removed the entry. // Flush the kernel cache for this entry if requested. if (flushKernelCache) { invalidateFuseInodeCache(); - invalidateFuseEntryCache(name); + invalidateChannelEntryCache(name); } #endif @@ -2706,11 +2708,7 @@ unique_ptr TreeInode::processCheckoutEntry( // after this inode processes all of its checkout actions. But we // do want to invalidate the kernel's dcache and inode caches. wasDirectoryListModified = true; -#ifndef _WIN32 - invalidateFuseEntryCache(name); -#else - cleanupPrjfsCache(name); -#endif // !_WIN32 + invalidateChannelEntryCache(name); } // Nothing else to do when there is no local inode. @@ -2821,19 +2819,14 @@ unique_ptr TreeInode::processCheckoutEntry( << ")"; getOverlay()->recursivelyRemoveOverlayData(oldEntryInodeNumber); } +#endif // TODO: contents have changed: we probably should propagate // this information up to our caller so it can mark us // materialized if necessary. // We removed or replaced an entry - invalidate it. - auto* fuseChannel = getMount()->getFuseChannel(); - if (fuseChannel) { - fuseChannel->invalidateEntry(getNodeId(), name); - } -#else - cleanupPrjfsCache(name); -#endif // !_WIN32 + invalidateChannelEntryCache(name); return nullptr; } @@ -2888,12 +2881,9 @@ Future TreeInode::checkoutUpdateEntry( } } - // Tell FUSE to invalidate its cache for this entry. -#ifndef _WIN32 - invalidateFuseEntryCache(name); -#else - cleanupPrjfsCache(name); -#endif + // Tell the OS to invalidate its cache for this entry. + invalidateChannelEntryCache(name); + // We don't save our own overlay data right now: // we'll wait to do that until the checkout operation finishes touching all // of our children in checkout(). @@ -2986,6 +2976,21 @@ Future TreeInode::checkoutUpdateEntry( }); } +void TreeInode::invalidateChannelEntryCache(PathComponentPiece name) { +#ifndef _WIN32 + if (auto* fuseChannel = getMount()->getFuseChannel()) { + fuseChannel->invalidateEntry(getNodeId(), name); + } +#else + if (auto* fsChannel = getMount()->getFsChannel()) { + const auto path = getPath(); + if (path.has_value()) { + fsChannel->removeCachedFile(path.value() + name); + } + } +#endif +} + #ifndef _WIN32 void TreeInode::invalidateFuseInodeCache() { if (auto* fuseChannel = getMount()->getFuseChannel()) { @@ -3004,28 +3009,12 @@ void TreeInode::invalidateFuseInodeCacheIfRequired() { invalidateFuseInodeCache(); } -void TreeInode::invalidateFuseEntryCache(PathComponentPiece name) { - if (auto* fuseChannel = getMount()->getFuseChannel()) { - fuseChannel->invalidateEntry(getNodeId(), name); - } -} - void TreeInode::invalidateFuseEntryCacheIfRequired(PathComponentPiece name) { if (RequestData::isFuseRequest()) { // no need to flush the cache if we are inside a FUSE request handler return; } - invalidateFuseEntryCache(name); -} -#else - -void TreeInode::cleanupPrjfsCache(PathComponentPiece name) { - if (auto* fsChannel = getMount()->getFsChannel()) { - const auto path = getPath(); - if (path.has_value()) { - fsChannel->removeCachedFile(path.value() + name); - } - } + invalidateChannelEntryCache(name); } #endif diff --git a/eden/fs/inodes/TreeInode.h b/eden/fs/inodes/TreeInode.h index ff32e2e1d0..2345d8caa7 100644 --- a/eden/fs/inodes/TreeInode.h +++ b/eden/fs/inodes/TreeInode.h @@ -654,20 +654,6 @@ class TreeInode final : public InodeBaseMetadata { */ void invalidateFuseInodeCacheIfRequired(); - /** - * Send a request to the kernel to invalidate the dcache entry for the given - * child entry name. The dcache caches name lookups to child inodes. - * - * This should be called when an entry is added, removed, or changed. - * Invalidating upon removal is required because the kernel maintains a - * negative cache on lookup failures. - * - * This is safe to call while holding the contents_ lock, but it is not - * required. Calling it without the contents_ lock held is preferable when - * possible. - */ - void invalidateFuseEntryCache(PathComponentPiece name); - /** * Invalidate the kernel FUSE cache for this entry name only if we are not * being called from inside a FUSE request handler. @@ -676,14 +662,24 @@ class TreeInode final : public InodeBaseMetadata { * need to tell the kernel about the change--it will automatically know. */ void invalidateFuseEntryCacheIfRequired(PathComponentPiece name); -#else - /** - * On Windows, Eden manages ProjectedFS cache. This function is to remove a - * file or folder from the cache. - */ - void cleanupPrjfsCache(PathComponentPiece name); #endif + /** + * Send a request to the kernel to invalidate its cache for the given child + * entry name. On unices this corresponds to the dcache entry which caches + * name lookups to child inodes. On Windows, this removes the on-disk + * placeholder. + * + * This should be called when an entry is added, removed, or changed. + * Invalidating upon removal is required because the kernel maintains a + * negative cache on lookup failures on Unices. + * + * This is safe to call while holding the contents_ lock, but it is not + * required. Calling it without the contents_ lock held is preferable when + * possible. + */ + void invalidateChannelEntryCache(PathComponentPiece name); + /** * Attempt to remove an empty directory during a checkout operation. *