Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,10 @@ private static AudiobookFile CreatePhysicalGenerationSnapshot(
string? source,
bool replaceMetadata)
{
var fileInfo = new FileInfo(registrationLease.MetadataPath);
var replacement = AudiobookFile.CreateUnresolved(currentFile.Path);
replacement.AudiobookId = currentFile.AudiobookId;
replacement.Size = fileInfo.Exists ? fileInfo.Length : currentFile.Size;
replacement.Size = TryGetRegisteredFileLength(registrationLease.MetadataPath)
?? currentFile.Size;
replacement.DurationSeconds = replaceMetadata
? metadata?.Duration.TotalSeconds
: Math.Abs(metadata?.Duration.TotalSeconds ?? 0) > double.Epsilon
Expand Down
29 changes: 27 additions & 2 deletions listenarr.application/Audiobooks/Files/AudiobookFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,9 @@ private async Task<bool> EnsureAudiobookFileCoreAsync(
cacheIdentity,
filePath);

var fi = new FileInfo(metadataPath);
var fileRecord = AudiobookFile.CreateUnresolved(filePath);
fileRecord.AudiobookId = audiobook.Id;
fileRecord.Size = fi.Exists ? fi.Length : null;
fileRecord.Size = TryGetRegisteredFileLength(metadataPath);
fileRecord.Source = source;
fileRecord.CreatedAt = DateTime.UtcNow;
fileRecord.DurationSeconds = meta?.Duration.TotalSeconds;
Expand Down Expand Up @@ -442,6 +441,32 @@ private static string ResolveAbsolutePath(string? path) =>
? string.Empty
: FileSystemPathIdentity.ResolveNativeAbsolutePath(path);

/// <summary>
/// Read the byte length of the file behind a registration metadata path.
/// The pinned lease's metadata path is a /proc/self/fd magic link on
/// Linux, and FileSystemInfo reads the link inode itself, whose reported
/// size is a constant 64 — not the file's length. Opening the path
/// follows the link to the pinned file, so the stream length is the real
/// size of the exact object the lease holds open.
/// </summary>
private static long? TryGetRegisteredFileLength(string metadataPath)
{
try
{
using var stream = new FileStream(
metadataPath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite | FileShare.Delete);
return stream.Length;
}
catch (Exception exception) when (exception is IOException
or UnauthorizedAccessException or NotSupportedException)
{
return null;
}
}

private void LogClaimRejection(
int audiobookId,
string path,
Expand Down