From a0656edac5486d06e81ea319716f79a3040b9eaa Mon Sep 17 00:00:00 2001 From: William Baker Date: Wed, 31 Jul 2019 09:13:40 -0700 Subject: [PATCH 1/2] Mac: Don't download file sizes as part of OnEnumerateDirectory --- .../MacFileSystemVirtualizer.cs | 35 +++++++------------ .../WindowsFileSystemVirtualizer.cs | 2 +- .../Mock/Mac/MockVirtualizationInstance.cs | 1 - .../Projection/MockGitIndexProjection.cs | 3 +- .../Projection/GitIndexProjection.cs | 18 ++++++---- .../MacFileSystemVirtualizer.cs | 1 - .../PrjFSLib.Mac.Managed/Interop/PrjFSLib.cs | 1 - .../VirtualizationInstance.cs | 2 -- ProjFS.Mac/PrjFSLib/PrjFSLib.cpp | 4 +-- ProjFS.Mac/PrjFSLib/PrjFSLib.h | 1 - 10 files changed, 27 insertions(+), 41 deletions(-) diff --git a/GVFS/GVFS.Platform.Mac/MacFileSystemVirtualizer.cs b/GVFS/GVFS.Platform.Mac/MacFileSystemVirtualizer.cs index faef5fc989..e3485988b5 100644 --- a/GVFS/GVFS.Platform.Mac/MacFileSystemVirtualizer.cs +++ b/GVFS/GVFS.Platform.Mac/MacFileSystemVirtualizer.cs @@ -99,7 +99,6 @@ public override FileSystemResult WritePlaceholderFile( relativePath, PlaceholderVersionId, ToVersionIdByteArray(FileSystemVirtualizer.ConvertShaToContentId(sha)), - (ulong)endOfFile, fileMode); return new FileSystemResult(ResultToFSResult(result), unchecked((int)result)); @@ -560,31 +559,19 @@ private Result OnEnumerateDirectory( { try { - Result result; - try - { - IEnumerable projectedItems; - - // TODO: Pool these connections or schedule this work to run asynchronously using TryScheduleFileOrNetworkRequest - using (BlobSizes.BlobSizesConnection blobSizesConnection = this.FileSystemCallbacks.BlobSizes.CreateConnection()) - { - projectedItems = this.FileSystemCallbacks.GitIndexProjection.GetProjectedItems(CancellationToken.None, blobSizesConnection, relativePath); - } + IEnumerable projectedItems; - result = this.CreatePlaceholders(relativePath, projectedItems, triggeringProcessName); - } - catch (SizesUnavailableException e) + // TODO: Pool these connections or schedule this work to run asynchronously using TryScheduleFileOrNetworkRequest + using (BlobSizes.BlobSizesConnection blobSizesConnection = this.FileSystemCallbacks.BlobSizes.CreateConnection()) { - // TODO: Is this the correct Result to return? - result = Result.EIOError; - - EventMetadata metadata = this.CreateEventMetadata(relativePath, e); - metadata.Add("commandId", commandId); - metadata.Add(nameof(result), result.ToString("X") + "(" + result.ToString("G") + ")"); - this.Context.Tracer.RelatedError(metadata, nameof(this.OnEnumerateDirectory) + ": caught SizesUnavailableException"); + projectedItems = this.FileSystemCallbacks.GitIndexProjection.GetProjectedItems( + CancellationToken.None, + blobSizesConnection, + relativePath, + populateSizes: false); } - return result; + return this.CreatePlaceholders(relativePath, projectedItems, triggeringProcessName); } catch (Exception e) { @@ -612,7 +599,9 @@ private Result CreatePlaceholders(string directoryRelativePath, IEnumerable GetProjectedItems( CancellationToken cancellationToken, BlobSizes.BlobSizesConnection blobSizesConnection, - string folderPath) + string folderPath, + bool populateSizes) { this.waitForGetProjectedItems.Set(); diff --git a/GVFS/GVFS.Virtualization/Projection/GitIndexProjection.cs b/GVFS/GVFS.Virtualization/Projection/GitIndexProjection.cs index 45c9f3bfde..1a88e5ce24 100644 --- a/GVFS/GVFS.Virtualization/Projection/GitIndexProjection.cs +++ b/GVFS/GVFS.Virtualization/Projection/GitIndexProjection.cs @@ -387,7 +387,8 @@ public virtual void GetFileTypeAndMode(string filePath, out FileType fileType, o public virtual List GetProjectedItems( CancellationToken cancellationToken, BlobSizes.BlobSizesConnection blobSizesConnection, - string folderPath) + string folderPath, + bool populateSizes) { this.projectionReadWriteLock.EnterReadLock(); @@ -396,12 +397,15 @@ public virtual List GetProjectedItems( FolderData folderData; if (this.TryGetOrAddFolderDataFromCache(folderPath, out folderData)) { - folderData.PopulateSizes( - this.context.Tracer, - this.gitObjects, - blobSizesConnection, - availableSizes: null, - cancellationToken: cancellationToken); + if (populateSizes) + { + folderData.PopulateSizes( + this.context.Tracer, + this.gitObjects, + blobSizesConnection, + availableSizes: null, + cancellationToken: cancellationToken); + } return ConvertToProjectedFileInfos(folderData.ChildEntries); } diff --git a/MirrorProvider/MirrorProvider.Mac/MacFileSystemVirtualizer.cs b/MirrorProvider/MirrorProvider.Mac/MacFileSystemVirtualizer.cs index 98fe298f4a..12cff622ae 100644 --- a/MirrorProvider/MirrorProvider.Mac/MacFileSystemVirtualizer.cs +++ b/MirrorProvider/MirrorProvider.Mac/MacFileSystemVirtualizer.cs @@ -107,7 +107,6 @@ private Result OnEnumerateDirectory( Path.Combine(relativePath, child.Name), providerId: ToVersionIdByteArray(1), contentId: ToVersionIdByteArray(0), - fileSize: (ulong)child.Size, fileMode: fileMode); if (result != Result.Success) { diff --git a/ProjFS.Mac/PrjFSLib.Mac.Managed/Interop/PrjFSLib.cs b/ProjFS.Mac/PrjFSLib.Mac.Managed/Interop/PrjFSLib.cs index 19d53ff2e9..95feb1c08a 100644 --- a/ProjFS.Mac/PrjFSLib.Mac.Managed/Interop/PrjFSLib.cs +++ b/ProjFS.Mac/PrjFSLib.Mac.Managed/Interop/PrjFSLib.cs @@ -29,7 +29,6 @@ public static extern Result WritePlaceholderFile( byte[] providerId, [MarshalAs(UnmanagedType.LPArray, SizeConst = PlaceholderIdLength)] byte[] contentId, - ulong fileSize, ushort fileMode); [DllImport(PrjFSLibPath, EntryPoint = "PrjFS_WriteSymLink")] diff --git a/ProjFS.Mac/PrjFSLib.Mac.Managed/VirtualizationInstance.cs b/ProjFS.Mac/PrjFSLib.Mac.Managed/VirtualizationInstance.cs index eb78b7ce75..2f50b806ce 100644 --- a/ProjFS.Mac/PrjFSLib.Mac.Managed/VirtualizationInstance.cs +++ b/ProjFS.Mac/PrjFSLib.Mac.Managed/VirtualizationInstance.cs @@ -94,7 +94,6 @@ public virtual Result WritePlaceholderFile( string relativePath, byte[] providerId, byte[] contentId, - ulong fileSize, ushort fileMode) { if (providerId.Length != Interop.PrjFSLib.PlaceholderIdLength || @@ -107,7 +106,6 @@ public virtual Result WritePlaceholderFile( relativePath, providerId, contentId, - fileSize, fileMode); } diff --git a/ProjFS.Mac/PrjFSLib/PrjFSLib.cpp b/ProjFS.Mac/PrjFSLib/PrjFSLib.cpp index 29e76a4a2d..14348e5ff5 100644 --- a/ProjFS.Mac/PrjFSLib/PrjFSLib.cpp +++ b/ProjFS.Mac/PrjFSLib/PrjFSLib.cpp @@ -348,7 +348,6 @@ PrjFS_Result PrjFS_WritePlaceholderFile( _In_ const char* relativePath, _In_ unsigned char providerId[PrjFS_PlaceholderIdLength], _In_ unsigned char contentId[PrjFS_PlaceholderIdLength], - _In_ unsigned long fileSize, _In_ uint16_t fileMode) { #ifdef DEBUG @@ -357,7 +356,6 @@ PrjFS_Result PrjFS_WritePlaceholderFile( << relativePath << ", " << (int)providerId[0] << ", " << (int)contentId[0] << ", " - << fileSize << ", " << oct << fileMode << dec << ")" << endl; #endif @@ -494,7 +492,7 @@ PrjFS_Result PrjFS_UpdatePlaceholderFileIfNeeded( } // TODO(#1372): Ensure that races with hydration are handled properly - return PrjFS_WritePlaceholderFile(relativePath, providerId, contentId, fileSize, fileMode); + return PrjFS_WritePlaceholderFile(relativePath, providerId, contentId, fileMode); } PrjFS_Result PrjFS_ReplacePlaceholderFileWithSymLink( diff --git a/ProjFS.Mac/PrjFSLib/PrjFSLib.h b/ProjFS.Mac/PrjFSLib/PrjFSLib.h index 21a312c2c7..d68d47317a 100644 --- a/ProjFS.Mac/PrjFSLib/PrjFSLib.h +++ b/ProjFS.Mac/PrjFSLib/PrjFSLib.h @@ -85,7 +85,6 @@ extern "C" PrjFS_Result PrjFS_WritePlaceholderFile( _In_ const char* relativePath, _In_ unsigned char providerId[PrjFS_PlaceholderIdLength], _In_ unsigned char contentId[PrjFS_PlaceholderIdLength], - _In_ unsigned long fileSize, _In_ uint16_t fileMode); extern "C" PrjFS_Result PrjFS_WriteSymLink( From 37a1f6cf7454cf0919d678b30318f1cdbe1e49ad Mon Sep 17 00:00:00 2001 From: William Baker Date: Wed, 31 Jul 2019 12:58:28 -0700 Subject: [PATCH 2/2] Changes for PR feedback: - Add comments where needed - Stop creating BlobSizeConnections in OnEnumerateDirectory - Remove populateSizes parameter from GetProjectedItems --- .../MacFileSystemVirtualizer.cs | 24 +++++++++---------- .../WindowsFileSystemVirtualizer.cs | 2 +- .../Projection/MockGitIndexProjection.cs | 3 +-- .../Projection/GitIndexProjection.cs | 13 +++++++--- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/GVFS/GVFS.Platform.Mac/MacFileSystemVirtualizer.cs b/GVFS/GVFS.Platform.Mac/MacFileSystemVirtualizer.cs index e3485988b5..72582f09f5 100644 --- a/GVFS/GVFS.Platform.Mac/MacFileSystemVirtualizer.cs +++ b/GVFS/GVFS.Platform.Mac/MacFileSystemVirtualizer.cs @@ -17,7 +17,8 @@ public class MacFileSystemVirtualizer : FileSystemVirtualizer { public static readonly byte[] PlaceholderVersionId = ToVersionIdByteArray(new byte[] { PlaceholderVersion }); - private const int SymLinkTargetBufferSize = 4096; + private const int SymLinkTargetBufferSize = 4096; + private const long DummyFileSize = -1; private const string ClassName = nameof(MacFileSystemVirtualizer); @@ -83,6 +84,12 @@ public override void Stop() this.Context.Tracer.RelatedEvent(EventLevel.Informational, $"{nameof(this.Stop)}_StopRequested", metadata: null); } + /// + /// Writes a placeholder file. + /// + /// Placeholder's path relative to the root of the repo + /// Length of the file (ignored on this platform) + /// The SHA of the placeholder's contents, stored as the content ID in the placeholder public override FileSystemResult WritePlaceholderFile( string relativePath, long endOfFile, @@ -559,17 +566,10 @@ private Result OnEnumerateDirectory( { try { - IEnumerable projectedItems; - - // TODO: Pool these connections or schedule this work to run asynchronously using TryScheduleFileOrNetworkRequest - using (BlobSizes.BlobSizesConnection blobSizesConnection = this.FileSystemCallbacks.BlobSizes.CreateConnection()) - { - projectedItems = this.FileSystemCallbacks.GitIndexProjection.GetProjectedItems( + IEnumerable projectedItems = this.FileSystemCallbacks.GitIndexProjection.GetProjectedItems( CancellationToken.None, - blobSizesConnection, - relativePath, - populateSizes: false); - } + blobSizesConnection: null, + folderPath: relativePath); return this.CreatePlaceholders(relativePath, projectedItems, triggeringProcessName); } @@ -601,7 +601,7 @@ private Result CreatePlaceholders(string directoryRelativePath, IEnumerable GetProjectedItems( CancellationToken cancellationToken, BlobSizes.BlobSizesConnection blobSizesConnection, - string folderPath, - bool populateSizes) + string folderPath) { this.waitForGetProjectedItems.Set(); diff --git a/GVFS/GVFS.Virtualization/Projection/GitIndexProjection.cs b/GVFS/GVFS.Virtualization/Projection/GitIndexProjection.cs index 1a88e5ce24..2e23ec5f46 100644 --- a/GVFS/GVFS.Virtualization/Projection/GitIndexProjection.cs +++ b/GVFS/GVFS.Virtualization/Projection/GitIndexProjection.cs @@ -384,11 +384,18 @@ public virtual void GetFileTypeAndMode(string filePath, out FileType fileType, o } } + /// + /// Gets the projected items within the specified folder. + /// + /// Cancellation token + /// + /// BlobSizes database connection, if null file sizes will not be populated + /// + /// Path of the folder relative to the repo's root public virtual List GetProjectedItems( CancellationToken cancellationToken, BlobSizes.BlobSizesConnection blobSizesConnection, - string folderPath, - bool populateSizes) + string folderPath) { this.projectionReadWriteLock.EnterReadLock(); @@ -397,7 +404,7 @@ public virtual List GetProjectedItems( FolderData folderData; if (this.TryGetOrAddFolderDataFromCache(folderPath, out folderData)) { - if (populateSizes) + if (blobSizesConnection != null) { folderData.PopulateSizes( this.context.Tracer,