From: Chi Zhiling Date: Tue, 3 Mar 2026 03:14:09 +0000 (+0800) Subject: exfat: fix error handling for FAT table operations X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d1d75eaf01abceb3d5cb50253375b5f254b6be54;p=thirdparty%2Flinux.git exfat: fix error handling for FAT table operations 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 Signed-off-by: Namjae Jeon --- diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 090f25d1a418f..9fed9fb33caec 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -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); diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c index a973aa4de57b2..f2e5d5dde3936 100644 --- a/fs/exfat/fatent.c +++ b/fs/exfat/fatent.c @@ -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; } diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index d5f6dbab47209..beb9ea7cca9f9 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -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) diff --git a/fs/exfat/misc.c b/fs/exfat/misc.c index fa84598280461..6f11a96a4ffa8 100644 --- a/fs/exfat/misc.c +++ b/fs/exfat/misc.c @@ -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) diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 670116ae9ec85..ef2a3488c1b37 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -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; }