Skip to content

Commit cb1fd54

Browse files
adamsitniktmds
andauthored
File system type fix (#69484)
Co-authored-by: Tom Deseyn <[email protected]>
1 parent da51411 commit cb1fd54

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

src/libraries/Common/src/Interop/Unix/System.Native/Interop.UnixFileSystemTypes.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System;
5+
using System.Diagnostics;
46
using System.Runtime.InteropServices;
57
using Microsoft.Win32.SafeHandles;
68

@@ -16,12 +18,13 @@ internal static partial class Sys
1618
/// where this enum must be a subset of the GetDriveType list, with the enum
1719
/// values here exactly matching a string there.
1820
/// </remarks>
19-
internal enum UnixFileSystemTypes : long
21+
internal enum UnixFileSystemTypes : uint
2022
{
2123
adfs = 0xADF5,
2224
affs = 0xADFF,
2325
afs = 0x5346414F,
2426
anoninode = 0x09041934,
27+
apfs = 0x1A,
2528
aufs = 0x61756673,
2629
autofs = 0x0187,
2730
autofs4 = 0x6D4A556D,
@@ -146,13 +149,14 @@ internal enum UnixFileSystemTypes : long
146149
}
147150

148151
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetFileSystemType")]
149-
private static partial long GetFileSystemType(SafeFileHandle fd);
152+
private static partial uint GetFileSystemType(SafeFileHandle fd);
150153

151154
internal static bool TryGetFileSystemType(SafeFileHandle fd, out UnixFileSystemTypes fileSystemType)
152155
{
153-
long fstatfsResult = GetFileSystemType(fd);
156+
uint fstatfsResult = GetFileSystemType(fd);
154157
fileSystemType = (UnixFileSystemTypes)fstatfsResult;
155-
return fstatfsResult != -1;
158+
Debug.Assert(Enum.IsDefined(fileSystemType) || fstatfsResult == 0 || !OperatingSystem.IsLinux(), $"GetFileSystemType returned {fstatfsResult}");
159+
return fstatfsResult != 0;
156160
}
157161
}
158162
}

src/native/libs/System.Native/pal_io.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,27 +1477,33 @@ static int16_t ConvertLockType(int16_t managedLockType)
14771477
}
14781478
}
14791479

1480-
int64_t SystemNative_GetFileSystemType(intptr_t fd)
1480+
uint32_t SystemNative_GetFileSystemType(intptr_t fd)
14811481
{
14821482
#if HAVE_STATFS_VFS || HAVE_STATFS_MOUNT
14831483
int statfsRes;
14841484
struct statfs statfsArgs;
14851485
// for our needs (get file system type) statfs is always enough and there is no need to use statfs64
14861486
// which got deprecated in macOS 10.6, in favor of statfs
14871487
while ((statfsRes = fstatfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ;
1488-
return statfsRes == -1 ? (int64_t)-1 : (int64_t)statfsArgs.f_type;
1488+
if (statfsRes == -1) return 0;
1489+
1490+
// On Linux, f_type is signed. This causes some filesystem types to be represented as
1491+
// negative numbers on 32-bit platforms. We cast to uint32_t to make them positive.
1492+
uint32_t result = (uint32_t)statfsArgs.f_type;
1493+
return result;
14891494
#elif !HAVE_NON_LEGACY_STATFS
14901495
int statfsRes;
14911496
struct statvfs statfsArgs;
14921497
while ((statfsRes = fstatvfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ;
1493-
if (statfsRes == -1) return (int64_t)-1;
1498+
if (statfsRes == -1) return 0;
14941499

1495-
int64_t result = -1;
1500+
uint32_t result = 0;
14961501

14971502
if (strcmp(statfsArgs.f_basetype, "adfs") == 0) result = 0xADF5;
14981503
else if (strcmp(statfsArgs.f_basetype, "affs") == 0) result = 0xADFF;
14991504
else if (strcmp(statfsArgs.f_basetype, "afs") == 0) result = 0x5346414F;
15001505
else if (strcmp(statfsArgs.f_basetype, "anoninode") == 0) result = 0x09041934;
1506+
else if (strcmp(statfsArgs.f_basetype, "apfs") == 0) result = 0x1A;
15011507
else if (strcmp(statfsArgs.f_basetype, "aufs") == 0) result = 0x61756673;
15021508
else if (strcmp(statfsArgs.f_basetype, "autofs") == 0) result = 0x0187;
15031509
else if (strcmp(statfsArgs.f_basetype, "autofs4") == 0) result = 0x6D4A556D;
@@ -1618,7 +1624,7 @@ int64_t SystemNative_GetFileSystemType(intptr_t fd)
16181624
else if (strcmp(statfsArgs.f_basetype, "udev") == 0) result = 0x01021994;
16191625
else if (strcmp(statfsArgs.f_basetype, "zfs") == 0) result = 0x2FC12FC1;
16201626

1621-
assert(result != -1);
1627+
assert(result != 0);
16221628
return result;
16231629
#else
16241630
#error "Platform doesn't support fstatfs or fstatvfs"

src/native/libs/System.Native/pal_io.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,9 +739,9 @@ PALEXPORT char* SystemNative_RealPath(const char* path);
739739
PALEXPORT int32_t SystemNative_GetPeerID(intptr_t socket, uid_t* euid);
740740

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

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

0 commit comments

Comments
 (0)