mirror of
https://github.com/Sonarr/Sonarr
synced 2026-01-24 16:31:24 +01:00
New: Removed Special Handling of Reflinks for BTRFS and ZFS
Closes #7946
This commit is contained in:
parent
d70dcfed56
commit
ee875ae654
5 changed files with 1 additions and 133 deletions
|
|
@ -238,11 +238,6 @@ public void CloneFile(string source, string destination, bool overwrite = false)
|
|||
throw new IOException(string.Format("Source and destination can't be the same {0}", source));
|
||||
}
|
||||
|
||||
CloneFileInternal(source, destination, overwrite);
|
||||
}
|
||||
|
||||
protected virtual void CloneFileInternal(string source, string destination, bool overwrite = false)
|
||||
{
|
||||
CopyFileInternal(source, destination, overwrite);
|
||||
}
|
||||
|
||||
|
|
@ -308,11 +303,6 @@ public virtual bool TryRenameFile(string source, string destination)
|
|||
|
||||
public abstract bool TryCreateHardLink(string source, string destination);
|
||||
|
||||
public virtual bool TryCreateRefLink(string source, string destination)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void DeleteFolder(string path, bool recursive)
|
||||
{
|
||||
Ensure.That(path, () => path).IsValidPath(PathValidationType.CurrentOs);
|
||||
|
|
|
|||
|
|
@ -340,41 +340,15 @@ public TransferMode TransferFile(string sourcePath, string targetPath, TransferM
|
|||
var targetDriveFormat = targetMount?.DriveFormat ?? string.Empty;
|
||||
|
||||
var isCifs = targetDriveFormat == "cifs";
|
||||
var isBtrfs = sourceDriveFormat == "btrfs" && targetDriveFormat == "btrfs";
|
||||
var isZfs = sourceDriveFormat == "zfs" && targetDriveFormat == "zfs";
|
||||
|
||||
if (mode.HasFlag(TransferMode.Copy))
|
||||
{
|
||||
if (isBtrfs || isZfs)
|
||||
{
|
||||
if (_diskProvider.TryCreateRefLink(sourcePath, targetPath))
|
||||
{
|
||||
return TransferMode.Copy;
|
||||
}
|
||||
}
|
||||
|
||||
TryCopyFileVerified(sourcePath, targetPath, originalSize);
|
||||
return TransferMode.Copy;
|
||||
}
|
||||
|
||||
if (mode.HasFlag(TransferMode.Move))
|
||||
{
|
||||
if (isBtrfs || isZfs)
|
||||
{
|
||||
if (isSameMount && _diskProvider.TryRenameFile(sourcePath, targetPath))
|
||||
{
|
||||
_logger.Trace("Renamed [{0}] to [{1}].", sourcePath, targetPath);
|
||||
return TransferMode.Move;
|
||||
}
|
||||
|
||||
if (_diskProvider.TryCreateRefLink(sourcePath, targetPath))
|
||||
{
|
||||
_logger.Trace("Reflink successful, deleting source [{0}].", sourcePath);
|
||||
_diskProvider.DeleteFile(sourcePath);
|
||||
return TransferMode.Move;
|
||||
}
|
||||
}
|
||||
|
||||
if (isCifs && !isSameMount)
|
||||
{
|
||||
_logger.Trace("On cifs mount. Starting verified copy [{0}] to [{1}].", sourcePath, targetPath);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ public interface IDiskProvider
|
|||
void MoveFolder(string source, string destination);
|
||||
bool TryRenameFile(string source, string destination);
|
||||
bool TryCreateHardLink(string source, string destination);
|
||||
bool TryCreateRefLink(string source, string destination);
|
||||
void DeleteFolder(string path, bool recursive);
|
||||
string ReadAllText(string filePath);
|
||||
void WriteAllText(string filename, string contents);
|
||||
|
|
|
|||
|
|
@ -21,13 +21,11 @@ public class DiskProvider : DiskProviderBase
|
|||
private readonly Logger _logger;
|
||||
private readonly IProcMountProvider _procMountProvider;
|
||||
private readonly ISymbolicLinkResolver _symLinkResolver;
|
||||
private readonly ICreateRefLink _createRefLink;
|
||||
|
||||
public DiskProvider(IProcMountProvider procMountProvider, ISymbolicLinkResolver symLinkResolver, ICreateRefLink createRefLink, Logger logger)
|
||||
public DiskProvider(IProcMountProvider procMountProvider, ISymbolicLinkResolver symLinkResolver, Logger logger)
|
||||
{
|
||||
_procMountProvider = procMountProvider;
|
||||
_symLinkResolver = symLinkResolver;
|
||||
_createRefLink = createRefLink;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
|
@ -234,19 +232,6 @@ protected override bool IsSpecialMount(IMount mount)
|
|||
return mount?.TotalSize;
|
||||
}
|
||||
|
||||
protected override void CloneFileInternal(string source, string destination, bool overwrite)
|
||||
{
|
||||
if (!File.Exists(destination) && !UnixFileSystemInfo.GetFileSystemEntry(source).IsSymbolicLink)
|
||||
{
|
||||
if (_createRefLink.TryCreateRefLink(source, destination))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CopyFileInternal(source, destination, overwrite);
|
||||
}
|
||||
|
||||
protected override void CopyFileInternal(string source, string destination, bool overwrite)
|
||||
{
|
||||
var sourceInfo = UnixFileSystemInfo.GetFileSystemEntry(source);
|
||||
|
|
@ -464,11 +449,6 @@ public override bool TryCreateHardLink(string source, string destination)
|
|||
}
|
||||
}
|
||||
|
||||
public override bool TryCreateRefLink(string source, string destination)
|
||||
{
|
||||
return _createRefLink.TryCreateRefLink(source, destination);
|
||||
}
|
||||
|
||||
private uint GetUserId(string user)
|
||||
{
|
||||
if (user.IsNullOrWhiteSpace())
|
||||
|
|
|
|||
|
|
@ -1,75 +0,0 @@
|
|||
using System;
|
||||
using Mono.Unix;
|
||||
using Mono.Unix.Native;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Mono.Interop;
|
||||
|
||||
namespace NzbDrone.Mono.Disk
|
||||
{
|
||||
public interface ICreateRefLink
|
||||
{
|
||||
bool TryCreateRefLink(string srcPath, string linkPath);
|
||||
}
|
||||
|
||||
public class RefLinkCreator : ICreateRefLink
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
private readonly bool _supported;
|
||||
|
||||
public RefLinkCreator(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
|
||||
// Only support x86_64 because we know the FICLONE value is valid for it
|
||||
_supported = OsInfo.IsLinux && (Syscall.uname(out var results) == 0 && results.machine == "x86_64");
|
||||
}
|
||||
|
||||
public bool TryCreateRefLink(string srcPath, string linkPath)
|
||||
{
|
||||
if (!_supported)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (var srcHandle = NativeMethods.open(srcPath, OpenFlags.O_RDONLY))
|
||||
{
|
||||
if (srcHandle.IsInvalid)
|
||||
{
|
||||
_logger.Trace("Failed to create reflink at '{0}' to '{1}': Couldn't open source file", linkPath, srcPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
using (var linkHandle = NativeMethods.open(linkPath, OpenFlags.O_WRONLY | OpenFlags.O_CREAT | OpenFlags.O_TRUNC))
|
||||
{
|
||||
if (linkHandle.IsInvalid)
|
||||
{
|
||||
_logger.Trace("Failed to create reflink at '{0}' to '{1}': Couldn't create new link file", linkPath, srcPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NativeMethods.clone_file(linkHandle, srcHandle) == -1)
|
||||
{
|
||||
var error = new UnixIOException();
|
||||
linkHandle.Dispose();
|
||||
Syscall.unlink(linkPath);
|
||||
_logger.Trace("Failed to create reflink at '{0}' to '{1}': {2}", linkPath, srcPath, error.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.Trace("Created reflink at '{0}' to '{1}'", linkPath, srcPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Syscall.unlink(linkPath);
|
||||
_logger.Trace(ex, "Failed to create reflink at '{0}' to '{1}'", linkPath, srcPath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue