]> git.hungrycats.org Git - linux/commitdiff
[PATCH] fatfs: fix printk storm during I/O errors
authorAndrew Morton <akpm@osdl.org>
Tue, 30 Dec 2003 07:43:52 +0000 (23:43 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Tue, 30 Dec 2003 07:43:52 +0000 (23:43 -0800)
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.

fs/fat/inode.c
fs/fat/misc.c

index 11f64401f1bdca25c8252747c32ad28f3d9a7feb..378bfde188d0c3202c66602a5d538927d34b1873 100644 (file)
@@ -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);
index b50f423466eb9129c8c2868ba717b30d5127ff2f..c3a7785d8381dc0fc0f7047ebb14685daafe90e6 100644 (file)
@@ -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;