[Bug 264196] filesystems/ntfs: read(2)ing big files in blocks of 32768 bytes and smaller fails with EINVAL

From: <bugzilla-noreply_at_freebsd.org>
Date: Thu, 10 Jul 2025 19:23:08 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=264196

--- Comment #16 from Gleb Popov <arrowd@FreeBSD.org> ---
It seems I'm getting close. First, quick recap:

* Mount an NTFS volume with a 4G file using ntfs-3g from filesystems/ntfs build
without the UBLIO option
* Read a byte from the file with "dd if=/mnt/file of=/dev/zero bs=1 count=1"
three times
* The second call fails with EINVAL while first and third succeed

Here are my findings after this round of debugging:

* FUSE receives EINVAL from the cluster_read() call there:
https://github.com/freebsd/freebsd-src/blob/d1f0ee548c73fa4d6e097539b9be01dae683b99b/sys/fs/fuse/fuse_io.c#L181-L182
* seqcount=2 in all 3 cases
* It feels like cluster_read (
https://github.com/freebsd/freebsd-src/blob/d1f0ee548c73fa4d6e097539b9be01dae683b99b/sys/kern/vfs_cluster.c#L89
) does something wrong wrt to handling errors from VOP_BMAP calls.

1. First (successful) dd call:

* We get into
https://github.com/freebsd/freebsd-src/blob/d1f0ee548c73fa4d6e097539b9be01dae683b99b/sys/kern/vfs_cluster.c#L229
and B_RAM flag is set on bp
* Call to VOP_BMAP in
https://github.com/freebsd/freebsd-src/blob/d1f0ee548c73fa4d6e097539b9be01dae683b99b/sys/kern/vfs_cluster.c#L262
returns EINVAL (this by itself is either OK or a bug in the NTFS usermode code
and is not relevant to this issue)
* We get into
https://github.com/freebsd/freebsd-src/blob/d1f0ee548c73fa4d6e097539b9be01dae683b99b/sys/kern/vfs_cluster.c#L323
and error=EINVAL gets overwritten by 0
* 0 is returned in everything is OK

2. Second (failing) dd call:

* We get into the "B_CACHE" case there:
https://github.com/freebsd/freebsd-src/blob/d1f0ee548c73fa4d6e097539b9be01dae683b99b/sys/kern/vfs_cluster.c#L171
and set reqbp=NULL
* The same VOP_BMAP calls happens with the same EINVAL failure
https://github.com/freebsd/freebsd-src/blob/d1f0ee548c73fa4d6e097539b9be01dae683b99b/sys/kern/vfs_cluster.c#L262
* Since reqbp==NULL, we do not get into
https://github.com/freebsd/freebsd-src/blob/d1f0ee548c73fa4d6e097539b9be01dae683b99b/sys/kern/vfs_cluster.c#L318
and error preserves EINVAL, which is then returned
* FUSE code thinks the operation has failed

3. Third (successful) dd call:

* We quickly get into
https://github.com/freebsd/freebsd-src/blob/d1f0ee548c73fa4d6e097539b9be01dae683b99b/sys/kern/vfs_cluster.c#L139
and everything is fine

I have about zero understanding of all that means, but it feels like
cluster_read() handles errors coming from VOP_BMAP in a wrong way.

-- 
You are receiving this mail because:
You are the assignee for the bug.