From 548b4535edc6a1e4ce4c56d8dba7435b879f8de9 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 29 Dec 2003 23:43:52 -0800 Subject: [PATCH] [PATCH] fatfs: fix printk storm during I/O errors From: OGAWA Hirofumi The fatfs was ignoring 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 --git a/fs/fat/inode.c b/fs/fat/inode.c index 11f64401f1bdc..378bfde188d0c 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -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, struct kstatfs *buf) 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 --git a/fs/fat/misc.c b/fs/fat/misc.c index b50f423466eb9..c3a7785d8381d 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -88,7 +88,7 @@ void fat_clusters_flush(struct super_block *sb) 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; -- 2.53.0