Re: [PATCH v3 08/11] exfat: add iomap buffered I/O support

From: Namjae Jeon

Date: Wed May 13 2026 - 21:47:50 EST


On Thu, May 14, 2026 at 10:39 AM Chi Zhiling <chizhiling@xxxxxxx> wrote:
>
> On 5/13/26 19:21, Namjae Jeon wrote:
> > +static int __exfat_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> > + unsigned int flags, struct iomap *iomap, bool may_alloc)
> > +{
> > + struct super_block *sb = inode->i_sb;
> > + struct exfat_sb_info *sbi = EXFAT_SB(sb);
> > + struct exfat_inode_info *ei = EXFAT_I(inode);
> > + unsigned int cluster, num_clusters;
> > + loff_t cluster_offset, cluster_length;
> > + int err;
> > + bool balloc = false;
> > +
> > + if (!may_alloc) {
> > + /* Completely beyond EOF. Treat as hole */
> > + if (i_size_read(inode) <= offset) {
> > + iomap->type = IOMAP_HOLE;
> > + iomap->addr = IOMAP_NULL_ADDR;
> > + iomap->offset = offset;
> > + iomap->length = length;
> > + return 0;
> > + }
> > +
> > + /* Clamp length if the requested range goes beyond i_size */
> > + if (offset + length > i_size_read(inode))
> > + length = round_up(i_size_read(inode),
> > + i_blocksize(inode)) - offset;
> > + }
> > +
> > + num_clusters = exfat_bytes_to_cluster_round_up(sbi,
> > + offset + length) - exfat_bytes_to_cluster(sbi, offset);
> > +
> > + mutex_lock(&sbi->s_lock);
> > + iomap->bdev = inode->i_sb->s_bdev;
> > + iomap->offset = offset;
> > +
> > + err = exfat_map_cluster(inode, exfat_bytes_to_cluster(sbi, offset),
> > + &cluster, &num_clusters, may_alloc, &balloc);
> > + if (err)
> > + goto out;
> > +
> > + cluster_offset = exfat_cluster_offset(sbi, offset);
> > + cluster_length = exfat_cluster_to_bytes(sbi, num_clusters);
> > +
> > + iomap->length = min_t(loff_t, length, cluster_length - cluster_offset);
> > + iomap->addr = exfat_cluster_to_phys(sbi, cluster) + cluster_offset;
> > + iomap->type = IOMAP_MAPPED;
> > + if (may_alloc) {
> > + if (balloc)
> > + iomap->flags = IOMAP_F_NEW;
> > + else if (iomap->offset + iomap->length >= ei->valid_size) {
> > + /*
> > + * This is a write that starts at or extends beyond
> > + * the current valid_size. The region between the old
> > + * valid_size and the end of this write needs to be
> > + * zeroed in the page cache to prevent stale data
> > + * exposure (see IOMAP_F_ZERO_TAIL handling in
> > + * __iomap_write_begin()).
> > + */
> > + iomap->flags = IOMAP_F_ZERO_TAIL;
> > + }
> > + } else {
> > + if (offset >= ei->valid_size)
> > + iomap->type = IOMAP_UNWRITTEN;
> > +
> > + if (iomap->type == IOMAP_MAPPED &&
> > + iomap->offset < ei->valid_size &&
> > + iomap->offset + iomap->length > ei->valid_size) {
> > + iomap->length = round_up(ei->valid_size,
> > + i_blocksize(inode)) -
> > + iomap->offset;
> > + }
>
> Hi, you can write it like this:
>
> if (offset >= ei->valid_size) {
> iomap->type = IOMAP_UNWRITTEN;
> } else if (offset + iomap->length > ei->valid_size) {
> iomap->length = round_up(ei->valid_size,
> i_blocksize(inode)) -
> iomap->offset;
> }
Okay, Will update it.
Thanks!