Re: [REGRESSION 7.2] exfat: stale dentry buffer of a deleted directory overwrites new file data
From: Namjae Jeon
Date: Fri Oct 09 2026 - 22:18:15 EST
Hi,
> A candidate fix (not a formal patch; tested only with this
> reproducer, all cases above 0/N on v7.3-rc6 with it applied):
>
> --- a/fs/exfat/iomap.c
> +++ b/fs/exfat/iomap.c
> @@ -7,6 +7,7 @@
>
> #include <linux/iomap.h>
> #include <linux/pagemap.h>
> +#include <linux/buffer_head.h>
>
> #include "exfat_raw.h"
> #include "exfat_fs.h"
> @@ -77,6 +78,21 @@
> if (err)
> goto out;
>
> + /*
> + * New clusters may still have dirty buffer_heads in the bdev
> + * mapping (e.g. dentries of a just-removed directory). Drop
> + * them, as __block_write_begin_int() did for buffer_new
> + * blocks, so a later bdev flush cannot write stale metadata
> + * over the new file data.
> + */
> + if (balloc) {
> + sector_t first = exfat_cluster_to_sector(sbi, cluster);
> + sector_t nr = (sector_t)num_clusters <<
> + sbi->sect_per_clus_bits;
> +
> + clean_bdev_aliases(sb->s_bdev, first, nr);
> + }
> +
> cluster_offset = exfat_cluster_offset(sbi, offset);
> cluster_length = exfat_cluster_to_bytes(sbi, num_clusters);
Thanks for the report and fixes! Your fix seems to miss clusters
allocated by fallocate() or an extending ftruncate(). These operations
allocate clusters before data I/O, so balloc is false when the
clusters are later mapped for writing, and clean_bdev_aliases() can be
skipped. Could you send a patch that moves the cleanup to
exfat_alloc_cluster(), using one call per contiguous range?