Re: [PATCH] fs/ntfs3: load ATTR_BITMAP run extents from $MFT extension records

Konstantin Komarov <[email protected]> Wed, 15 Jul 2026 19:02:37 +0200
Newsgroups dev.linux.lists.ntfs3,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 6/10/26 07:45, Senjin wrote:

> When $MFT's ATTR_BITMAP attribute is heavily fragmented, its run list
> can span multiple MFT extension records (attribute list entries with
> vcn > 0). The non-primary segment handler in ntfs_read_mft() only
> processed ATTR_DATA extension segments for MFT_REC_MFT, silently
> skipping any ATTR_BITMAP segments. This left sbi->mft.bitmap.run
> incomplete, causing wnd_init() to fail with -ENOENT when wnd_rescan()
> tried to look up a VCN not covered by the truncated run list.
>
> Observed on a 16 TB NTFS volume (0xFFFFFEFF total clusters) whose MFT
> bitmap run list was split across 97 extents in extension records.
> wnd_rescan() successfully looked up VCNs 0-122 from the runs loaded
> from the base record, then failed at VCN 123 (the last cluster of the
> bitmap) whose run was only present in an extension record.
>
> Fix by extending the MFT_REC_MFT special case to also handle
> ATTR_BITMAP extension segments, storing their runs into
> sbi->mft.bitmap.run the same way the primary segment does.
>
> Signed-off-by: Senjin <[email protected]>
> ---
>   fs/ntfs3/inode.c | 10 +++++++---
>   1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
> index XXXXXXX..XXXXXXX 100644
> --- a/fs/ntfs3/inode.c
> +++ b/fs/ntfs3/inode.c
> @@ -128,11 +128,16 @@ static struct inode *ntfs_read_mft(struct inode *inode,
>
>          if (le && le->vcn) {
>                  /* This is non primary attribute segment. Ignore if not MFT. */
> -               if (ino != MFT_REC_MFT || attr->type != ATTR_DATA)
> +               if (ino != MFT_REC_MFT)
>                          goto next_attr;
>
> -               run = &ni->file.run;
> +               if (attr->type == ATTR_DATA)
> +                       run = &ni->file.run;
> +               else if (attr->type == ATTR_BITMAP)
> +                       run = &sbi->mft.bitmap.run;
> +               else
> +                       goto next_attr;
> +
>                  asize = le32_to_cpu(attr->size);
>                  goto attr_unpack_run;
>          }
> --
> 2.x

Hello,

Very sorry for the delay.
Your patch is applied, thanks.

Regards,
Konstantin