Nit: Explicitly pass flag indicating if parity repair is allowed
This commit is contained in:
@@ -309,9 +309,10 @@ internal partial class BackendManager : IBackendManager
|
||||
/// <param name="remotename">The name of the remote file</param>
|
||||
/// <param name="hash">The hash of the remote file, for verification</param>
|
||||
/// <param name="size">The size of the remote file, for verification</param>
|
||||
/// <param name="allowParityRepair">Whether a failed download may be repaired using parity data</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <returns>A temporary file with the contents of the remote file</returns>
|
||||
public async Task<TempFile> GetAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true)
|
||||
public async Task<TempFile> GetAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken)
|
||||
{
|
||||
var op = new GetOperation(remotename, size, context, cancelToken)
|
||||
{
|
||||
@@ -331,9 +332,10 @@ internal partial class BackendManager : IBackendManager
|
||||
/// <param name="remotename">The name of the remote file</param>
|
||||
/// <param name="hash">The hash of the remote file, for verification</param>
|
||||
/// <param name="size">The size of the remote file, for verification</param>
|
||||
/// <param name="allowParityRepair">Whether a failed download may be repaired using parity data</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <returns>A temporary file with the contents of the remote file</returns>
|
||||
public async Task<TempFile> GetDirectAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true)
|
||||
public async Task<TempFile> GetDirectAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken)
|
||||
{
|
||||
var op = new GetOperation(remotename, size, context, cancelToken)
|
||||
{
|
||||
@@ -365,9 +367,10 @@ internal partial class BackendManager : IBackendManager
|
||||
/// <param name="remotename">The name of the remote file</param>
|
||||
/// <param name="hash">The hash of the remote file, or null if not known</param>
|
||||
/// <param name="size">The size of the remote file, or -1 if not known</param>
|
||||
/// <param name="allowParityRepair">Whether a failed download may be repaired using parity data</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <returns>A tuple containing the temporary file, the hash of the file, and the size of the file</returns>
|
||||
public async Task<(TempFile File, string Hash, long Size)> GetWithInfoAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true)
|
||||
public async Task<(TempFile File, string Hash, long Size)> GetWithInfoAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken)
|
||||
{
|
||||
var op = new GetOperation(remotename, size, context, cancelToken)
|
||||
{
|
||||
@@ -557,22 +560,23 @@ internal partial class BackendManager : IBackendManager
|
||||
/// Performs a download of the files specified, with pre-fetch to overlap the download and processing
|
||||
/// </summary>
|
||||
/// <param name="volumes">The volumes to download</param>
|
||||
/// <param name="allowParityRepair">Whether a failed download may be repaired using parity data</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <returns>The downloaded files and the volume they came from</returns>
|
||||
public async IAsyncEnumerable<(TempFile File, string Hash, long Size, string Name)> GetFilesOverlappedAsync(IEnumerable<IRemoteVolume> volumes, [EnumeratorCancellation] CancellationToken cancelToken, bool allowParityRepair = true)
|
||||
public async IAsyncEnumerable<(TempFile File, string Hash, long Size, string Name)> GetFilesOverlappedAsync(IEnumerable<IRemoteVolume> volumes, bool allowParityRepair, [EnumeratorCancellation] CancellationToken cancelToken)
|
||||
{
|
||||
var prevVolume = volumes.FirstOrDefault();
|
||||
if (prevVolume == null)
|
||||
yield break;
|
||||
|
||||
// Get the first volume, so we do not have pending parallel transfers
|
||||
var prevResult = await GetWithInfoAsync(prevVolume.Name, prevVolume.Hash, prevVolume.Size, cancelToken, allowParityRepair)
|
||||
var prevResult = await GetWithInfoAsync(prevVolume.Name, prevVolume.Hash, prevVolume.Size, allowParityRepair, cancelToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
foreach (var volume in volumes.Skip(1))
|
||||
{
|
||||
// Prepare the next volume, while processing the previous one
|
||||
var nextTask = GetWithInfoAsync(volume.Name, volume.Hash, volume.Size, cancelToken, allowParityRepair);
|
||||
var nextTask = GetWithInfoAsync(volume.Name, volume.Hash, volume.Size, allowParityRepair, cancelToken);
|
||||
|
||||
// Assuming we do not throw while yielding, otherwise we would need to dispose nextTask
|
||||
yield return (prevResult.File, prevResult.Hash, prevResult.Size, prevVolume.Name);
|
||||
@@ -592,22 +596,23 @@ internal partial class BackendManager : IBackendManager
|
||||
/// Performs a direct download of the files specified, with pre-fetch to overlap the download and processing
|
||||
/// </summary>
|
||||
/// <param name="volumes">The volumes to download</param>
|
||||
/// <param name="allowParityRepair">Whether a failed download may be repaired using parity data</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <returns>The downloaded files and the volume they came from</returns>
|
||||
public async IAsyncEnumerable<(TempFile File, string Name)> GetFilesOverlappedDirectAsync(IEnumerable<IRemoteVolume> volumes, [EnumeratorCancellation] CancellationToken cancelToken, bool allowParityRepair = true)
|
||||
public async IAsyncEnumerable<(TempFile File, string Name)> GetFilesOverlappedDirectAsync(IEnumerable<IRemoteVolume> volumes, bool allowParityRepair, [EnumeratorCancellation] CancellationToken cancelToken)
|
||||
{
|
||||
var prevVolume = volumes.FirstOrDefault();
|
||||
if (prevVolume == null)
|
||||
yield break;
|
||||
|
||||
// Get the first volume, so we do not have pending parallel transfers
|
||||
var prevResult = await GetDirectAsync(prevVolume.Name, prevVolume.Hash, prevVolume.Size, cancelToken, allowParityRepair)
|
||||
var prevResult = await GetDirectAsync(prevVolume.Name, prevVolume.Hash, prevVolume.Size, allowParityRepair, cancelToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
foreach (var volume in volumes.Skip(1))
|
||||
{
|
||||
// Prepare the next volume, while processing the previous one
|
||||
var nextTask = GetDirectAsync(volume.Name, volume.Hash, volume.Size, cancelToken, allowParityRepair);
|
||||
var nextTask = GetDirectAsync(volume.Name, volume.Hash, volume.Size, allowParityRepair, cancelToken);
|
||||
|
||||
// Assuming we do not throw while yielding, otherwise we would need to dispose nextTask
|
||||
yield return (prevResult, prevVolume.Name);
|
||||
|
||||
@@ -144,10 +144,10 @@ internal interface IBackendManager : IDisposable
|
||||
/// <param name="remotename">The name of the file to get</param>
|
||||
/// <param name="hash">The hash of the file to get, or <c>null</c> if not known</param>
|
||||
/// <param name="size">The size of the file to get, or -1 if not known</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <param name="allowParityRepair">Whether a failed download may be repaired using parity data. Disable for the test/verification flow so damaged files are reported.</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <returns>The file, hash, and size</returns>
|
||||
Task<(TempFile File, string Hash, long Size)> GetWithInfoAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true);
|
||||
Task<(TempFile File, string Hash, long Size)> GetWithInfoAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a file from the backend
|
||||
@@ -155,10 +155,10 @@ internal interface IBackendManager : IDisposable
|
||||
/// <param name="remotename">The name of the file to get</param>
|
||||
/// <param name="hash">The hash of the file to get, or <c>null</c> if not known</param>
|
||||
/// <param name="size">The size of the file to get, or -1 if not known</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <param name="allowParityRepair">Whether a failed download may be repaired using parity data. Disable for the test/verification flow so damaged files are reported.</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <returns>The downloaded file</returns>
|
||||
Task<TempFile> GetAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true);
|
||||
Task<TempFile> GetAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a file from the backend without decrypting it
|
||||
@@ -166,28 +166,28 @@ internal interface IBackendManager : IDisposable
|
||||
/// <param name="remotename">The name of the remote volume</param>
|
||||
/// <param name="hash">The hash of the volume</param>
|
||||
/// <param name="size">The size of the volume</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <param name="allowParityRepair">Whether a failed download may be repaired using parity data. Disable for the test/verification flow so damaged files are reported.</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <returns>The downloaded file</returns>
|
||||
Task<TempFile> GetDirectAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true);
|
||||
Task<TempFile> GetDirectAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken);
|
||||
|
||||
/// <summary>
|
||||
/// Performs a download of the files specified, with pre-fetch to overlap the download and processing
|
||||
/// </summary>
|
||||
/// <param name="volumes">The volumes to download</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <param name="allowParityRepair">Whether a failed download may be repaired using parity data. Disable for the test/verification flow so damaged files are reported.</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <returns>The downloaded files, hash, size, and name</returns>
|
||||
IAsyncEnumerable<(TempFile File, string Hash, long Size, string Name)> GetFilesOverlappedAsync(IEnumerable<IRemoteVolume> volumes, CancellationToken cancelToken, bool allowParityRepair = true);
|
||||
IAsyncEnumerable<(TempFile File, string Hash, long Size, string Name)> GetFilesOverlappedAsync(IEnumerable<IRemoteVolume> volumes, bool allowParityRepair, CancellationToken cancelToken);
|
||||
|
||||
/// <summary>
|
||||
/// Performs a direct download of the files specified, with pre-fetch to overlap the download and processing
|
||||
/// </summary>
|
||||
/// <param name="volumes">The volumes to download</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <param name="allowParityRepair">Whether a failed download may be repaired using parity data. Disable for the test/verification flow so damaged files are reported.</param>
|
||||
/// <param name="cancelToken">The cancellation token</param>
|
||||
/// <returns>The downloaded files and the volume they came from</returns>
|
||||
IAsyncEnumerable<(TempFile File, string Name)> GetFilesOverlappedDirectAsync(IEnumerable<IRemoteVolume> volumes, CancellationToken cancelToken, bool allowParityRepair = true);
|
||||
IAsyncEnumerable<(TempFile File, string Name)> GetFilesOverlappedDirectAsync(IEnumerable<IRemoteVolume> volumes, bool allowParityRepair, CancellationToken cancelToken);
|
||||
|
||||
/// <summary>
|
||||
/// Flushes the database messages to the database
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
|
||||
using (var q = await db.CreateBlockQueryHelperAsync(m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
{
|
||||
await foreach (var (tmpfile, hash, size, name) in backendManager.GetFilesOverlappedAsync(volumesToDownload, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
await foreach (var (tmpfile, hash, size, name) in backendManager.GetFilesOverlappedAsync(volumesToDownload, allowParityRepair: true, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
{
|
||||
using (tmpfile)
|
||||
{
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
return;
|
||||
|
||||
using (new Logging.Timer(LOGTAG, "InsertBaseFiles", "Inserting base files into database"))
|
||||
using (var tmpfile = await backendManager.GetAsync(baseFile.File.Name, null, baseFile.File.Size, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
using (var tmpfile = await backendManager.GetAsync(baseFile.File.Name, null, baseFile.File.Size, allowParityRepair: true, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
using (var rd = new Volumes.FilesetVolumeReader(RestoreHandler.GetCompressionModule(baseFile.File.Name), tmpfile, m_options))
|
||||
foreach (var f in rd.Files)
|
||||
if (FilterExpression.Matches(filter, f.Path))
|
||||
@@ -158,7 +158,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
return;
|
||||
|
||||
using (new Logging.Timer(LOGTAG, "InsertCompareFiles", "Inserting compare files into database"))
|
||||
using (var tmpfile = await backendManager.GetAsync(compareFile.File.Name, null, compareFile.File.Size, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
using (var tmpfile = await backendManager.GetAsync(compareFile.File.Name, null, compareFile.File.Size, allowParityRepair: true, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
using (var rd = new Volumes.FilesetVolumeReader(RestoreHandler.GetCompressionModule(compareFile.File.Name), tmpfile, m_options))
|
||||
foreach (var f in rd.Files)
|
||||
if (FilterExpression.Matches(filter, f.Path))
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var files = new List<Library.Interface.IListResultFile>();
|
||||
using (var tmpfile = await backendManager.GetAsync(file.Name, entry.Hash, entry.Size < 0 ? file.Size : entry.Size, cancellationToken).ConfigureAwait(false))
|
||||
using (var tmpfile = await backendManager.GetAsync(file.Name, entry.Hash, entry.Size < 0 ? file.Size : entry.Size, allowParityRepair: true, cancellationToken).ConfigureAwait(false))
|
||||
using (var tmp = new Volumes.FilesetVolumeReader(RestoreHandler.GetCompressionModule(file.Name), tmpfile, m_options))
|
||||
foreach (var cf in tmp.ControlFiles)
|
||||
if (Library.Utility.FilterExpression.Matches(filter, cf.Key))
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
if (!await m_result.TaskControl.ProgressRendevouzAsync().ConfigureAwait(false))
|
||||
return;
|
||||
|
||||
using (var tmpfile = await backendManager.GetAsync(firstEntry.File.Name, null, firstEntry.File.Size, cancellationToken).ConfigureAwait(false))
|
||||
using (var tmpfile = await backendManager.GetAsync(firstEntry.File.Name, null, firstEntry.File.Size, allowParityRepair: true, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
VolumeReaderBase.UpdateOptionsFromManifest(RestoreHandler.GetCompressionModule(firstEntry.File.Name), tmpfile, m_options);
|
||||
using (var rd = new FilesetVolumeReader(RestoreHandler.GetCompressionModule(firstEntry.File.Name), tmpfile, m_options))
|
||||
@@ -196,7 +196,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
|
||||
long flindex = 1;
|
||||
var filteredListMap = filteredList.ToDictionary(x => x.Value.File.Name, x => x.Value);
|
||||
await foreach (var (tmpfile, hash, size, name) in backendManager.GetFilesOverlappedAsync(filteredList.Select(x => new RemoteVolumeMapper(x.Value)), cancellationToken).ConfigureAwait(false))
|
||||
await foreach (var (tmpfile, hash, size, name) in backendManager.GetFilesOverlappedAsync(filteredList.Select(x => new RemoteVolumeMapper(x.Value)), allowParityRepair: true, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
var flentry = filteredListMap[name];
|
||||
using (tmpfile)
|
||||
@@ -256,7 +256,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
{
|
||||
var list = new List<IListResultFileset>();
|
||||
var map = filteredList.ToDictionary(x => x.Value.File.Name, x => x);
|
||||
await foreach (var (file, hash, size, name) in backendManager.GetFilesOverlappedAsync(filteredList.Select(x => new RemoteVolumeMapper(x.Value)), cancelToken).ConfigureAwait(false))
|
||||
await foreach (var (file, hash, size, name) in backendManager.GetFilesOverlappedAsync(filteredList.Select(x => new RemoteVolumeMapper(x.Value)), allowParityRepair: true, cancelToken).ConfigureAwait(false))
|
||||
{
|
||||
// We must obtain the partial/full status from the fileset file in the dlist files.
|
||||
// Without this, the restore dialog will show all versions as full, or all versions
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
var isFirstFilelist = true;
|
||||
// At this point, we do not know the hashing used to verify the files, so we need to use direct download, and manually decrypt the files
|
||||
// so we can calculate the hash AFTER we have read the manifest content and updated the options
|
||||
await foreach (var (tmpencfile, name) in backendManager.GetFilesOverlappedDirectAsync(filelistWork, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
await foreach (var (tmpencfile, name) in backendManager.GetFilesOverlappedDirectAsync(filelistWork, allowParityRepair: true, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -364,7 +364,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
|
||||
progress = 0;
|
||||
|
||||
await foreach (var (tmpfile, hash, size, name) in backendManager.GetFilesOverlappedAsync(indexfiles, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
await foreach (var (tmpfile, hash, size, name) in backendManager.GetFilesOverlappedAsync(indexfiles, allowParityRepair: true, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -546,7 +546,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
}
|
||||
|
||||
progress = 0;
|
||||
await foreach (var (tmpfile, hash, size, name) in backendManager.GetFilesOverlappedAsync(lst, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
await foreach (var (tmpfile, hash, size, name) in backendManager.GetFilesOverlappedAsync(lst, allowParityRepair: true, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -776,7 +776,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
|
||||
// Download all required block volumes and extract metadata blocks.
|
||||
var volumesToDownload = volumeInfo.Values.Cast<IRemoteVolume>().ToList();
|
||||
await foreach (var (tmpfile, hash, size, name) in backendManager.GetFilesOverlappedAsync(volumesToDownload, cancellationToken).ConfigureAwait(false))
|
||||
await foreach (var (tmpfile, hash, size, name) in backendManager.GetFilesOverlappedAsync(volumesToDownload, allowParityRepair: true, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
using (tmpfile)
|
||||
{
|
||||
|
||||
@@ -265,7 +265,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
m_result.OperationProgressUpdater.UpdateProgress((float)progress / targetProgess);
|
||||
|
||||
KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>> res;
|
||||
var (tf, hash, size) = await backendManager.GetWithInfoAsync(n.Name, n.Hash, n.Size, cancellationToken).ConfigureAwait(false);
|
||||
var (tf, hash, size) = await backendManager.GetWithInfoAsync(n.Name, n.Hash, n.Size, allowParityRepair: true, cancellationToken).ConfigureAwait(false);
|
||||
using (tf)
|
||||
res =
|
||||
await TestHandler.TestVolumeInternalsAsync(testdb, n, tf, m_options, 1, cancellationToken)
|
||||
@@ -322,7 +322,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
{
|
||||
try
|
||||
{
|
||||
(var tf, var hash, var size) = await backendManager.GetWithInfoAsync(n.File.Name, null, n.File.Size, cancellationToken).ConfigureAwait(false);
|
||||
(var tf, var hash, var size) = await backendManager.GetWithInfoAsync(n.File.Name, null, n.File.Size, allowParityRepair: true, cancellationToken).ConfigureAwait(false);
|
||||
using (tf)
|
||||
using (var ifr = new IndexVolumeReader(n.CompressionModule, tf, m_options, m_options.BlockhashSize))
|
||||
{
|
||||
@@ -479,7 +479,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
var remoteVolume = await db
|
||||
.GetRemoteVolumeAsync(volumename, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
using var tmpfile = await backendManager.GetAsync(remoteVolume.Name, remoteVolume.Hash, remoteVolume.Size, cancellationToken).ConfigureAwait(false);
|
||||
using var tmpfile = await backendManager.GetAsync(remoteVolume.Name, remoteVolume.Hash, remoteVolume.Size, allowParityRepair: true, cancellationToken).ConfigureAwait(false);
|
||||
var parsed = VolumeBase.ParseFilename(remoteVolume.Name);
|
||||
using var stream = new FileStream(tmpfile, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var compressor = DynamicLoader.CompressionLoader.GetModule(parsed.CompressionModule, stream, ArchiveMode.Read, m_options.RawOptions);
|
||||
@@ -1245,7 +1245,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
await EmitBlockListBlock().ConfigureAwait(false);
|
||||
|
||||
//Then we grab all remote volumes that have the missing blocks
|
||||
await foreach (var (tmpfile, _, _, name) in backendManager.GetFilesOverlappedAsync(await mbl.GetMissingBlockSourcesAsync(cancellationToken).ToListAsync(cancellationToken: cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false))
|
||||
await foreach (var (tmpfile, _, _, name) in backendManager.GetFilesOverlappedAsync(await mbl.GetMissingBlockSourcesAsync(cancellationToken).ToListAsync(cancellationToken: cancellationToken).ConfigureAwait(false), allowParityRepair: true, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1357,7 +1357,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
.GetRemoteVolumeFromFilesetIDAsync(entry.Key, m_result.TaskControl.ProgressToken)
|
||||
.ConfigureAwait(false);
|
||||
var parsed = VolumeBase.ParseFilename(volume.Name);
|
||||
using var tmpfile = await backendManager.GetAsync(volume.Name, volume.Hash, volume.Size, CancellationToken.None).ConfigureAwait(false);
|
||||
using var tmpfile = await backendManager.GetAsync(volume.Name, volume.Hash, volume.Size, allowParityRepair: true, CancellationToken.None).ConfigureAwait(false);
|
||||
using var stream = new FileStream(tmpfile, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var compressor = DynamicLoader.CompressionLoader.GetModule(parsed.CompressionModule, stream, ArchiveMode.Read, m_options.RawOptions);
|
||||
if (compressor == null)
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace Duplicati.Library.Main.Operation.Restore
|
||||
.ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
f = await backend.GetDirectAsync(volume_name, hash, size, results.TaskControl.TransferToken).ConfigureAwait(false);
|
||||
f = await backend.GetDirectAsync(volume_name, hash, size, allowParityRepair: true, results.TaskControl.TransferToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var res = new List<string>();
|
||||
using (var tmpfile = await backendManager.GetAsync(file.Name, entry.Hash, entry.Size < 0 ? file.Size : entry.Size, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
using (var tmpfile = await backendManager.GetAsync(file.Name, entry.Hash, entry.Size < 0 ? file.Size : entry.Size, allowParityRepair: true, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
using (var tmp = new Volumes.FilesetVolumeReader(RestoreHandler.GetCompressionModule(file.Name), tmpfile, m_options))
|
||||
foreach (var cf in tmp.ControlFiles)
|
||||
if (FilterExpression.Matches(filter, cf.Key))
|
||||
|
||||
@@ -1174,7 +1174,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
var brokenFiles = new List<string>();
|
||||
|
||||
using (new Logging.Timer(LOGTAG, "PatchWithBlocklist", "PatchWithBlocklist"))
|
||||
await foreach (var (tmpfile, _, _, name) in backendManager.GetFilesOverlappedAsync(volumes, cancellationToken).ConfigureAwait(false))
|
||||
await foreach (var (tmpfile, _, _, name) in backendManager.GetFilesOverlappedAsync(volumes, allowParityRepair: true, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
var faultyIndexFiles = new List<IRemoteVolume>();
|
||||
// Do not repair with parity during verification: a repairable download would
|
||||
// otherwise mask that the remote copy is actually damaged.
|
||||
await foreach (var (tf, hash, size, name) in backend.GetFilesOverlappedAsync(files, m_result.TaskControl.ProgressToken, allowParityRepair: false).ConfigureAwait(false))
|
||||
await foreach (var (tf, hash, size, name) in backend.GetFilesOverlappedAsync(files, allowParityRepair: false, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
{
|
||||
var vol = new RemoteVolume(name, hash, size);
|
||||
try
|
||||
@@ -200,7 +200,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "MissingRemoteHash", LC.L("No hash or size recorded for {0}, performing full verification", f.Name));
|
||||
KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>> res;
|
||||
|
||||
(var tf, var hash, var size) = await backend.GetWithInfoAsync(f.Name, f.Hash, f.Size, m_result.TaskControl.ProgressToken, allowParityRepair: false).ConfigureAwait(false);
|
||||
(var tf, var hash, var size) = await backend.GetWithInfoAsync(f.Name, f.Hash, f.Size, allowParityRepair: false, m_result.TaskControl.ProgressToken).ConfigureAwait(false);
|
||||
|
||||
using (tf)
|
||||
res = await TestVolumeInternalsAsync(db, f, tf, m_options, 1, m_result.TaskControl.ProgressToken)
|
||||
@@ -227,7 +227,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var tf = await backend.GetAsync(f.Name, f.Hash, f.Size, m_result.TaskControl.ProgressToken, allowParityRepair: false).ConfigureAwait(false))
|
||||
using (var tf = await backend.GetAsync(f.Name, f.Hash, f.Size, allowParityRepair: false, m_result.TaskControl.ProgressToken).ConfigureAwait(false))
|
||||
{ }
|
||||
}
|
||||
|
||||
|
||||
@@ -64,11 +64,11 @@ namespace Duplicati.UnitTest
|
||||
public TempFile DecryptFile(TempFile volume, string volume_name, Options options, bool dispose) => throw new NotImplementedException();
|
||||
public Task DeleteAsync(string remotename, long size, bool waitForComplete, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public Task<IQuotaInfo?> GetQuotaInfoAsync(CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public Task<(TempFile File, string Hash, long Size)> GetWithInfoAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true) => throw new NotImplementedException();
|
||||
public Task<TempFile> GetAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true) => throw new NotImplementedException();
|
||||
public Task<TempFile> GetDirectAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true) => throw new NotImplementedException();
|
||||
public System.Collections.Generic.IAsyncEnumerable<(TempFile File, string Hash, long Size, string Name)> GetFilesOverlappedAsync(System.Collections.Generic.IEnumerable<IRemoteVolume> volumes, CancellationToken cancelToken, bool allowParityRepair = true) => throw new NotImplementedException();
|
||||
public System.Collections.Generic.IAsyncEnumerable<(TempFile File, string Name)> GetFilesOverlappedDirectAsync(System.Collections.Generic.IEnumerable<IRemoteVolume> volumes, CancellationToken cancelToken, bool allowParityRepair = true) => throw new NotImplementedException();
|
||||
public Task<(TempFile File, string Hash, long Size)> GetWithInfoAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public Task<TempFile> GetAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public Task<TempFile> GetDirectAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public System.Collections.Generic.IAsyncEnumerable<(TempFile File, string Hash, long Size, string Name)> GetFilesOverlappedAsync(System.Collections.Generic.IEnumerable<IRemoteVolume> volumes, bool allowParityRepair, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public System.Collections.Generic.IAsyncEnumerable<(TempFile File, string Name)> GetFilesOverlappedDirectAsync(System.Collections.Generic.IEnumerable<IRemoteVolume> volumes, bool allowParityRepair, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public Task FlushPendingMessagesAsync(IBackendManagerDatabase database, CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
public void UpdateThrottleValues(long maxUploadPrSecond, long maxDownloadPrSecond) => throw new NotImplementedException();
|
||||
#endregion
|
||||
|
||||
@@ -96,11 +96,11 @@ namespace Duplicati.UnitTest
|
||||
public TempFile DecryptFile(TempFile volume, string volume_name, Options options, bool dispose) => throw new NotImplementedException();
|
||||
public Task DeleteAsync(string remotename, long size, bool waitForComplete, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public Task<IQuotaInfo?> GetQuotaInfoAsync(CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public Task<(TempFile File, string Hash, long Size)> GetWithInfoAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true) => throw new NotImplementedException();
|
||||
public Task<TempFile> GetAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true) => throw new NotImplementedException();
|
||||
public Task<TempFile> GetDirectAsync(string remotename, string hash, long size, CancellationToken cancelToken, bool allowParityRepair = true) => throw new NotImplementedException();
|
||||
public IAsyncEnumerable<(TempFile File, string Hash, long Size, string Name)> GetFilesOverlappedAsync(IEnumerable<IRemoteVolume> volumes, CancellationToken cancelToken, bool allowParityRepair = true) => throw new NotImplementedException();
|
||||
public IAsyncEnumerable<(TempFile File, string Name)> GetFilesOverlappedDirectAsync(IEnumerable<IRemoteVolume> volumes, CancellationToken cancelToken, bool allowParityRepair = true) => throw new NotImplementedException();
|
||||
public Task<(TempFile File, string Hash, long Size)> GetWithInfoAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public Task<TempFile> GetAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public Task<TempFile> GetDirectAsync(string remotename, string hash, long size, bool allowParityRepair, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public IAsyncEnumerable<(TempFile File, string Hash, long Size, string Name)> GetFilesOverlappedAsync(IEnumerable<IRemoteVolume> volumes, bool allowParityRepair, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public IAsyncEnumerable<(TempFile File, string Name)> GetFilesOverlappedDirectAsync(IEnumerable<IRemoteVolume> volumes, bool allowParityRepair, CancellationToken cancelToken) => throw new NotImplementedException();
|
||||
public Task FlushPendingMessagesAsync(IBackendManagerDatabase database, CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
public void UpdateThrottleValues(long maxUploadPrSecond, long maxDownloadPrSecond) => throw new NotImplementedException();
|
||||
#endregion
|
||||
|
||||
Reference in New Issue
Block a user