From 5e39505111554f4b45618865057d99298797fea4 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 27 Apr 2009 16:43:48 +0200 Subject: [PATCH] --- yaml --- r: 147828 b: refs/heads/master c: 5a3e5cb8e08bd876e2542c1451c9a93dab1b0e39 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/internal.h | 9 +++++++++ trunk/fs/super.c | 29 ++++++++++++++++++++++++++++- trunk/fs/sync.c | 4 +++- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index f3fdb9712219..2bbc920047a7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 876a9f76abbcb775f8d21cbc99fa161f9e5937f1 +refs/heads/master: 5a3e5cb8e08bd876e2542c1451c9a93dab1b0e39 diff --git a/trunk/fs/internal.h b/trunk/fs/internal.h index 6d4ef208ef65..343a537ab809 100644 --- a/trunk/fs/internal.h +++ b/trunk/fs/internal.h @@ -71,3 +71,12 @@ extern void chroot_fs_refs(struct path *, struct path *); * file_table.c */ extern void mark_files_ro(struct super_block *); + +/* + * super.c + */ +#ifdef CONFIG_BLOCK +extern void sync_blockdevs(void); +#else +static inline void sync_blockdevs(void) { } +#endif diff --git a/trunk/fs/super.c b/trunk/fs/super.c index 3d9f117dd2a3..18d159dc1e40 100644 --- a/trunk/fs/super.c +++ b/trunk/fs/super.c @@ -293,6 +293,7 @@ void __fsync_super(struct super_block *sb) { sync_inodes_sb(sb, 0); vfs_dq_sync(sb); + sync_inodes_sb(sb, 1); lock_super(sb); if (sb->s_dirt && sb->s_op->write_super) sb->s_op->write_super(sb); @@ -300,7 +301,6 @@ void __fsync_super(struct super_block *sb) if (sb->s_op->sync_fs) sb->s_op->sync_fs(sb, 1); sync_blockdev(sb->s_bdev); - sync_inodes_sb(sb, 1); } /* @@ -522,6 +522,33 @@ void sync_filesystems(int wait) mutex_unlock(&mutex); } +#ifdef CONFIG_BLOCK +/* + * Sync all block devices underlying some superblock + */ +void sync_blockdevs(void) +{ + struct super_block *sb; + + spin_lock(&sb_lock); +restart: + list_for_each_entry(sb, &super_blocks, s_list) { + if (!sb->s_bdev) + continue; + sb->s_count++; + spin_unlock(&sb_lock); + down_read(&sb->s_umount); + if (sb->s_root) + sync_blockdev(sb->s_bdev); + up_read(&sb->s_umount); + spin_lock(&sb_lock); + if (__put_super_and_need_restart(sb)) + goto restart; + } + spin_unlock(&sb_lock); +} +#endif + /** * get_super - get the superblock of a device * @bdev: device to get the superblock for diff --git a/trunk/fs/sync.c b/trunk/fs/sync.c index 7abc65fbf21d..631fd5aece78 100644 --- a/trunk/fs/sync.c +++ b/trunk/fs/sync.c @@ -13,6 +13,7 @@ #include #include #include +#include "internal.h" #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ SYNC_FILE_RANGE_WAIT_AFTER) @@ -26,10 +27,11 @@ static void do_sync(unsigned long wait) wakeup_pdflush(0); sync_inodes(0); /* All mappings, inodes and their blockdevs */ vfs_dq_sync(NULL); + sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */ sync_supers(); /* Write the superblocks */ sync_filesystems(0); /* Start syncing the filesystems */ sync_filesystems(wait); /* Waitingly sync the filesystems */ - sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */ + sync_blockdevs(); if (!wait) printk("Emergency Sync complete\n"); if (unlikely(laptop_mode))