A small file can use more MFT records if its attribute list is too large to fit in a single record.
When there is no more space for storing attributes in the file record segment, additional file record segments are allocated and inserted in the first (or base) file record segment in an attribute called the attribute list. The attribute list indicates where each attribute associated with the file can be found. This includes all attributes in the base file record, except for the attribute list itself. For more information, see ATTRIBUTE_LIST_ENTRY
.
https://learn.microsoft.com/en-us/windows/desktop/devnotes/master-file-table
An example of this is when it has a large number of ADS. I created a file that consumes most of the MFT record space (1000/1024 bytes as you can see below)
PS D:\> fsutil file queryoptimizemetadata .\test.txt
File metadata optimization : None
Attribute list size : 0 (0)
File metadata space used : 1000 (0x3e8)
File metadata space allocated : 1024 (0x400)
File metadata space usage : 97%
File records count(s) : 1
Number of resident attribute(s) : 3
Number of nonresident attribute(s) : 8
Total number of attributes : 11
Total active file metadata optimization(s) : 0
Total pending file metadata optimization(s) : 0
After I added another stream you can see that the File metadata space allocated has been doubled to 2048 bytes, i.e. 2 records, and ATTRIBUTE_LIST
has to be used which takes 448 bytes
PS D:\> cat .\test.txt | Set-Content -path .\test.txt -Stream stream8
PS D:\> fsutil file queryoptimizemetadata .\test.txt
File metadata optimization : None
Attribute list size : 448 (0x1c0)
File metadata space used : 1624 (0x658)
File metadata space allocated : 2048 (0x800)
File metadata space usage : 79%
File records count(s) : 2
Number of resident attribute(s) : 4
Number of nonresident attribute(s) : 9
Total number of attributes : 13
Total active file metadata optimization(s) : 0
Total pending file metadata optimization(s) : 0
This can also happen if the file is too fragmented (or too many holes in a sparse file) and the record doesn't have enough space to store the extent list. Other possibilities are too complex permissions, or multiple hard links like others mentioned
$ATTRIBUTE_LIST
may be needed if the file:
- has a large number of hard links (lots of file name attributes present).
- becomes very fragmented, so the data runs overflow the MFT record.
- has a complex security descriptor (not applicable to NTFS v3.0+)
- has many named streams, e.g. data streams.
https://flatcap.org/linux-ntfs/ntfs/attributes/attribute_list.html
More information can be found in Can the NTFS $MFT file have child records?