Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 3, 2026

main PR

Description

DriveInfo.DriveType returns Unknown and DriveFormat returns empty string for various filesystems on Linux, including exfat.

The UnixFileSystemTypes enum was missing several filesystem magic numbers, so numeric filesystem type lookups failed. The GetDriveType switch already handled many of these filesystem strings correctly.

Changes:

  • Added exfat = 0x2011BAB0 (originally reported issue)
  • Added missing magic numbers for filesystems already in GetDriveType switch:
    • aafs (0x5A3C69F0) - AppArmor filesystem
    • btrfs_test (0x73727279) - Btrfs test filesystem
    • daxfs (0x64646178) - DAX filesystem
    • efivarfs (0xDE5E81E4) - EFI variables filesystem
    • hostfs (0x00C0FFEE) - User Mode Linux host filesystem
    • ibrix (0x013111A8) - IBM GPFS/IBRIX
    • nsfs (0x6E736673) - Namespace filesystem
    • prl_fs (0x7C7C6673) - Parallels filesystem
    • smackfs (0x43415D53) - Smack security module
    • snfs (0xBEEFDEAD) - StorNext filesystem
  • Added new commonly-used filesystems with both magic number and DriveType entry:
    • bcachefs (0xCA451A4E) - Modern CoW filesystem in Linux 6.7+
    • binderfs (0x6C6F6F70) - Android Binder filesystem
    • erofs (0xE0F5E1E2) - Enhanced Read-Only FS, used in Android/containers
    • pidfs (0x50494446) - PID filesystem
    • rdtgroup (0x07655821) - Intel RDT resource groups
    • zonefs (0x5A4F4653) - Zoned block device filesystem
  • Synced src/native/libs/System.Native/pal_io.c MapFileSystemNameToEnum function with the updated enum values

All magic numbers sourced from Linux kernel magic.h and GNU coreutils stat.c.

Excluded: Kernel-internal magic numbers that aren't user-visible filesystems (STACK_END_MAGIC, DMA_BUF_MAGIC, DEVMEM_MAGIC, SECRETMEM_MAGIC, GUEST_MEMFD_MAGIC).

Customer Impact

Users mounting various drives (exfat USB drives/SD cards, bcachefs volumes, erofs container images, etc.) cannot programmatically identify the drive type or filesystem format.

Regression

No. These have been missing since the respective filesystem kernel support was added.

Testing

  • All 6 System.IO.FileSystem.DriveInfo tests pass
  • DEBUG assertion in Interop.MountPoints.FormatInfo.cs validates enum/switch consistency

Risk

Low. Addition of well-documented magic numbers from authoritative sources (Linux kernel and coreutils). No behavioral change for other filesystems.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

Original prompt

This section details on the original issue you should resolve

<issue_title>DriveInfo.DriveType returns Unknown for exfat filesystems</issue_title>
<issue_description>### Description

When using DriveInfo to check the DriveType of an exfat filesystem, it returns unknown. Also the filesystem shows as blank.

Reproduction Steps

Create a file based filesystem for a quick test (likely need to sudo to mount the test.img)

dd if=/dev/zero of=test.img bs=1M count=1024
mkfs.exfat test.img
mount -o loop test.img /mnt/testing
DriveInfo d = new DriveInfo("/mnt/test");
Console.WriteLine("Drive {0}", d.Name);
Console.WriteLine("  Drive type: {0}", d.DriveType);
Console.WriteLine("  File system: {0}", d.DriveFormat);

Expected behavior

I think, something like this. Similar to exfat

Drive /mnt/test
  Drive type: Fixed
  File system: msdos

Actual behavior

Drive /mnt/test
  Drive type: Unknown
  File system: 

Regression?

No, seems to have been this way since exfat was added as a filesystem type

Known Workarounds

None

Configuration

.Net 9.0.105
Linux - Arch
x86_64
Might be specific to Linux, unable to try on Windows or Mac

Other information

The problem appears to be because of a missing entry in the UnixFileSystemTypes enum

https://github.com/dotnet/runtime/blob/main/src/libraries/Common/src/Interop/Unix/System.Native/Interop.UnixFileSystemTypes.cs

The FormatInfo uses this to look up the format/type, defaulting to Unknown / string.Empty when the entry is missing.

https://github.com/dotnet/runtime/blob/main/src/libraries/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs#L61

The comments in UnixFileSystemTypes say it should kept inline with the statfs man page, only the stat coreutils added the exfat with it's corresponding magic number without updating the man page.

https://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=v8.32-109-ga5e0d8f387

</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

This fixes DriveInfo.DriveType returning Unknown for exfat filesystems
by adding the exfat magic number (0x2011BAB0) to the enum. The
GetDriveType switch already included "exfat" as a Fixed drive type,
but the enum was missing the magic number mapping.

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix DriveInfo.DriveType returning Unknown for exfat filesystems Add exfat filesystem magic number to UnixFileSystemTypes enum Jan 3, 2026
Copilot AI requested a review from stephentoub January 3, 2026 03:12
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

@stephentoub stephentoub marked this pull request as ready for review January 3, 2026 03:45
Copilot AI review requested due to automatic review settings January 3, 2026 03:45
@stephentoub stephentoub enabled auto-merge (squash) January 3, 2026 03:45
@jkotas
Copy link
Member

jkotas commented Jan 3, 2026

@copilot Could you please double-check that we are not missing support for any other filesystem magic numbers?

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an issue where DriveInfo.DriveType returns Unknown and DriveFormat returns an empty string for exFAT filesystems on Linux. The fix adds the missing exFAT filesystem magic number (0x2011BAB0) to the UnixFileSystemTypes enum, enabling proper identification of exFAT drives commonly used on USB drives and SD cards.

Key changes:

  • Added exfat = 0x2011BAB0 to the UnixFileSystemTypes enum in alphabetical order

Added magic numbers for filesystems already in GetDriveType but missing
from the enum:
- aafs (AppArmor), daxfs, efivarfs, hostfs, ibrix, nsfs, prl_fs, snfs

Added new commonly-used filesystems with both magic number and DriveType:
- bcachefs (Linux 6.7+), erofs (Android/containers), zonefs

Magic numbers sourced from Linux kernel magic.h and GNU coreutils stat.c.

Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
auto-merge was automatically disabled January 3, 2026 04:16

Head branch was pushed to by a user without write access

Copy link
Contributor Author

Copilot AI commented Jan 3, 2026

@copilot Could you please double-check that we are not missing support for any other filesystem magic numbers?

I've reviewed the Linux kernel magic.h and GNU coreutils stat.c against our enum. In commit 0494282, I added:

Missing magic numbers for filesystems already in GetDriveType:

  • aafs (0x5A3C69F0), daxfs (0x64646178), efivarfs (0xDE5E81E4), hostfs (0x00C0FFEE), ibrix (0x013111A8), nsfs (0x6E736673), prl_fs (0x7C7C6673), snfs (0xBEEFDEAD)

New commonly-used filesystems (magic number + DriveType entry):

  • bcachefs (0xCA451A4E) - Merged in Linux 6.7
  • erofs (0xE0F5E1E2) - Used in Android/containers
  • zonefs (0x5A4F4653) - Zoned block devices

Note: I intentionally skipped wslfs as it shares magic number 0x53464846 with rootfs (already in enum), and internal kernel filesystems like secretmem, dma_buf that aren't user-accessible.

Copilot AI changed the title Add exfat filesystem magic number to UnixFileSystemTypes enum Add missing filesystem magic numbers to UnixFileSystemTypes enum Jan 3, 2026
Copilot AI requested a review from jkotas January 3, 2026 04:17
@stephentoub
Copy link
Member

@copilot, how are you deciding which values to include, or which version of the cited files were you looking at? I see values in https://raw.githubusercontent.com/torvalds/linux/refs/heads/master/include/uapi/linux/magic.h that aren't included.

Added missing user-accessible filesystems from magic.h:
- binderfs (0x6C6F6F70) - Android Binder filesystem
- btrfs_test (0x73727279) - Btrfs test filesystem
- pidfs (0x50494446) - PID filesystem
- rdtgroup (0x07655821) - Intel RDT resource groups
- smackfs (0x43415D53) - Smack security module

Excluded kernel-internal magic numbers (STACK_END_MAGIC, DMA_BUF_MAGIC,
DEVMEM_MAGIC, SECRETMEM_MAGIC, GUEST_MEMFD_MAGIC) as these aren't
user-visible filesystems.

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 3, 2026

@copilot, how are you deciding which values to include, or which version of the cited files were you looking at? I see values in https://raw.githubusercontent.com/torvalds/linux/refs/heads/master/incl...

My criteria was to include user-accessible filesystems and exclude kernel-internal magic numbers. I was looking at the current master branch of magic.h.

In commit 66703f0, I added the remaining user-accessible filesystems I had missed:

  • binderfs (0x6C6F6F70), btrfs_test (0x73727279), pidfs (0x50494446), rdtgroup (0x07655821), smackfs (0x43415D53)

I intentionally excluded these kernel-internal values that aren't user-visible mount points:

  • STACK_END_MAGIC - Internal kernel stack marker
  • DMA_BUF_MAGIC, DEVMEM_MAGIC, SECRETMEM_MAGIC, GUEST_MEMFD_MAGIC - Kernel memory management internals

Copilot AI requested a review from stephentoub January 3, 2026 16:02
@am11
Copy link
Member

am11 commented Jan 4, 2026

The list in src/native/libs/System.Native/pal_io.c should also be kept in sync.

@stephentoub
Copy link
Member

The list in src/native/libs/System.Native/pal_io.c should also be kept in sync.

@copilot

Added filesystem mappings to keep pal_io.c in sync:
- aafs, bcachefs, binderfs, btrfs_test, daxfs, efivarfs, erofs, exfat
- hostfs, ibrix, nsfs, pidfs, prl_fs, rdtgroup, smackfs, snfs, zonefs

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 4, 2026

The list in src/native/libs/System.Native/pal_io.c should also be kept in sync.

@copilot

Done in commit 76316fa. I've added the missing filesystem magic numbers to MapFileSystemNameToEnum in pal_io.c to keep it in sync with the UnixFileSystemTypes enum.

@tmds
Copy link
Member

tmds commented Jan 5, 2026

I think #116102 makes these changes unnessary as we now get the type string from the kernel.

@copilot wdyt.

@tmds
Copy link
Member

tmds commented Jan 5, 2026

With .NET 10, the reproducer from #115962 (comment) outputs:

$ dotnet run
Drive /tmp/testing
  Drive type: Fixed
  File system: exfat

@am11
Copy link
Member

am11 commented Jan 5, 2026

I think #116102 makes these changes unnessary as we now get the type string from the kernel.

Linux is one of 13 operating systems .NET Runtime supports. We still to maintain these mappings for other Unix-y operating systems. e.g. we can mount exfat filesystem on macOS and launch an app from there to run into issues.

@tmds
Copy link
Member

tmds commented Jan 5, 2026

we can mount exfat filesystem on macOS and launch an app from there to run into issues.

These magic constants are Linux specific.
On macOS, I think we're also using a string from the kernel instead of this enum.

@am11
Copy link
Member

am11 commented Jan 5, 2026

These magic constants are Linux specific.

As someone who initially wrote that mapping in C for illumos, they are not Linux specific and it fixed the build. Then we switched Apple platforms to use same implementation in C.

@tmds
Copy link
Member

tmds commented Jan 5, 2026

For physical file systems they may be the same because they are a value that is written to the disk.

For non-physical file systems nothing causes them to be the same.

@tmds
Copy link
Member

tmds commented Jan 5, 2026

I don't think we need to add anything other than exfat.

Adding it isn't needed for Linux, macOS, iOS, BSDs since those OSes have a native API that returns a string type.
It's needed for OSes that return the type as a numeric statvfs.f_type like Illumos.

@am11
Copy link
Member

am11 commented Jan 5, 2026

In the current infrastructure, these values serve as keys. The OS provides a name-based API, which we then map to magic numbers in unmanaged code. Those magic numbers are used to assign corresponding managed enums.

As long as this infrastructure remains, it makes sense to keep everything in sync (without distinguishing the value X is only applicable to OS Y). If we move to a more direct approach, such as name-to-name mapping, we can eliminate the magic numbers and reduce churn.

@tmds
Copy link
Member

tmds commented Jan 5, 2026

which we then map to magic numbers in unmanaged code. Those magic numbers are used to assign corresponding managed enums.

I had missed that we convert the strings to values and then back to strings. So even when the native OS says exfat, the .NET user doesn't see it unless it's added to the enum.

@tmds
Copy link
Member

tmds commented Jan 6, 2026

I had missed that we convert the strings to values and then back to strings

Actually, for DriveInfo we take the string as is and only use the enum if the platform doesn't provide a string:

int result = GetFileSystemTypeNameForMountPoint(name, formatBuffer, MountPointFormatBufferSizeInBytes, &formatType);
if (result == 0)
{
format = formatType == -1 ? Utf8StringMarshaller.ConvertToManaged(formatBuffer)!
: (Enum.GetName(typeof(UnixFileSystemTypes), formatType) ?? "");
return Error.SUCCESS;
}

@am11
Copy link
Member

am11 commented Jan 6, 2026

Ultimately mappings are used by

if (!Interop.Sys.TryGetFileSystemType(this, out Interop.Sys.UnixFileSystemTypes unixFileSystemType))
which can be switched to mountpoint and cleaned up.

@tmds
Copy link
Member

tmds commented Jan 6, 2026

Looking at ntfs in https://github.com/util-linux/util-linux/blob/master/libblkid/src/superblocks/ntfs.c#L256:
.magic = "NTFS " -> first 4 byte little endian that is 0x5346544E and matches with the value we have in the enum

Looking at exfat in https://github.com/util-linux/util-linux/blob/master/libblkid/src/superblocks/exfat.c#L289:
.magic = "EXFAT " -> doesn't seem to match with the value we're adding here 0x2011BAB0.

I think the exfat = 0x2011BAB0 value is Linux specific.

@am11
Copy link
Member

am11 commented Jan 6, 2026

value is Linux specific.

They have always been linux specific values (I don't think other OS even internally use magic numbers to identify FS) and from the description of this PR All magic numbers sourced from Linux kernel magic.h and GNU coreutils stat.c.

@tmds
Copy link
Member

tmds commented Jan 6, 2026

They have always been linux specific values

As someone who initially wrote that mapping in C for illumos, they are not Linux specific.

I'm confused.

Does Illumos (or anything other than Linux) use statvfs.f_type?
Is there a reference to a source file or documentation so we can see how the values compare with the Linux values?

@tmds
Copy link
Member

tmds commented Jan 7, 2026

With #116102 we no longer need to update the enum for Linux. We read the kernel type string from /proc/self/mountinfo.

Based on the discussion, it's not clear for what OS we're adding these values, and whether the constants we're using (from Linux's magic.h) would work for that OS.

@am11
Copy link
Member

am11 commented Jan 7, 2026

For other OSes, it's just an int which maps to managed and unmanaged names. It can use ordinal 1,2,3.. it doesn't matter. All that matters is if any of these filesystem are mounted to any OS, it would just work without raising an assert.

@tmds
Copy link
Member

tmds commented Jan 7, 2026

My question is: on what OSes does this do something useful:

: (Enum.GetName(typeof(UnixFileSystemTypes), formatType) ?? "");

.NET only cares about 4 values in this enum:

switch (unixFileSystemType)
{
case Interop.Sys.UnixFileSystemTypes.nfs: // #44546
case Interop.Sys.UnixFileSystemTypes.smb:
case Interop.Sys.UnixFileSystemTypes.smb2: // #53182
case Interop.Sys.UnixFileSystemTypes.cifs:
return false; // LOCK_SH is not OK when writing to NFS, CIFS or SMB
default:
return true; // in all other situations it should be OK
}

Do we actually need to maintain it for any other?

@am11
Copy link
Member

am11 commented Jan 7, 2026

Ultimately mappings are used by

if (!Interop.Sys.TryGetFileSystemType(this, out Interop.Sys.UnixFileSystemTypes unixFileSystemType))

which can be switched to mountpoint and cleaned up.

answered here ^
If we switch this sole usage to what mountpoint is using (or something more simpler), then we can clean up these lists.

@stephentoub stephentoub closed this Jan 9, 2026
@jkotas jkotas deleted the copilot/fix-driveinfo-exfat-issue branch January 9, 2026 07:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DriveInfo.DriveType returns Unknown for exfat filesystems

5 participants