Re: [PATCH v2 4/9] exfat: add support for multi-cluster allocation

From: CharSyam

Date: Thu May 07 2026 - 10:14:31 EST


hi, Namjae.

The critical issue is that this hunk drops the hole-care walk in
exfat_map_cluster():

*clu = new_clu.dir;
+ *count = new_clu.size;

- inode->i_blocks +=
- exfat_cluster_to_sectors(sbi,
num_to_be_allocated) >> 9;
-
- /*
- * Move *clu pointer along FAT chains (hole care) because the
- * caller of this function expect *clu to be the last cluster.
- * This only works when num_to_be_allocated >= 2,
- * *clu = (the first cluster of the allocated chain) =>
- * (the last cluster of ...)
- */
- if (exfat_cluster_walk(sb, clu, num_to_be_allocated
- 1, ei->flags))
- return -EIO;
- *count = 1;
+ inode->i_blocks += exfat_cluster_to_sectors(sbi,
new_clu.size);

The removed comment is explicit: the caller expects *clu to be the
cluster at the requested clu_offset, not necessarily the first cluster
of the newly allocated chain. The old code walked
num_to_be_allocated - 1 steps so that *clu ended up at clu_offset.

With this change, *clu is left as new_clu.dir (the first newly
allocated cluster) and *count is set to new_clu.size. That is only
correct for the sequential-extension case where
clu_offset == num_clusters. For clu_offset > num_clusters, the caller
will compute the physical sector from the wrong cluster:

phys = exfat_cluster_to_sector(sbi, cluster) + sec_offset;

This also interacts badly with the new contig=true allocation mode.
If exfat_alloc_cluster() stops early at a non-contiguous boundary,
new_clu.size can be smaller than num_to_be_allocated, so the allocated
run may not even reach clu_offset while exfat_map_cluster() still
returns success.

Could you keep the old hole-care behavior and extend it to the
multi-cluster case? After allocation, the code should advance from
new_clu.dir to the cluster corresponding to clu_offset, set *count to
the remaining number of clusters from that point, and handle partial
contiguous allocation by either continuing allocation or unwinding it
before returning an error.