mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 19:26:25 +00:00
fat: Check s_dirt in fat_sync_fs()
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>
This commit is contained in:
parent
955234755c
commit
ed248b290d
3 changed files with 15 additions and 9 deletions
|
@ -323,7 +323,7 @@ extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
|
||||||
/* fat/misc.c */
|
/* fat/misc.c */
|
||||||
extern void fat_fs_error(struct super_block *s, const char *fmt, ...)
|
extern void fat_fs_error(struct super_block *s, const char *fmt, ...)
|
||||||
__attribute__ ((format (printf, 2, 3))) __cold;
|
__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 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,
|
extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
|
||||||
__le16 __time, __le16 __date, u8 time_cs);
|
__le16 __time, __le16 __date, u8 time_cs);
|
||||||
|
|
|
@ -451,12 +451,16 @@ static void fat_write_super(struct super_block *sb)
|
||||||
|
|
||||||
static int fat_sync_fs(struct super_block *sb, int wait)
|
static int fat_sync_fs(struct super_block *sb, int wait)
|
||||||
{
|
{
|
||||||
lock_super(sb);
|
int err = 0;
|
||||||
fat_clusters_flush(sb);
|
|
||||||
sb->s_dirt = 0;
|
|
||||||
unlock_super(sb);
|
|
||||||
|
|
||||||
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)
|
static void fat_put_super(struct super_block *sb)
|
||||||
|
|
|
@ -43,19 +43,19 @@ EXPORT_SYMBOL_GPL(fat_fs_error);
|
||||||
|
|
||||||
/* Flushes the number of free clusters on FAT32 */
|
/* Flushes the number of free clusters on FAT32 */
|
||||||
/* XXX: Need to write one per FSINFO block. Currently only writes 1 */
|
/* 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 msdos_sb_info *sbi = MSDOS_SB(sb);
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
struct fat_boot_fsinfo *fsinfo;
|
struct fat_boot_fsinfo *fsinfo;
|
||||||
|
|
||||||
if (sbi->fat_bits != 32)
|
if (sbi->fat_bits != 32)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
bh = sb_bread(sb, sbi->fsinfo_sector);
|
bh = sb_bread(sb, sbi->fsinfo_sector);
|
||||||
if (bh == NULL) {
|
if (bh == NULL) {
|
||||||
printk(KERN_ERR "FAT: bread failed in fat_clusters_flush\n");
|
printk(KERN_ERR "FAT: bread failed in fat_clusters_flush\n");
|
||||||
return;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
|
fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
|
||||||
|
@ -74,6 +74,8 @@ void fat_clusters_flush(struct super_block *sb)
|
||||||
mark_buffer_dirty(bh);
|
mark_buffer_dirty(bh);
|
||||||
}
|
}
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue