vfs: Make sys_sync() use fsync_super() (version 4)

It is unnecessarily fragile to have two places (fsync_super() and do_sync())
doing data integrity sync of the filesystem. Alter __fsync_super() to
accommodate needs of both callers and use it. So after this patch
__fsync_super() is the only place where we gather all the calls needed to
properly send all data on a filesystem to disk.

Nice bonus is that we get a complete livelock avoidance and write_supers()
is now only used for periodic writeback of superblocks.

sync_blockdevs() introduced a couple of patches ago is gone now.

[build fixes folded]

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Jan Kara
2009-04-27 16:43:51 +02:00
committed by Al Viro
parent 429479f031
commit 5cee5815d1
7 changed files with 52 additions and 136 deletions

View File

@@ -18,35 +18,24 @@
#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
SYNC_FILE_RANGE_WAIT_AFTER)
/*
* sync everything. Start out by waking pdflush, because that writes back
* all queues in parallel.
*/
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_blockdevs();
if (!wait)
printk("Emergency Sync complete\n");
if (unlikely(laptop_mode))
laptop_sync_completion();
}
SYSCALL_DEFINE0(sync)
{
do_sync(1);
sync_filesystems(0);
sync_filesystems(1);
if (unlikely(laptop_mode))
laptop_sync_completion();
return 0;
}
static void do_sync_work(struct work_struct *work)
{
do_sync(0);
/*
* Sync twice to reduce the possibility we skipped some inodes / pages
* because they were temporarily locked
*/
sync_filesystems(0);
sync_filesystems(0);
printk("Emergency Sync complete\n");
kfree(work);
}