Skip to content
Merged
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
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

Expand All @@ -16,12 +18,13 @@ internal static partial class Sys
/// where this enum must be a subset of the GetDriveType list, with the enum
/// values here exactly matching a string there.
/// </remarks>
internal enum UnixFileSystemTypes : long
internal enum UnixFileSystemTypes : uint
{
adfs = 0xADF5,
affs = 0xADFF,
afs = 0x5346414F,
anoninode = 0x09041934,
apfs = 0x1A,
aufs = 0x61756673,
autofs = 0x0187,
autofs4 = 0x6D4A556D,
Expand Down Expand Up @@ -146,13 +149,14 @@ internal enum UnixFileSystemTypes : long
}

[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetFileSystemType")]
private static partial long GetFileSystemType(SafeFileHandle fd);
private static partial uint GetFileSystemType(SafeFileHandle fd);

internal static bool TryGetFileSystemType(SafeFileHandle fd, out UnixFileSystemTypes fileSystemType)
{
long fstatfsResult = GetFileSystemType(fd);
uint fstatfsResult = GetFileSystemType(fd);
fileSystemType = (UnixFileSystemTypes)fstatfsResult;
return fstatfsResult != -1;
Debug.Assert(Enum.IsDefined(fileSystemType) || fstatfsResult == 0 || !OperatingSystem.IsLinux(), $"GetFileSystemType returned {fstatfsResult}");
return fstatfsResult != 0;
}
}
}
16 changes: 11 additions & 5 deletions src/native/libs/System.Native/pal_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1472,27 +1472,33 @@ static int16_t ConvertLockType(int16_t managedLockType)
}
}

int64_t SystemNative_GetFileSystemType(intptr_t fd)
uint32_t SystemNative_GetFileSystemType(intptr_t fd)
{
#if HAVE_STATFS_VFS || HAVE_STATFS_MOUNT
int statfsRes;
struct statfs statfsArgs;
// for our needs (get file system type) statfs is always enough and there is no need to use statfs64
// which got deprecated in macOS 10.6, in favor of statfs
while ((statfsRes = fstatfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ;
return statfsRes == -1 ? (int64_t)-1 : (int64_t)statfsArgs.f_type;
if (statfsRes == -1) return 0;

// On Linux, f_type is signed. This causes some filesystem types to be represented as
// negative numbers on 32-bit platforms. We cast to uint32_t to make them positive.
uint32_t result = (uint32_t)statfsArgs.f_type;
return result;
#elif !HAVE_NON_LEGACY_STATFS
int statfsRes;
struct statvfs statfsArgs;
while ((statfsRes = fstatvfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ;
if (statfsRes == -1) return (int64_t)-1;
if (statfsRes == -1) return 0;

int64_t result = -1;
uint32_t result = 0;

if (strcmp(statfsArgs.f_basetype, "adfs") == 0) result = 0xADF5;
else if (strcmp(statfsArgs.f_basetype, "affs") == 0) result = 0xADFF;
else if (strcmp(statfsArgs.f_basetype, "afs") == 0) result = 0x5346414F;
else if (strcmp(statfsArgs.f_basetype, "anoninode") == 0) result = 0x09041934;
else if (strcmp(statfsArgs.f_basetype, "apfs") == 0) result = 0x1A;
else if (strcmp(statfsArgs.f_basetype, "aufs") == 0) result = 0x61756673;
else if (strcmp(statfsArgs.f_basetype, "autofs") == 0) result = 0x0187;
else if (strcmp(statfsArgs.f_basetype, "autofs4") == 0) result = 0x6D4A556D;
Expand Down Expand Up @@ -1613,7 +1619,7 @@ int64_t SystemNative_GetFileSystemType(intptr_t fd)
else if (strcmp(statfsArgs.f_basetype, "udev") == 0) result = 0x01021994;
else if (strcmp(statfsArgs.f_basetype, "zfs") == 0) result = 0x2FC12FC1;

assert(result != -1);
assert(result != 0);
return result;
#else
#error "Platform doesn't support fstatfs or fstatvfs"
Expand Down
4 changes: 2 additions & 2 deletions src/native/libs/System.Native/pal_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -739,9 +739,9 @@ PALEXPORT char* SystemNative_RealPath(const char* path);
PALEXPORT int32_t SystemNative_GetPeerID(intptr_t socket, uid_t* euid);

/**
* Returns file system type on success, or -1 on error.
* Returns file system type on success, or 0 on error.
*/
PALEXPORT int64_t SystemNative_GetFileSystemType(intptr_t fd);
PALEXPORT uint32_t SystemNative_GetFileSystemType(intptr_t fd);

/**
* Attempts to lock/unlock the region of the file "fd" specified by the offset and length. lockType
Expand Down