Commit 548b4535 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] fatfs: fix printk storm during I/O errors

From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

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.
parent 992d50d5
...@@ -1047,7 +1047,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, ...@@ -1047,7 +1047,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
int fat_statfs(struct super_block *sb, struct kstatfs *buf) int fat_statfs(struct super_block *sb, struct kstatfs *buf)
{ {
int free, nr; int free, nr, ret;
if (MSDOS_SB(sb)->free_clusters != -1) if (MSDOS_SB(sb)->free_clusters != -1)
free = MSDOS_SB(sb)->free_clusters; free = MSDOS_SB(sb)->free_clusters;
...@@ -1057,9 +1057,14 @@ int fat_statfs(struct super_block *sb, struct kstatfs *buf) ...@@ -1057,9 +1057,14 @@ int fat_statfs(struct super_block *sb, struct kstatfs *buf)
free = MSDOS_SB(sb)->free_clusters; free = MSDOS_SB(sb)->free_clusters;
else { else {
free = 0; free = 0;
for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++) for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++) {
if (fat_access(sb, nr, -1) == FAT_ENT_FREE) ret = fat_access(sb, nr, -1);
if (ret < 0) {
unlock_fat(sb);
return ret;
} else if (ret == FAT_ENT_FREE)
free++; free++;
}
MSDOS_SB(sb)->free_clusters = free; MSDOS_SB(sb)->free_clusters = free;
} }
unlock_fat(sb); unlock_fat(sb);
......
...@@ -88,7 +88,7 @@ void fat_clusters_flush(struct super_block *sb) ...@@ -88,7 +88,7 @@ void fat_clusters_flush(struct super_block *sb)
int fat_add_cluster(struct inode *inode) int fat_add_cluster(struct inode *inode)
{ {
struct super_block *sb = inode->i_sb; 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; int cluster_bits = MSDOS_SB(sb)->cluster_bits;
/* /*
...@@ -123,7 +123,12 @@ int fat_add_cluster(struct inode *inode) ...@@ -123,7 +123,12 @@ int fat_add_cluster(struct inode *inode)
new_dclus = new_dclus % limit; new_dclus = new_dclus % limit;
if (new_dclus < 2) if (new_dclus < 2)
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; break;
} }
if (count >= MSDOS_SB(sb)->clusters) { if (count >= MSDOS_SB(sb)->clusters) {
...@@ -131,9 +136,14 @@ int fat_add_cluster(struct inode *inode) ...@@ -131,9 +136,14 @@ int fat_add_cluster(struct inode *inode)
unlock_fat(sb); unlock_fat(sb);
return -ENOSPC; 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) if (MSDOS_SB(sb)->free_clusters != -1)
MSDOS_SB(sb)->free_clusters--; MSDOS_SB(sb)->free_clusters--;
fat_clusters_flush(sb); fat_clusters_flush(sb);
...@@ -142,7 +152,9 @@ int fat_add_cluster(struct inode *inode) ...@@ -142,7 +152,9 @@ int fat_add_cluster(struct inode *inode)
/* add new one to the last of the cluster chain */ /* add new one to the last of the cluster chain */
if (last) { 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); fat_cache_add(inode, new_fclus, new_dclus);
} else { } else {
MSDOS_I(inode)->i_start = new_dclus; MSDOS_I(inode)->i_start = new_dclus;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment