]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
exfat: fix error handling for FAT table operations
authorChi Zhiling <chizhiling@kylinos.cn>
Tue, 3 Mar 2026 03:14:09 +0000 (11:14 +0800)
committerNamjae Jeon <linkinjeon@kernel.org>
Thu, 5 Mar 2026 12:09:35 +0000 (21:09 +0900)
Fix three error handling issues in FAT table operations:

1. Fix exfat_update_bh() to properly return errors from sync_dirty_buffer
2. Fix exfat_end_bh() to properly return errors from exfat_update_bh()
   and exfat_mirror_bh()
3. Fix ignored return values from exfat_chain_cont_cluster() in inode.c
   and namei.c

These fixes ensure that FAT table write errors are properly propagated
to the caller instead of being silently ignored.

Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
fs/exfat/exfat_fs.h
fs/exfat/fatent.c
fs/exfat/inode.c
fs/exfat/misc.c
fs/exfat/namei.c

index 090f25d1a418f68656ab365308f1f9a507db271f..9fed9fb33caecb2656e1fa451b08fd32e619d5e6 100644 (file)
@@ -584,7 +584,7 @@ void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
                u8 *tz, __le16 *time, __le16 *date, u8 *time_cs);
 u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type);
 u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type);
-void exfat_update_bh(struct buffer_head *bh, int sync);
+int exfat_update_bh(struct buffer_head *bh, int sync);
 int exfat_update_bhs(struct buffer_head **bhs, int nr_bhs, int sync);
 void exfat_chain_set(struct exfat_chain *ec, unsigned int dir,
                unsigned int size, unsigned char flags);
index a973aa4de57b285b96b142a40ffd75418f6797bf..f2e5d5dde393662c4b0befaa9ad25cb48bc2bd70 100644 (file)
@@ -25,7 +25,7 @@ static int exfat_mirror_bh(struct super_block *sb, struct buffer_head *bh)
                if (!c_bh)
                        return -ENOMEM;
                memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize);
-               exfat_update_bh(c_bh, sb->s_flags & SB_SYNCHRONOUS);
+               err = exfat_update_bh(c_bh, sb->s_flags & SB_SYNCHRONOUS);
                brelse(c_bh);
        }
 
@@ -36,10 +36,10 @@ static int exfat_end_bh(struct super_block *sb, struct buffer_head *bh)
 {
        int err;
 
-       exfat_update_bh(bh, sb->s_flags & SB_SYNCHRONOUS);
-       err = exfat_mirror_bh(sb, bh);
+       err = exfat_update_bh(bh, sb->s_flags & SB_SYNCHRONOUS);
+       if (!err)
+               err = exfat_mirror_bh(sb, bh);
        brelse(bh);
-
        return err;
 }
 
index d5f6dbab472094d9dfc23f704a96fa345123b0b9..beb9ea7cca9f9df4854ed59a770565194a62e985 100644 (file)
@@ -204,8 +204,9 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
                                 * so fat-chain should be synced with
                                 * alloc-bitmap
                                 */
-                               exfat_chain_cont_cluster(sb, ei->start_clu,
-                                       num_clusters);
+                               if (exfat_chain_cont_cluster(sb, ei->start_clu,
+                                               num_clusters))
+                                       return -EIO;
                                ei->flags = ALLOC_FAT_CHAIN;
                        }
                        if (new_clu.flags == ALLOC_FAT_CHAIN)
index fa84598280461eaac07fb2f6bbe1f54ed192c5e5..6f11a96a4ffa84e41e4b4c2a841631facf06fe8f 100644 (file)
@@ -161,13 +161,17 @@ u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type)
        return chksum;
 }
 
-void exfat_update_bh(struct buffer_head *bh, int sync)
+int exfat_update_bh(struct buffer_head *bh, int sync)
 {
+       int err = 0;
+
        set_buffer_uptodate(bh);
        mark_buffer_dirty(bh);
 
        if (sync)
-               sync_dirty_buffer(bh);
+               err = sync_dirty_buffer(bh);
+
+       return err;
 }
 
 int exfat_update_bhs(struct buffer_head **bhs, int nr_bhs, int sync)
index 670116ae9ec857ba5ae824ec1e64626bbeaa17db..ef2a3488c1b370cba9675dbb29c2a691a6d306c8 100644 (file)
@@ -365,7 +365,8 @@ int exfat_find_empty_entry(struct inode *inode,
                        /* no-fat-chain bit is disabled,
                         * so fat-chain should be synced with alloc-bitmap
                         */
-                       exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size);
+                       if (exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size))
+                               return -EIO;
                        p_dir->flags = ALLOC_FAT_CHAIN;
                        hint_femp.cur.flags = ALLOC_FAT_CHAIN;
                }