summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChi Zhiling <chizhiling@kylinos.cn>2026-03-03 11:14:09 +0800
committerNamjae Jeon <linkinjeon@kernel.org>2026-03-05 21:09:35 +0900
commitd1d75eaf01abceb3d5cb50253375b5f254b6be54 (patch)
tree3ce5db43ae4c06893a847e149059baba3e252e91
parent636bd62299aea24684086d126ea88b23a6466f8e (diff)
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 <chizhiling@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
-rw-r--r--fs/exfat/exfat_fs.h2
-rw-r--r--fs/exfat/fatent.c8
-rw-r--r--fs/exfat/inode.c5
-rw-r--r--fs/exfat/misc.c8
-rw-r--r--fs/exfat/namei.c3
5 files changed, 16 insertions, 10 deletions
diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
index 090f25d1a418..9fed9fb33cae 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 a973aa4de57b..f2e5d5dde393 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 d5f6dbab4720..beb9ea7cca9f 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 fa8459828046..6f11a96a4ffa 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 670116ae9ec8..ef2a3488c1b3 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;
}