]> err.no Git - linux-2.6/blobdiff - fs/fs-writeback.c
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-2.6] / fs / fs-writeback.c
index d6efb36cab2a7d5089e2ec5358424c1990fc3f24..e94ab398b71763b3caf598dfe8fbeb66e818789d 100644 (file)
@@ -485,34 +485,9 @@ static void set_sb_syncing(int val)
        spin_unlock(&sb_lock);
 }
 
-/*
- * Find a superblock with inodes that need to be synced
- */
-static struct super_block *get_super_to_sync(void)
-{
-       struct super_block *sb;
-restart:
-       spin_lock(&sb_lock);
-       sb = sb_entry(super_blocks.prev);
-       for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) {
-               if (sb->s_syncing)
-                       continue;
-               sb->s_syncing = 1;
-               sb->s_count++;
-               spin_unlock(&sb_lock);
-               down_read(&sb->s_umount);
-               if (!sb->s_root) {
-                       drop_super(sb);
-                       goto restart;
-               }
-               return sb;
-       }
-       spin_unlock(&sb_lock);
-       return NULL;
-}
-
 /**
- * sync_inodes
+ * sync_inodes - writes all inodes to disk
+ * @wait: wait for completion
  *
  * sync_inodes() goes through each super block's dirty inode list, writes the
  * inodes out, waits on the writeout and puts the inodes back on the normal
@@ -529,23 +504,39 @@ restart:
  * outstanding dirty inodes, the writeback goes block-at-a-time within the
  * filesystem's write_inode().  This is extremely slow.
  */
-void sync_inodes(int wait)
+static void __sync_inodes(int wait)
 {
        struct super_block *sb;
 
-       set_sb_syncing(0);
-       while ((sb = get_super_to_sync()) != NULL) {
-               sync_inodes_sb(sb, 0);
-               sync_blockdev(sb->s_bdev);
-               drop_super(sb);
+       spin_lock(&sb_lock);
+restart:
+       list_for_each_entry(sb, &super_blocks, s_list) {
+               if (sb->s_syncing)
+                       continue;
+               sb->s_syncing = 1;
+               sb->s_count++;
+               spin_unlock(&sb_lock);
+               down_read(&sb->s_umount);
+               if (sb->s_root) {
+                       sync_inodes_sb(sb, wait);
+                       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);
+}
+
+void sync_inodes(int wait)
+{
+       set_sb_syncing(0);
+       __sync_inodes(0);
+
        if (wait) {
                set_sb_syncing(0);
-               while ((sb = get_super_to_sync()) != NULL) {
-                       sync_inodes_sb(sb, 1);
-                       sync_blockdev(sb->s_bdev);
-                       drop_super(sb);
-               }
+               __sync_inodes(1);
        }
 }
 
@@ -604,6 +595,7 @@ EXPORT_SYMBOL(sync_inode);
 /**
  * generic_osync_inode - flush all dirty data for a given inode to disk
  * @inode: inode to write
+ * @mapping: the address_space that should be flushed
  * @what:  what to write and wait upon
  *
  * This can be called by file_write functions for files which have the