- Add some commentary to this function - Add a mutex to prevent new callers of sync_filesytems() from DoSing currently-running caller. fs/super.c | 17 ++++++++++++++++- 1 files changed, 16 insertions(+), 1 deletion(-) diff -puN fs/super.c~sync_filesystems-docco-lock fs/super.c --- 25/fs/super.c~sync_filesystems-docco-lock 2003-03-20 18:25:40.000000000 -0800 +++ 25-akpm/fs/super.c 2003-03-20 18:25:40.000000000 -0800 @@ -303,11 +303,25 @@ restart: /* * Call the ->sync_fs super_op against all filesytems which are r/w and * 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) { - struct super_block * sb; + struct super_block *sb; + static DECLARE_MUTEX(mutex); + down(&mutex); /* Could be down_interruptible */ spin_lock(&sb_lock); for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.next)) { @@ -337,6 +351,7 @@ restart: goto restart; } spin_unlock(&sb_lock); + up(&mutex); } /** _