ntfs: include the final partial cluster in sync writes

ntfs_attrlist_repack() synchronously writes the replacement attribute
list before updating its mapping pairs and freeing the old run. With
512-byte clusters, a 544-byte list submits a 512-byte bio, but the
write returns 544 and repack accepts it as complete. If the later
buffered update does not reach disk, the replacement list lacks its
final 32 bytes.

__ntfs_inode_non_resident_attr_pwrite() converts attr_len to clusters
with ntfs_bytes_to_cluster(), which rounds down. Before repack, its
synchronous callers used either cluster-aligned lengths or lengths
smaller than one cluster, where max_t() selects one.

Round attr_len up so repack writes the final partial cluster before
publishing the new mapping pairs.

Fixes: b1d732e62a ("ntfs: repack $MFT/$ATTRIBUTE LIST")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
Karl Mehltretter 2026-09-22 06:33:01 +02:00 committed by Namjae Jeon
parent 17a1edda75
commit fa5489ebc8

View File

@ -3761,7 +3761,9 @@ static s64 __ntfs_inode_non_resident_attr_pwrite(struct inode *vi,
struct runlist_element *rl;
int bio_err;
lcn_count = max_t(s64, 1, ntfs_bytes_to_cluster(vol, attr_len));
lcn_count = max_t(s64, 1,
ntfs_bytes_to_cluster(vol, attr_len +
vol->cluster_size - 1));
vcn = ntfs_pidx_to_cluster(vol, folio->index);
do {