Skip to content

Commit

Permalink
File system type fix (#69484)
Browse files Browse the repository at this point in the history
Co-authored-by: Tom Deseyn <[email protected]>
  • Loading branch information
adamsitnik and tmds authored May 26, 2022
1 parent da51411 commit cb1fd54
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
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 @@ -1477,27 +1477,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 @@ -1618,7 +1624,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

0 comments on commit cb1fd54

Please sign in to comment.