mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] fs/ntfs3: fix SEEK_DATA/SEEK_HOLE for WOF compressed and dedup files
@ 2026-10-05 22:33 Marcin Mennemann
  2026-10-25 12:24 ` Marcin Mennemann
  0 siblings, 1 reply; 2+ messages in thread
From: Marcin Mennemann @ 2026-10-05 22:33 UTC (permalink / raw)
  To: Konstantin Komarov, ntfs3; +Cc: linux-kernel, Marcin Mennemann

Since commit c61326967728 ("fs/ntfs3: implement llseek
SEEK_DATA/SEEK_HOLE by scanning data runs"), ntfs_llseek() finds data
and holes by scanning the runs of the unnamed $DATA attribute.

This breaks WOF compressed files. Their data is stored in the
WofCompressedData stream and the unnamed stream is completely sparse,
so SEEK_DATA returns -ENXIO and the whole file looks like a hole.
Deduplicated files keep their data outside the unnamed stream as well.

cp from coreutils uses SEEK_DATA for these files and silently creates a
file full of zeros.

Fix this by using generic_file_llseek_size() for files with
NI_FLAG_COMPRESSED_MASK or NI_FLAG_DEDUPLICATED set, like before the
commit above.

Fixes: c61326967728 ("fs/ntfs3: implement llseek SEEK_DATA/SEEK_HOLE by scanning data runs")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Marcin Mennemann <marcin@mennemann.net>
---

Notes:
    I found this when cp of bootmgfw.efi from my Windows partition gave me
    a file of zeros.
    
    Tested on 7.2.8 with the Windows 11 partition mounted read-only: all
    WOF compressed files I sampled from C:\Windows were reported as one hole
    before the patch and as one data extent after it, and cp of bootmgfw.efi
    went from a zero-filled copy to an identical one. Sparse and LZNT1
    compressed files behave the same with and without the patch.
    
    Not tested: deduplicated files (I have none).

 fs/ntfs3/file.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index 2abf334bfa0c..bbabeea7248e 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -1554,7 +1554,9 @@ static loff_t ntfs_llseek(struct file *file, loff_t offset, int whence)
 	loff_t maxbytes = ntfs_get_maxbytes(ni);
 	loff_t ret;
 
-	if (whence != SEEK_DATA && whence != SEEK_HOLE) {
+	if ((whence != SEEK_DATA && whence != SEEK_HOLE) ||
+	    /* Data of WOF and dedup files is not in the unnamed stream. */
+	    (ni->ni_flags & (NI_FLAG_COMPRESSED_MASK | NI_FLAG_DEDUPLICATED))) {
 		ret = generic_file_llseek_size(file, offset, whence, maxbytes,
 					       i_size_read(inode));
 	} else if ((unsigned long long)offset >= i_size_read(inode)) {

base-commit: 67f0943b394d920b6c142aad8c6af94340342ae7
-- 
2.56.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-25 12:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-05 22:33 [PATCH] fs/ntfs3: fix SEEK_DATA/SEEK_HOLE for WOF compressed and dedup files Marcin Mennemann
2026-10-25 12:24 ` Marcin Mennemann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®