Commit e1a1de5f authored by Andrew Morton's avatar Andrew Morton Committed by David S. Miller

[PATCH] sync_filesystems commentary and latency fix

- Add some commentary to this function

- Add a mutex to prevent new callers of sync_filesytems() from DoSing
  currently-running caller.
parent b39fe640
...@@ -303,11 +303,25 @@ void sync_supers(void) ...@@ -303,11 +303,25 @@ void sync_supers(void)
/* /*
* Call the ->sync_fs super_op against all filesytems which are r/w and * Call the ->sync_fs super_op against all filesytems which are r/w and
* which implement it. * which implement it.
*
* This operation is careful to avoid the livelock which could easily happen
* if two or more filesystems are being continuously dirtied. s_need_sync_fs
* is used only here. We set it against all filesystems and then clear it as
* we sync them. So redirtied filesystems are skipped.
*
* But if process A is currently running sync_filesytems and then process B
* calls sync_filesystems as well, process B will set all the s_need_sync_fs
* flags again, which will cause process A to resync everything. Fix that with
* a local mutex.
*
* FIXME: If wait==0, we only really need to call ->sync_fs if s_dirt is true.
*/ */
void sync_filesystems(int wait) void sync_filesystems(int wait)
{ {
struct super_block * sb; struct super_block *sb;
static DECLARE_MUTEX(mutex);
down(&mutex); /* Could be down_interruptible */
spin_lock(&sb_lock); spin_lock(&sb_lock);
for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks); for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks);
sb = sb_entry(sb->s_list.next)) { sb = sb_entry(sb->s_list.next)) {
...@@ -337,6 +351,7 @@ void sync_filesystems(int wait) ...@@ -337,6 +351,7 @@ void sync_filesystems(int wait)
goto restart; goto restart;
} }
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
up(&mutex);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment