--- /dev/null
+From stable+bounces-278557-greg=kroah.com@vger.kernel.org Tue Jul 21 13:47:03 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jul 2026 07:46:52 -0400
+Subject: exfat: replace unsafe macros with static inline functions
+To: stable@vger.kernel.org
+Cc: Namjae Jeon <linkinjeon@kernel.org>, Christoph Hellwig <hch@lst.de>, "Darrick J. Wong" <djwong@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260721114656.3687966-1-sashal@kernel.org>
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit f07db38084dc45162d5fe2871ed72674ddc0f9ae ]
+
+The current exFAT driver relies on various macros for unit conversions
+between clusters, blocks, sectors, and directory entries. These macros
+are structurally unsafe as they lack type enforcement and are prone to
+potential integer overflows during bit-shift operations, especially
+on 64-bit architectures. Replace all arithmetic macros with static inline
+functions to provide strict type checking and explicit casting.
+
+Acked-by: Christoph Hellwig <hch@lst.de>
+Acked-by: "Darrick J. Wong" <djwong@kernel.org>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Stable-dep-of: 044472d5ee7d ("iomap: consolidate bio submission")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/exfat/balloc.c | 2
+ fs/exfat/dir.c | 48 ++++++++++----------
+ fs/exfat/exfat_fs.h | 122 +++++++++++++++++++++++++++++++++++++---------------
+ fs/exfat/fatent.c | 4 -
+ fs/exfat/file.c | 8 +--
+ fs/exfat/inode.c | 19 ++++----
+ fs/exfat/namei.c | 26 +++++------
+ fs/exfat/super.c | 4 -
+ 8 files changed, 147 insertions(+), 86 deletions(-)
+
+--- a/fs/exfat/balloc.c
++++ b/fs/exfat/balloc.c
+@@ -112,7 +112,7 @@ static int exfat_allocate_bitmap(struct
+ }
+
+ if (exfat_test_bitmap_range(sb, sbi->map_clu,
+- EXFAT_B_TO_CLU_ROUND_UP(map_size, sbi)) == false)
++ exfat_bytes_to_cluster_round_up(sbi, map_size)) == false)
+ goto err_out;
+
+ return 0;
+--- a/fs/exfat/dir.c
++++ b/fs/exfat/dir.c
+@@ -76,7 +76,7 @@ static int exfat_readdir(struct inode *i
+ 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 dentry = EXFAT_B_TO_DEN(*cpos) & 0xFFFFFFFF;
++ unsigned int dentry = exfat_bytes_to_dentries(*cpos) & 0xFFFFFFFF;
+ struct buffer_head *bh;
+
+ /* check if the given file ID is opened */
+@@ -84,13 +84,13 @@ static int exfat_readdir(struct inode *i
+ return -EPERM;
+
+ exfat_chain_set(&dir, ei->start_clu,
+- EXFAT_B_TO_CLU(i_size_read(inode), sbi), ei->flags);
++ exfat_bytes_to_cluster(sbi, i_size_read(inode)), ei->flags);
+
+ dentries_per_clu = sbi->dentries_per_clu;
+- max_dentries = (unsigned int)min_t(u64, MAX_EXFAT_DENTRIES,
+- (u64)EXFAT_CLU_TO_DEN(sbi->num_clusters, sbi));
++ max_dentries = min(MAX_EXFAT_DENTRIES,
++ exfat_cluster_to_dentries(sbi, sbi->num_clusters));
+
+- clu_offset = EXFAT_DEN_TO_CLU(dentry, sbi);
++ clu_offset = exfat_dentries_to_cluster(sbi, dentry);
+ exfat_chain_dup(&clu, &dir);
+
+ if (clu.flags == ALLOC_FAT_CHAIN) {
+@@ -147,10 +147,10 @@ static int exfat_readdir(struct inode *i
+ dir_entry->dir = clu;
+ brelse(bh);
+
+- ei->hint_bmap.off = EXFAT_DEN_TO_CLU(dentry, sbi);
++ ei->hint_bmap.off = exfat_dentries_to_cluster(sbi, dentry);
+ ei->hint_bmap.clu = clu.dir;
+
+- *cpos = EXFAT_DEN_TO_B(dentry + 1 + num_ext);
++ *cpos = exfat_dentries_to_bytes(dentry + 1 + num_ext);
+ return 0;
+ }
+
+@@ -160,7 +160,7 @@ static int exfat_readdir(struct inode *i
+
+ out:
+ dir_entry->namebuf.lfn[0] = '\0';
+- *cpos = EXFAT_DEN_TO_B(dentry);
++ *cpos = exfat_dentries_to_bytes(dentry);
+ return 0;
+ }
+
+@@ -465,7 +465,7 @@ static void exfat_free_benign_secondary_
+ return;
+
+ exfat_chain_set(&dir, start_clu,
+- EXFAT_B_TO_CLU_ROUND_UP(size, EXFAT_SB(sb)),
++ exfat_bytes_to_cluster_round_up(EXFAT_SB(sb), size),
+ flags);
+ exfat_free_cluster(inode, &dir);
+ }
+@@ -594,10 +594,11 @@ static int exfat_find_location(struct su
+ unsigned int off, clu = 0;
+ struct exfat_sb_info *sbi = EXFAT_SB(sb);
+
+- off = EXFAT_DEN_TO_B(entry);
++ off = exfat_dentries_to_bytes(entry);
+
+ clu = p_dir->dir;
+- ret = exfat_cluster_walk(sb, &clu, EXFAT_B_TO_CLU(off, sbi), p_dir->flags);
++ ret = exfat_cluster_walk(sb, &clu, exfat_bytes_to_cluster(sbi, off),
++ p_dir->flags);
+ if (ret)
+ return ret;
+
+@@ -605,7 +606,7 @@ static int exfat_find_location(struct su
+ exfat_fs_error(sb,
+ "unexpected early break in cluster chain (clu : %u, len : %d)",
+ p_dir->dir,
+- EXFAT_B_TO_CLU(off, sbi));
++ exfat_bytes_to_cluster(sbi, off));
+ return -EIO;
+ }
+
+@@ -615,13 +616,13 @@ static int exfat_find_location(struct su
+ }
+
+ /* byte offset in cluster */
+- off = EXFAT_CLU_OFFSET(off, sbi);
++ off = exfat_cluster_offset(sbi, off);
+
+ /* byte offset in sector */
+- *offset = EXFAT_BLK_OFFSET(off, sb);
++ *offset = exfat_block_offset(sb, off);
+
+ /* sector offset in cluster */
+- *sector = EXFAT_B_TO_BLK(off, sb);
++ *sector = exfat_bytes_to_block(sb, off);
+ *sector += exfat_cluster_to_sector(sbi, clu);
+ return 0;
+ }
+@@ -631,7 +632,7 @@ struct exfat_dentry *exfat_get_dentry(st
+ {
+ struct exfat_sb_info *sbi = EXFAT_SB(sb);
+ unsigned int sect_per_clus = sbi->sect_per_clus;
+- unsigned int dentries_per_page = EXFAT_B_TO_DEN(PAGE_SIZE);
++ unsigned int dentries_per_page = exfat_bytes_to_dentries(PAGE_SIZE);
+ int off;
+ sector_t sec;
+
+@@ -710,8 +711,8 @@ struct exfat_dentry *exfat_get_dentry_ca
+ struct exfat_entry_set_cache *es, int num)
+ {
+ int off = es->start_off + num * DENTRY_SIZE;
+- struct buffer_head *bh = es->bh[EXFAT_B_TO_BLK(off, es->sb)];
+- char *p = bh->b_data + EXFAT_BLK_OFFSET(off, es->sb);
++ struct buffer_head *bh = es->bh[exfat_bytes_to_block(es->sb, off)];
++ char *p = bh->b_data + exfat_block_offset(es->sb, off);
+
+ return (struct exfat_dentry *)p;
+ }
+@@ -779,7 +780,7 @@ static int __exfat_get_dentry_set(struct
+
+ es->num_entries = num_entries;
+
+- num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb);
++ num_bh = exfat_bytes_to_block_round_up(sb, off + num_entries * DENTRY_SIZE);
+ if (num_bh > ARRAY_SIZE(es->__bh)) {
+ es->bh = kmalloc_objs(*es->bh, num_bh, GFP_NOFS);
+ if (!es->bh) {
+@@ -868,7 +869,7 @@ static int exfat_validate_empty_dentry_s
+
+ err_used_follow_unused:
+ off = es->start_off + (i << DENTRY_SIZE_BITS);
+- bh = es->bh[EXFAT_B_TO_BLK(off, es->sb)];
++ bh = es->bh[exfat_bytes_to_block(es->sb, off)];
+
+ exfat_fs_error(es->sb,
+ "in sector %lld, dentry %d should be unused, but 0x%x",
+@@ -877,7 +878,8 @@ err_used_follow_unused:
+ return -EIO;
+
+ count_skip_entries:
+- es->num_entries = EXFAT_B_TO_DEN(EXFAT_BLK_TO_B(es->num_bh, es->sb) - es->start_off);
++ es->num_entries =
++ exfat_bytes_to_dentries(exfat_block_to_bytes(es->sb, es->num_bh) - es->start_off);
+ for (; i < es->num_entries; i++) {
+ ep = exfat_get_dentry_cached(es, i);
+ if (IS_EXFAT_DELETED(ep->type))
+@@ -930,7 +932,7 @@ static inline void exfat_set_empty_hint(
+ {
+ if (ei->hint_femp.eidx == EXFAT_HINT_NONE ||
+ ei->hint_femp.eidx > dentry) {
+- int total_entries = EXFAT_B_TO_DEN(i_size_read(&ei->vfs_inode));
++ int total_entries = exfat_bytes_to_dentries(i_size_read(&ei->vfs_inode));
+
+ if (candi_empty->count == 0) {
+ candi_empty->cur = *clu;
+@@ -1258,7 +1260,7 @@ static int exfat_get_volume_label_dentry
+ es->bh = es->__bh;
+ es->bh[0] = bh;
+ es->num_bh = 1;
+- es->start_off = EXFAT_DEN_TO_B(i) % sb->s_blocksize;
++ es->start_off = exfat_dentries_to_bytes(i) % sb->s_blocksize;
+
+ return 0;
+ }
+--- a/fs/exfat/exfat_fs.h
++++ b/fs/exfat/exfat_fs.h
+@@ -85,38 +85,6 @@ enum {
+ << (PAGE_SHIFT - (sb)->s_blocksize_bits))
+
+ /*
+- * helpers for cluster size to byte conversion.
+- */
+-#define EXFAT_CLU_TO_B(b, sbi) ((b) << (sbi)->cluster_size_bits)
+-#define EXFAT_B_TO_CLU(b, sbi) ((b) >> (sbi)->cluster_size_bits)
+-#define EXFAT_B_TO_CLU_ROUND_UP(b, sbi) \
+- (((b - 1) >> (sbi)->cluster_size_bits) + 1)
+-#define EXFAT_CLU_OFFSET(off, sbi) ((off) & ((sbi)->cluster_size - 1))
+-
+-/*
+- * helpers for block size to byte conversion.
+- */
+-#define EXFAT_BLK_TO_B(b, sb) ((b) << (sb)->s_blocksize_bits)
+-#define EXFAT_B_TO_BLK(b, sb) ((b) >> (sb)->s_blocksize_bits)
+-#define EXFAT_B_TO_BLK_ROUND_UP(b, sb) \
+- (((b - 1) >> (sb)->s_blocksize_bits) + 1)
+-#define EXFAT_BLK_OFFSET(off, sb) ((off) & ((sb)->s_blocksize - 1))
+-
+-/*
+- * helpers for block size to dentry size conversion.
+- */
+-#define EXFAT_B_TO_DEN(b) ((b) >> DENTRY_SIZE_BITS)
+-#define EXFAT_DEN_TO_B(b) ((b) << DENTRY_SIZE_BITS)
+-
+-/*
+- * helpers for cluster size to dentry size conversion.
+- */
+-#define EXFAT_CLU_TO_DEN(clu, sbi) \
+- ((clu) << ((sbi)->cluster_size_bits - DENTRY_SIZE_BITS))
+-#define EXFAT_DEN_TO_CLU(dentry, sbi) \
+- ((dentry) >> ((sbi)->cluster_size_bits - DENTRY_SIZE_BITS))
+-
+-/*
+ * helpers for fat entry.
+ */
+ #define FAT_ENT_SIZE (4)
+@@ -149,7 +117,7 @@ enum {
+ * The 608 bytes are in 3 sectors at most (even 512 Byte sector).
+ */
+ #define DIR_CACHE_SIZE \
+- (DIV_ROUND_UP(EXFAT_DEN_TO_B(ES_MAX_ENTRY_NUM), SECTOR_SIZE) + 1)
++ (DIV_ROUND_UP(ES_MAX_ENTRY_NUM << DENTRY_SIZE_BITS, SECTOR_SIZE) + 1)
+
+ /* Superblock flags */
+ #define EXFAT_FLAGS_SHUTDOWN 1
+@@ -432,6 +400,94 @@ static inline loff_t exfat_ondisk_size(c
+ return ((loff_t)inode->i_blocks) << 9;
+ }
+
++/*
++ * helpers for cluster size to byte conversion.
++ */
++static inline loff_t exfat_cluster_to_bytes(struct exfat_sb_info *sbi,
++ u32 nr_clusters)
++{
++ return (loff_t)nr_clusters << sbi->cluster_size_bits;
++}
++
++static inline blkcnt_t exfat_cluster_to_sectors(struct exfat_sb_info *sbi,
++ u32 nr_clusters)
++{
++ return (blkcnt_t)nr_clusters << (sbi->cluster_size_bits - 9);
++}
++
++static inline u32 exfat_bytes_to_cluster(struct exfat_sb_info *sbi, loff_t size)
++{
++ return (u32)(size >> sbi->cluster_size_bits);
++}
++
++static inline u32 exfat_bytes_to_cluster_round_up(struct exfat_sb_info *sbi,
++ loff_t size)
++{
++ if (size <= 0)
++ return 0;
++ return (u32)((size - 1) >> sbi->cluster_size_bits) + 1;
++}
++
++static inline u32 exfat_cluster_offset(struct exfat_sb_info *sbi, loff_t off)
++{
++ return off & (sbi->cluster_size - 1);
++}
++
++/*
++ * helpers for block size to byte conversion.
++ */
++static inline loff_t exfat_block_to_bytes(struct super_block *sb,
++ sector_t block)
++{
++ return (loff_t)block << sb->s_blocksize_bits;
++}
++
++static inline sector_t exfat_bytes_to_block(struct super_block *sb, loff_t size)
++{
++ return (sector_t)(size >> sb->s_blocksize_bits);
++}
++
++static inline sector_t exfat_bytes_to_block_round_up(struct super_block *sb,
++ loff_t size)
++{
++ if (size <= 0)
++ return 0;
++ return (sector_t)(((size - 1) >> sb->s_blocksize_bits) + 1);
++}
++
++static inline u32 exfat_block_offset(struct super_block *sb, loff_t off)
++{
++ return (u32)(off & (sb->s_blocksize - 1));
++}
++
++/*
++ * helpers for block size to dentry size conversion.
++ */
++static inline u32 exfat_bytes_to_dentries(loff_t b)
++{
++ return (u32)(b >> DENTRY_SIZE_BITS);
++}
++
++static inline u32 exfat_dentries_to_bytes(u32 dentry)
++{
++ return dentry << DENTRY_SIZE_BITS;
++}
++
++/*
++ * helpers for cluster size to dentry size conversion.
++ */
++static inline u32 exfat_cluster_to_dentries(struct exfat_sb_info *sbi,
++ u32 nr_clusters)
++{
++ return nr_clusters << (sbi->cluster_size_bits - DENTRY_SIZE_BITS);
++}
++
++static inline u32 exfat_dentries_to_cluster(struct exfat_sb_info *sbi,
++ u32 dentry)
++{
++ return dentry >> (sbi->cluster_size_bits - DENTRY_SIZE_BITS);
++}
++
+ /* super.c */
+ int exfat_set_volume_dirty(struct super_block *sb);
+ int exfat_clear_volume_dirty(struct super_block *sb);
+--- a/fs/exfat/fatent.c
++++ b/fs/exfat/fatent.c
+@@ -412,8 +412,8 @@ int exfat_zeroed_cluster(struct inode *d
+
+ if (IS_DIRSYNC(dir))
+ return sync_blockdev_range(sb->s_bdev,
+- EXFAT_BLK_TO_B(blknr, sb),
+- EXFAT_BLK_TO_B(last_blknr, sb) - 1);
++ exfat_block_to_bytes(sb, blknr),
++ exfat_block_to_bytes(sb, last_blknr) - 1);
+
+ return 0;
+ }
+--- a/fs/exfat/file.c
++++ b/fs/exfat/file.c
+@@ -33,9 +33,9 @@ static int exfat_cont_expand(struct inod
+ if (ret)
+ return ret;
+
+- num_clusters = EXFAT_B_TO_CLU(exfat_ondisk_size(inode), sbi);
++ num_clusters = exfat_bytes_to_cluster(sbi, exfat_ondisk_size(inode));
+ /* integer overflow is already checked in inode_newsize_ok(). */
+- new_num_clusters = EXFAT_B_TO_CLU_ROUND_UP(size, sbi);
++ new_num_clusters = exfat_bytes_to_cluster_round_up(sbi, size);
+
+ if (new_num_clusters == num_clusters)
+ goto out;
+@@ -200,8 +200,8 @@ int __exfat_truncate(struct inode *inode
+
+ exfat_set_volume_dirty(sb);
+
+- num_clusters_new = EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi);
+- num_clusters_phys = EXFAT_B_TO_CLU(exfat_ondisk_size(inode), sbi);
++ num_clusters_new = exfat_bytes_to_cluster_round_up(sbi, i_size_read(inode));
++ num_clusters_phys = exfat_bytes_to_cluster(sbi, exfat_ondisk_size(inode));
+
+ exfat_chain_set(&clu, ei->start_clu, num_clusters_phys, ei->flags);
+
+--- a/fs/exfat/inode.c
++++ b/fs/exfat/inode.c
+@@ -135,7 +135,7 @@ static int exfat_map_cluster(struct inod
+ unsigned int local_clu_offset = clu_offset;
+ unsigned int num_to_be_allocated = 0, num_clusters;
+
+- num_clusters = EXFAT_B_TO_CLU(exfat_ondisk_size(inode), sbi);
++ num_clusters = exfat_bytes_to_cluster(sbi, exfat_ondisk_size(inode));
+
+ if (clu_offset >= num_clusters)
+ num_to_be_allocated = clu_offset - num_clusters + 1;
+@@ -216,7 +216,8 @@ static int exfat_map_cluster(struct inod
+
+ *clu = new_clu.dir;
+
+- inode->i_blocks += EXFAT_CLU_TO_B(num_to_be_allocated, sbi) >> 9;
++ inode->i_blocks +=
++ exfat_cluster_to_sectors(sbi, num_to_be_allocated);
+
+ /*
+ * Move *clu pointer along FAT chains (hole care) because the
+@@ -254,12 +255,12 @@ static int exfat_get_block(struct inode
+
+ mutex_lock(&sbi->s_lock);
+ i_size = i_size_read(inode);
+- last_block = EXFAT_B_TO_BLK_ROUND_UP(i_size, sb);
++ last_block = exfat_bytes_to_block_round_up(sb, i_size);
+ if (iblock >= last_block && !create)
+ goto done;
+
+ /* Is this block already allocated? */
+- count = EXFAT_B_TO_CLU_ROUND_UP(bh_result->b_size, sbi);
++ count = exfat_bytes_to_cluster_round_up(sbi, bh_result->b_size);
+ err = exfat_map_cluster(inode, iblock >> sbi->sect_per_clus_bits,
+ &cluster, &count, create);
+ if (err) {
+@@ -296,9 +297,9 @@ static int exfat_get_block(struct inode
+ * care the last nested block if valid_size is not equal to i_size.
+ */
+ if (i_size == ei->valid_size || create || !bh_result->b_folio)
+- valid_blks = EXFAT_B_TO_BLK_ROUND_UP(ei->valid_size, sb);
++ valid_blks = exfat_bytes_to_block_round_up(sb, ei->valid_size);
+ else
+- valid_blks = EXFAT_B_TO_BLK(ei->valid_size, sb);
++ valid_blks = exfat_bytes_to_block(sb, ei->valid_size);
+
+ /* The range has been fully written, map it */
+ if (iblock + max_blocks < valid_blks)
+@@ -313,7 +314,7 @@ static int exfat_get_block(struct inode
+ /* The area has not been written, map and mark as new for create case */
+ if (create) {
+ set_buffer_new(bh_result);
+- ei->valid_size = EXFAT_BLK_TO_B(iblock + max_blocks, sb);
++ ei->valid_size = exfat_block_to_bytes(sb, iblock + max_blocks);
+ mark_inode_dirty(inode);
+ goto done;
+ }
+@@ -343,7 +344,7 @@ static int exfat_get_block(struct inode
+ goto done;
+ }
+
+- pos = EXFAT_BLK_TO_B(iblock, sb);
++ pos = exfat_block_to_bytes(sb, iblock);
+ size = ei->valid_size - pos;
+ addr = folio_address(bh_result->b_folio) +
+ offset_in_folio(bh_result->b_folio, pos);
+@@ -374,7 +375,7 @@ static int exfat_get_block(struct inode
+ */
+ clear_buffer_mapped(bh_result);
+ done:
+- bh_result->b_size = EXFAT_BLK_TO_B(max_blocks, sb);
++ bh_result->b_size = exfat_block_to_bytes(sb, max_blocks);
+ if (err < 0)
+ clear_buffer_mapped(bh_result);
+ unlock_ret:
+--- a/fs/exfat/namei.c
++++ b/fs/exfat/namei.c
+@@ -208,7 +208,7 @@ static int exfat_search_empty_slot(struc
+ int dentries_per_clu;
+ struct exfat_chain clu;
+ struct exfat_sb_info *sbi = EXFAT_SB(sb);
+- int total_entries = EXFAT_CLU_TO_DEN(p_dir->size, sbi);
++ unsigned int total_entries = exfat_cluster_to_dentries(sbi, p_dir->size);
+
+ dentries_per_clu = sbi->dentries_per_clu;
+
+@@ -266,7 +266,7 @@ static int exfat_search_empty_slot(struc
+
+ static int exfat_check_max_dentries(struct inode *inode)
+ {
+- if (EXFAT_B_TO_DEN(i_size_read(inode)) >= MAX_EXFAT_DENTRIES) {
++ if (exfat_bytes_to_dentries(i_size_read(inode)) >= MAX_EXFAT_DENTRIES) {
+ /*
+ * exFAT spec allows a dir to grow up to 8388608(256MB)
+ * dentries
+@@ -314,7 +314,8 @@ int exfat_find_empty_entry(struct inode
+ }
+
+ exfat_chain_set(p_dir, ei->start_clu,
+- EXFAT_B_TO_CLU(i_size_read(inode), sbi), ei->flags);
++ exfat_bytes_to_cluster(sbi, i_size_read(inode)),
++ ei->flags);
+
+ while ((dentry = exfat_search_empty_slot(sb, &hint_femp, p_dir,
+ num_entries, es)) < 0) {
+@@ -375,7 +376,7 @@ int exfat_find_empty_entry(struct inode
+
+ hint_femp.cur.size++;
+ p_dir->size++;
+- size = EXFAT_CLU_TO_B(p_dir->size, sbi);
++ size = exfat_cluster_to_bytes(sbi, p_dir->size);
+
+ /* directory inode should be updated in here */
+ i_size_write(inode, size);
+@@ -604,7 +605,7 @@ static int exfat_find(struct inode *dir,
+ return ret;
+
+ exfat_chain_set(&cdir, ei->start_clu,
+- EXFAT_B_TO_CLU(i_size_read(dir), sbi), ei->flags);
++ exfat_bytes_to_cluster(sbi, i_size_read(dir)), ei->flags);
+
+ /* check the validation of hint_stat and initialize it if required */
+ if (ei->version != (inode_peek_iversion_raw(dir) & 0xffffffff)) {
+@@ -681,7 +682,7 @@ static int exfat_find(struct inode *dir,
+ return -EIO;
+ }
+
+- if (unlikely(EXFAT_B_TO_CLU_ROUND_UP(info->size, sbi) > sbi->used_clusters)) {
++ if (unlikely(exfat_bytes_to_cluster_round_up(sbi, info->size) > sbi->used_clusters)) {
+ exfat_fs_error(sb, "data size is invalid(%lld)", info->size);
+ return -EIO;
+ }
+@@ -695,7 +696,8 @@ static int exfat_find(struct inode *dir,
+
+ if (info->type == TYPE_DIR) {
+ exfat_chain_set(&cdir, info->start_clu,
+- EXFAT_B_TO_CLU(info->size, sbi), info->flags);
++ exfat_bytes_to_cluster(sbi, info->size),
++ info->flags);
+ count = exfat_count_dir_entries(sb, &cdir);
+ if (count < 0)
+ return -EIO;
+@@ -951,7 +953,7 @@ static int exfat_rmdir(struct inode *dir
+ }
+
+ exfat_chain_set(&clu_to_free, ei->start_clu,
+- EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi), ei->flags);
++ exfat_bytes_to_cluster_round_up(sbi, i_size_read(inode)), ei->flags);
+
+ err = exfat_check_dir_empty(sb, &clu_to_free);
+ if (err) {
+@@ -1207,8 +1209,8 @@ static int __exfat_rename(struct inode *
+
+ new_clu.dir = new_ei->start_clu;
+ new_clu.size =
+- EXFAT_B_TO_CLU_ROUND_UP(i_size_read(new_inode),
+- sbi);
++ exfat_bytes_to_cluster_round_up(sbi,
++ i_size_read(new_inode));
+ new_clu.flags = new_ei->flags;
+
+ ret = exfat_check_dir_empty(sb, &new_clu);
+@@ -1252,8 +1254,8 @@ static int __exfat_rename(struct inode *
+ struct exfat_chain new_clu_to_free;
+
+ exfat_chain_set(&new_clu_to_free, new_ei->start_clu,
+- EXFAT_B_TO_CLU_ROUND_UP(i_size_read(new_inode),
+- sbi), new_ei->flags);
++ exfat_bytes_to_cluster_round_up(sbi, i_size_read(new_inode)),
++ new_ei->flags);
+
+ if (exfat_free_cluster(new_inode, &new_clu_to_free)) {
+ /* just set I/O error only */
+--- a/fs/exfat/super.c
++++ b/fs/exfat/super.c
+@@ -369,7 +369,7 @@ static int exfat_read_root(struct inode
+ ei->hint_stat.clu = sbi->root_dir;
+ ei->hint_femp.eidx = EXFAT_HINT_NONE;
+
+- i_size_write(inode, EXFAT_CLU_TO_B(root_clu->size, sbi));
++ i_size_write(inode, exfat_cluster_to_bytes(sbi, root_clu->size));
+
+ num_subdirs = exfat_count_dir_entries(sb, root_clu);
+ if (num_subdirs < 0)
+@@ -538,7 +538,7 @@ static int exfat_read_boot_sector(struct
+ * machines.
+ */
+ sb->s_maxbytes = min(MAX_LFS_FILESIZE,
+- EXFAT_CLU_TO_B((loff_t)EXFAT_MAX_NUM_CLUSTER, sbi));
++ exfat_cluster_to_bytes(sbi, (loff_t)EXFAT_MAX_NUM_CLUSTER));
+
+ /* check logical sector size */
+ if (exfat_calibrate_blocksize(sb, 1 << p_boot->sect_size_bits))
--- /dev/null
+From stable+bounces-278561-greg=kroah.com@vger.kernel.org Tue Jul 21 13:47:12 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jul 2026 07:46:56 -0400
+Subject: iomap: consolidate bio submission
+To: stable@vger.kernel.org
+Cc: Christoph Hellwig <hch@lst.de>, Namjae Jeon <linkinjeon@kernel.org>, "Darrick J. Wong" <djwong@kernel.org>, Joanne Koong <joannelkoong@gmail.com>, "Christian Brauner (Amutable)" <brauner@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260721114656.3687966-5-sashal@kernel.org>
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 044472d5ee7d71f918fa3f61bd65e4933a0c006e ]
+
+Add a iomap_bio_submit_read_endio helper factored out of
+iomap_bio_submit_read to that all ->submit_read implementations for
+iomap_read_ops that use iomap_bio_read_folio_range can shared the
+logic.
+
+Right now that logic is mostly trivial, but already has a bug for XFS
+because the XFS version is too trivial: file system integrity validation
+needs a workqueue context and thus can't happen from the default iomap
+bi_end_io I/O handler. Unfortunately the iomap refactoring just before
+fs integrity landed moved code around here and the call go misplaced,
+meaning it never got called. The PI information still is verified by
+the block layer, but the offloading is less efficient (and the future
+userspace interface can't get at it).
+
+Fixes: 0b10a370529c ("iomap: support T10 protection information")
+Cc: stable@vger.kernel.org # v7.1
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://patch.msgid.link/20260629121750.3392300-2-hch@lst.de
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
+Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/iomap/bio.c | 13 ++++++++++---
+ fs/ntfs/aops.c | 6 ++----
+ fs/ntfs3/inode.c | 5 +----
+ fs/xfs/xfs_aops.c | 3 +--
+ include/linux/iomap.h | 2 ++
+ 5 files changed, 16 insertions(+), 13 deletions(-)
+
+--- a/fs/iomap/bio.c
++++ b/fs/iomap/bio.c
+@@ -78,15 +78,23 @@ u32 iomap_finish_ioend_buffered_read(str
+ return __iomap_read_end_io(&ioend->io_bio, ioend->io_error);
+ }
+
+-static void iomap_bio_submit_read(const struct iomap_iter *iter,
+- struct iomap_read_folio_ctx *ctx)
++void iomap_bio_submit_read_endio(const struct iomap_iter *iter,
++ struct iomap_read_folio_ctx *ctx, bio_end_io_t end_io)
+ {
+ struct bio *bio = ctx->read_ctx;
+
++ bio->bi_end_io = end_io;
+ if (iter->iomap.flags & IOMAP_F_INTEGRITY)
+ fs_bio_integrity_alloc(bio);
+ submit_bio(bio);
+ }
++EXPORT_SYMBOL_GPL(iomap_bio_submit_read_endio);
++
++static void iomap_bio_submit_read(const struct iomap_iter *iter,
++ struct iomap_read_folio_ctx *ctx)
++{
++ return iomap_bio_submit_read_endio(iter, ctx, iomap_read_end_io);
++}
+
+ static struct bio_set *iomap_read_bio_set(struct iomap_read_folio_ctx *ctx)
+ {
+@@ -127,7 +135,6 @@ static void iomap_read_alloc_bio(const s
+ if (ctx->rac)
+ bio->bi_opf |= REQ_RAHEAD;
+ bio->bi_iter.bi_sector = iomap_sector(iomap, iter->pos);
+- bio->bi_end_io = iomap_read_end_io;
+ bio_add_folio_nofail(bio, folio, plen,
+ offset_in_folio(folio, iter->pos));
+ ctx->read_ctx = bio;
+--- a/fs/ntfs/aops.c
++++ b/fs/ntfs/aops.c
+@@ -38,11 +38,9 @@ static void ntfs_iomap_read_end_io(struc
+ }
+
+ static void ntfs_iomap_bio_submit_read(const struct iomap_iter *iter,
+- struct iomap_read_folio_ctx *ctx)
++ struct iomap_read_folio_ctx *ctx)
+ {
+- struct bio *bio = ctx->read_ctx;
+- bio->bi_end_io = ntfs_iomap_read_end_io;
+- submit_bio(bio);
++ iomap_bio_submit_read_endio(iter, ctx, ntfs_iomap_read_end_io);
+ }
+
+ static const struct iomap_read_ops ntfs_iomap_bio_read_ops = {
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -609,10 +609,7 @@ static void ntfs_iomap_read_end_io(struc
+ static void ntfs_iomap_bio_submit_read(const struct iomap_iter *iter,
+ struct iomap_read_folio_ctx *ctx)
+ {
+- struct bio *bio = ctx->read_ctx;
+-
+- bio->bi_end_io = ntfs_iomap_read_end_io;
+- submit_bio(bio);
++ iomap_bio_submit_read_endio(iter, ctx, ntfs_iomap_read_end_io);
+ }
+
+ static const struct iomap_read_ops ntfs_iomap_bio_read_ops = {
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -753,8 +753,7 @@ xfs_bio_submit_read(
+
+ /* defer read completions to the ioend workqueue */
+ iomap_init_ioend(iter->inode, bio, ctx->read_ctx_file_offset, 0);
+- bio->bi_end_io = xfs_end_bio;
+- submit_bio(bio);
++ iomap_bio_submit_read_endio(iter, ctx, xfs_end_bio);
+ }
+
+ static const struct iomap_read_ops xfs_iomap_read_ops = {
+--- a/include/linux/iomap.h
++++ b/include/linux/iomap.h
+@@ -615,6 +615,8 @@ extern struct bio_set iomap_ioend_bioset
+ #ifdef CONFIG_BLOCK
+ int iomap_bio_read_folio_range(const struct iomap_iter *iter,
+ struct iomap_read_folio_ctx *ctx, size_t plen);
++void iomap_bio_submit_read_endio(const struct iomap_iter *iter,
++ struct iomap_read_folio_ctx *ctx, bio_end_io_t end_io);
+
+ extern const struct iomap_read_ops iomap_bio_read_ops;
+