From: OGAWA Hirofumi The fatfs was ignoreing the I/O error on two points. If I/O error happen while checking a free block entries, this checks the all entries, and reports an I/O error on each entry. This problem became cause of the disk full by syslogd. fs/fat/inode.c | 11 ++++++++--- fs/fat/misc.c | 22 +++++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff -puN fs/fat/inode.c~fatfs-log-storm-fix fs/fat/inode.c --- 25/fs/fat/inode.c~fatfs-log-storm-fix 2003-12-20 07:22:29.000000000 -0800 +++ 25-akpm/fs/fat/inode.c 2003-12-20 07:22:29.000000000 -0800 @@ -1047,7 +1047,7 @@ out_fail: int fat_statfs(struct super_block *sb, struct kstatfs *buf) { - int free, nr; + int free, nr, ret; if (MSDOS_SB(sb)->free_clusters != -1) free = MSDOS_SB(sb)->free_clusters; @@ -1057,9 +1057,14 @@ int fat_statfs(struct super_block *sb, s free = MSDOS_SB(sb)->free_clusters; else { free = 0; - for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++) - if (fat_access(sb, nr, -1) == FAT_ENT_FREE) + for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++) { + ret = fat_access(sb, nr, -1); + if (ret < 0) { + unlock_fat(sb); + return ret; + } else if (ret == FAT_ENT_FREE) free++; + } MSDOS_SB(sb)->free_clusters = free; } unlock_fat(sb); diff -puN fs/fat/misc.c~fatfs-log-storm-fix fs/fat/misc.c --- 25/fs/fat/misc.c~fatfs-log-storm-fix 2003-12-20 07:22:29.000000000 -0800 +++ 25-akpm/fs/fat/misc.c 2003-12-20 07:22:29.000000000 -0800 @@ -88,7 +88,7 @@ void fat_clusters_flush(struct super_blo int fat_add_cluster(struct inode *inode) { struct super_block *sb = inode->i_sb; - int count, limit, new_dclus, new_fclus, last; + int ret, count, limit, new_dclus, new_fclus, last; int cluster_bits = MSDOS_SB(sb)->cluster_bits; /* @@ -123,7 +123,12 @@ int fat_add_cluster(struct inode *inode) new_dclus = new_dclus % limit; if (new_dclus < 2) new_dclus = 2; - if (fat_access(sb, new_dclus, -1) == FAT_ENT_FREE) + + ret = fat_access(sb, new_dclus, -1); + if (ret < 0) { + unlock_fat(sb); + return ret; + } else if (ret == FAT_ENT_FREE) break; } if (count >= MSDOS_SB(sb)->clusters) { @@ -131,9 +136,14 @@ int fat_add_cluster(struct inode *inode) unlock_fat(sb); return -ENOSPC; } - MSDOS_SB(sb)->prev_free = new_dclus; - fat_access(sb, new_dclus, FAT_ENT_EOF); + ret = fat_access(sb, new_dclus, FAT_ENT_EOF); + if (ret < 0) { + unlock_fat(sb); + return ret; + } + + MSDOS_SB(sb)->prev_free = new_dclus; if (MSDOS_SB(sb)->free_clusters != -1) MSDOS_SB(sb)->free_clusters--; fat_clusters_flush(sb); @@ -142,7 +152,9 @@ int fat_add_cluster(struct inode *inode) /* add new one to the last of the cluster chain */ if (last) { - fat_access(sb, last, new_dclus); + ret = fat_access(sb, last, new_dclus); + if (ret < 0) + return ret; fat_cache_add(inode, new_fclus, new_dclus); } else { MSDOS_I(inode)->i_start = new_dclus; _