From: Marcin Mennemann <marcin@mennemann.net>
To: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>,
ntfs3@lists.linux.dev
Cc: linux-kernel@vger.kernel.org, Marcin Mennemann <marcin@mennemann.net>
Subject: [PATCH] fs/ntfs3: fix SEEK_DATA/SEEK_HOLE for WOF compressed and dedup files
Date: Tue, 6 Oct 2026 00:33:18 +0200 [thread overview]
Message-ID: <20261005223318.19303-1-marcin@mennemann.net> (raw)
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
next reply other threads:[~2026-10-05 22:33 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-05 22:33 Marcin Mennemann [this message]
2026-10-25 12:24 ` Marcin Mennemann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261005223318.19303-1-marcin@mennemann.net \
--to=marcin@mennemann.net \
--cc=almaz.alexandrovich@paragon-software.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ntfs3@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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®