diff --git a/Duplicati/Library/Snapshots/WindowsSnapshot.cs b/Duplicati/Library/Snapshots/WindowsSnapshot.cs index 542376b9d..29b7fbc26 100644 --- a/Duplicati/Library/Snapshots/WindowsSnapshot.cs +++ b/Duplicati/Library/Snapshots/WindowsSnapshot.cs @@ -75,6 +75,11 @@ namespace Duplicati.Library.Snapshots /// private static SystemIOWindows IO_WIN = new SystemIOWindows(); + /// + /// Commonly used string element + /// + private static string SLASH = Path.DirectorySeparatorChar.ToString(); + /// /// Constructs a new backup snapshot, using all the required disks /// @@ -399,21 +404,33 @@ namespace Duplicati.Library.Snapshots throw new InvalidOperationException(); } + /// + /// Cache element to speed up returning the same paths + /// + private KeyValuePair m_lastLookup; + /// public override string ConvertToSnapshotPath(string localPath) { + // Hot cache, we tend to call the same conversion multiple times + var m = m_lastLookup; + if (m.Key == localPath) + return m.Value; + if (!Path.IsPathRooted(localPath)) throw new InvalidOperationException(); var root = AlphaFS.Path.GetPathRoot(localPath); - if (!m_volumeMap.TryGetValue(root, out var volumePath)) throw new InvalidOperationException(); - var mappedPath = IO_WIN.PathCombine(volumePath, localPath.Substring(root.Length)); - if (localPath.EndsWith("\\", StringComparison.Ordinal)) - return Library.Utility.Utility.AppendDirSeparator(mappedPath); + // Note: Do NOT use Path.Combine as it strips the UNC path prefix + var subPath = localPath.Replace(root, String.Empty); + if (!volumePath.EndsWith(SLASH, StringComparison.Ordinal) && !subPath.StartsWith(SLASH, StringComparison.Ordinal)) + subPath = subPath.Insert(0, SLASH); + var mappedPath = subPath.Insert(0, volumePath); + m_lastLookup = new KeyValuePair(localPath, mappedPath); return mappedPath; } @@ -454,13 +471,13 @@ namespace Duplicati.Library.Snapshots catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "MappedDriveCleanupError", ex, "Failed during VSS mapped drive unmapping"); - } - - try - { - m_backup?.BackupComplete(); + } + + try + { + m_backup?.BackupComplete(); } - catch (Exception ex) + catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "VSSTerminateError", ex, "Failed to signal VSS completion"); } @@ -470,12 +487,12 @@ namespace Duplicati.Library.Snapshots if (m_backup != null) { foreach (var g in m_volumes.Values) - { - try - { - m_backup.DeleteSnapshot(g, false); + { + try + { + m_backup.DeleteSnapshot(g, false); } - catch (Exception ex) + catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "VSSSnapShotDeleteError", ex, "Failed to close VSS snapshot"); }