merge 2.0.0 into migration
This commit is contained in:
@@ -4,6 +4,7 @@ using LightlessSync.Services.Compactor;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Channels;
|
||||
@@ -16,6 +17,7 @@ public sealed partial class FileCompactor : IDisposable
|
||||
public const uint FSCTL_DELETE_EXTERNAL_BACKING = 0x90314U;
|
||||
public const ulong WOF_PROVIDER_FILE = 2UL;
|
||||
public const int _maxRetries = 3;
|
||||
private readonly bool _isWindows;
|
||||
|
||||
private readonly ConcurrentDictionary<string, byte> _pendingCompactions;
|
||||
private readonly ILogger<FileCompactor> _logger;
|
||||
@@ -263,24 +265,12 @@ public sealed partial class FileCompactor : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
bool isWine = _dalamudUtilService?.IsWine ?? false;
|
||||
var (_, linuxPath) = ResolvePathsForBtrfs(fileInfo.FullName);
|
||||
|
||||
string linuxPath = isWine ? ToLinuxPathIfWine(fileInfo.FullName, isWine)
|
||||
: fileInfo.FullName;
|
||||
|
||||
(bool ok, string so, string se, int code) res;
|
||||
|
||||
res = isWine
|
||||
? RunProcessShell($"stat -c %b -- {QuoteSingle(linuxPath)}", timeoutMs: 10000)
|
||||
: RunProcessDirect("stat", ["-c", "%b", "--", linuxPath], "/", 10000);
|
||||
|
||||
var outTrim = res.so?.Trim() ?? "";
|
||||
|
||||
if (res.ok && long.TryParse(outTrim, out long blocks) && blocks >= 0)
|
||||
{
|
||||
// st_blocks are 512-byte units
|
||||
return (flowControl: false, value: blocks * 512L);
|
||||
}
|
||||
var (ok, output, err, code) =
|
||||
_isWindows
|
||||
? RunProcessShell($"stat -c='%b' {QuoteSingle(linuxPath)}", workingDir: null, 10000)
|
||||
: RunProcessDirect("stat", ["-c='%b'", linuxPath], workingDir: null, 10000);
|
||||
|
||||
if (_logger.IsEnabled(LogLevel.Debug))
|
||||
_logger.LogDebug("Btrfs size probe failed for {linux} (exit {code}). stdout='{so}' stderr='{se}'. Falling back to Length.", linuxPath, res.code, outTrim, (res.se ?? "").Trim());
|
||||
@@ -305,17 +295,28 @@ public sealed partial class FileCompactor : IDisposable
|
||||
try
|
||||
{
|
||||
var blockSize = GetBlockSizeForPath(fileInfo.FullName, _logger, _dalamudUtilService.IsWine);
|
||||
var losize = GetCompressedFileSizeW(fileInfo.FullName, out uint hosize);
|
||||
var size = (long)hosize << 32 | losize;
|
||||
return (flowControl: false, value: ((size + blockSize - 1) / blockSize) * blockSize);
|
||||
if (blockSize <= 0)
|
||||
throw new InvalidOperationException($"Invalid block size {blockSize} for {fileInfo.FullName}");
|
||||
|
||||
uint lo = GetCompressedFileSizeW(fileInfo.FullName, out uint hi);
|
||||
|
||||
if (lo == 0xFFFFFFFF)
|
||||
{
|
||||
int err = Marshal.GetLastWin32Error();
|
||||
if (err != 0)
|
||||
throw new Win32Exception(err);
|
||||
}
|
||||
|
||||
long size = ((long)hi << 32) | lo;
|
||||
long rounded = ((size + blockSize - 1) / blockSize) * blockSize;
|
||||
|
||||
return (flowControl: false, value: rounded);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (_logger.IsEnabled(LogLevel.Debug))
|
||||
_logger.LogDebug(ex, "Failed stat size for {file}, fallback to Length", fileInfo.FullName);
|
||||
_logger.LogDebug(ex, "Failed stat size for {file}, fallback to Length", fileInfo.FullName);
|
||||
return (flowControl: true, value: default);
|
||||
}
|
||||
|
||||
return (flowControl: true, value: default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1149,18 +1150,16 @@ public sealed partial class FileCompactor : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
var pathToOpen = _isWindows ? winePath : linuxPath;
|
||||
|
||||
if (string.IsNullOrEmpty(pathToOpen) || !File.Exists(pathToOpen))
|
||||
return false;
|
||||
|
||||
using var _ = new FileStream(pathToOpen, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
if (_isWindows)
|
||||
{
|
||||
using var _ = new FileStream(winePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
}
|
||||
else
|
||||
{
|
||||
using var _ = new FileStream(linuxPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user