fat: Check s_dirt in fat_sync_fs()
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Sat, 19 Sep 2009 16:31:58 +0000 (01:31 +0900)
committerOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Sat, 19 Sep 2009 16:35:25 +0000 (01:35 +0900)
If we didn't check sb->s_dirt, it will update the FSINFO
unconditionally. It will reduce the filetime of flash base device.

So, this checks sb->s_dirt. sb->s_dirt is racy, however FSINFO is just
hint. So even if there is race, and we hit it, it would not become big
problem.

And this also is as workaround of suspend problem.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
fs/fat/fat.h
fs/fat/inode.c
fs/fat/misc.c

index adb0e72a176dd42bb8bdd1b4d099e021a02b02b1..7db0979c6b72f0d16e19c77d6e73af5642992f83 100644 (file)
@@ -323,7 +323,7 @@ extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
 /* fat/misc.c */
 extern void fat_fs_error(struct super_block *s, const char *fmt, ...)
        __attribute__ ((format (printf, 2, 3))) __cold;
-extern void fat_clusters_flush(struct super_block *sb);
+extern int fat_clusters_flush(struct super_block *sb);
 extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster);
 extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
                              __le16 __time, __le16 __date, u8 time_cs);
index 63a5c1a4ee60fe627db29726ec6622315a7c3f7f..a8a3afec87581da99083bb11abc3f8a42f460401 100644 (file)
@@ -451,12 +451,16 @@ static void fat_write_super(struct super_block *sb)
 
 static int fat_sync_fs(struct super_block *sb, int wait)
 {
-       lock_super(sb);
-       fat_clusters_flush(sb);
-       sb->s_dirt = 0;
-       unlock_super(sb);
+       int err = 0;
 
-       return 0;
+       if (sb->s_dirt) {
+               lock_super(sb);
+               sb->s_dirt = 0;
+               err = fat_clusters_flush(sb);
+               unlock_super(sb);
+       }
+
+       return err;
 }
 
 static void fat_put_super(struct super_block *sb)
index a6c20473dfd75bd83d2d6caf1d4685078c687fb4..63785a150290c4f9ad00a50464f7e45db21c10d3 100644 (file)
@@ -43,19 +43,19 @@ EXPORT_SYMBOL_GPL(fat_fs_error);
 
 /* Flushes the number of free clusters on FAT32 */
 /* XXX: Need to write one per FSINFO block.  Currently only writes 1 */
-void fat_clusters_flush(struct super_block *sb)
+int fat_clusters_flush(struct super_block *sb)
 {
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
        struct buffer_head *bh;
        struct fat_boot_fsinfo *fsinfo;
 
        if (sbi->fat_bits != 32)
-               return;
+               return 0;
 
        bh = sb_bread(sb, sbi->fsinfo_sector);
        if (bh == NULL) {
                printk(KERN_ERR "FAT: bread failed in fat_clusters_flush\n");
-               return;
+               return -EIO;
        }
 
        fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
@@ -74,6 +74,8 @@ void fat_clusters_flush(struct super_block *sb)
                mark_buffer_dirty(bh);
        }
        brelse(bh);
+
+       return 0;
 }
 
 /*