ReFS Reference

$EA_INFORMATION and $EA

Extended attributes (EAs) on ReFS are a two-part structure: $EA_INFORMATION (embedded type 0xD0, schema 0x1D0; v3.7+) is the size index, and $EA (embedded type 0xE0, schema 0x1E0; v3.14+) is the body — a standard NT FILE_FULL_EA_INFORMATION chain. Both are single-instance sub-records in the type-0x10 own-row. EAs are the storage mechanism for WSL Linux metadata ($LXUID, $LXGID, $LXMOD, $LXDEV) and kernel-cache state ($Kernel.Purge.*).

$EA_INFORMATION value layout (type 0xD0)

Sub-record: marker 0x80000001 (single-instance), type code 0x00D0. Fixed 20-byte value:

OffsetSizeFieldDescription
0x004Padding0
0x044Data-area size8
0x084Content offset0x0C
0x0C4PackedEaSizethe NTFS-conventional packed EA size, Σ per-entry 5 + EaNameLength + EaValueLength. Mirrored into $SI+0x50 on v3.10+ (= FCB+0xA0), enabling EA-presence detection without reading the body
0x104Serialized footprintΣ align4(8 + EaNameLength + 1 + EaValueLength) — the on-disk byte footprint of the chain (always ≥ val[0x0C])

The two size fields are distinct: val[0x0C] is the logical PackedEaSize (the value stored at $SI+0x50); val[0x10] is the physical chain length. (RefsReplaceFileEas sets FCB+0xA0 = val[0x0C]; RefsComputeStandardInformationFromFcb reads it into $SI+0x50.)

$EA value layout (type 0xE0)

Sub-record: marker 0x80000001 (single-instance), type code 0x00E0.

OffsetSizeFieldDescription
0x004Padding0
0x044Data-area sizevalue length − 12
0x084Content offset0x0C
0x0CvarEA chainFILE_FULL_EA_INFORMATION entries

Each FILE_FULL_EA_INFORMATION entry (at value+0x0C, chained via NextEntryOffset, 8-byte aligned):

OffsetSizeFieldDescription
0x004NextEntryOffsetoffset to the next entry (0 = last)
0x041Flags0 or FILE_NEED_EA
0x051EaNameLengthname length, excluding the null terminator
0x062EaValueLengthvalue-data length
0x08N+1EaNameASCII name + null terminator
0x08+N+1MEaValueraw value bytes

The per-entry value starts at entry + 8 + EaNameLength + 1.

Common EA names

EA nameValuePurpose
$LXUID4 bytes (u32)WSL Linux UID → FILE_STAT_LX_INFORMATION+0x4c, presence-flag bit 0x1
$LXGID4 bytes (u32)WSL Linux GID → +0x50, bit 0x2
$LXMOD4 bytes (u32 mode_t)WSL permission + file-type bits → +0x54, bit 0x4
$LXDEV8 bytes (u32 major + u32 minor)WSL device number (device nodes only) → major +0x58, minor +0x5c, bit 0x8
$Kernel.Purge.*varkernel-purgeable cache state (the driver matches the $Kernel.Purge. prefix and deletes these in RefsPurgeKernelEA)
$CI.CATALOGHINTvarCode-Integrity catalog hint

The WSL presence-flags word is at FILE_STAT_LX_INFORMATION+0x48 (bits 0x1/0x2/0x4/0x8 for UID/GID/MOD/DEV); the decode is RefsQueryLxMetadataEa, which gates each $LX* on its exact value length. WSL EAs require a -o metadata mount.

Cross-references

Evidence

$EA_INFORMATION (0xD0/0x1D0, v3.7+) and $EA (0xE0/0x1E0, v3.14+) and their layouts are confirmed in the decompiled driver (RefsLookupEasOnFile, RefsReplaceFileEas, RefsQueryLxMetadataEa) and raw-disk decoded across the corpus.