]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/super.c
cleanup sync_supers
[net-next-2.6.git] / fs / super.c
index 1943fdf655faca2d3d1810cca8b36ac80c9d3593..cb19fffc7681f9d5b96bfa22c8050df0728bcaca 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/blkdev.h>
 #include <linux/quotaops.h>
 #include <linux/namei.h>
-#include <linux/buffer_head.h>         /* for fsync_super() */
 #include <linux/mount.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
@@ -38,7 +37,6 @@
 #include <linux/kobject.h>
 #include <linux/mutex.h>
 #include <linux/file.h>
-#include <linux/async.h>
 #include <asm/uaccess.h>
 #include "internal.h"
 
@@ -72,7 +70,6 @@ static struct super_block *alloc_super(struct file_system_type *type)
                INIT_HLIST_HEAD(&s->s_anon);
                INIT_LIST_HEAD(&s->s_inodes);
                INIT_LIST_HEAD(&s->s_dentry_lru);
-               INIT_LIST_HEAD(&s->s_async_list);
                init_rwsem(&s->s_umount);
                mutex_init(&s->s_lock);
                lockdep_set_class(&s->s_umount, &type->s_umount_key);
@@ -285,38 +282,6 @@ void unlock_super(struct super_block * sb)
 EXPORT_SYMBOL(lock_super);
 EXPORT_SYMBOL(unlock_super);
 
-/*
- * Write out and wait upon all dirty data associated with this
- * superblock.  Filesystem data as well as the underlying block
- * device.  Takes the superblock lock.  Requires a second blkdev
- * flush by the caller to complete the operation.
- */
-void __fsync_super(struct super_block *sb)
-{
-       sync_inodes_sb(sb, 0);
-       vfs_dq_sync(sb);
-       lock_super(sb);
-       if (sb->s_dirt && sb->s_op->write_super)
-               sb->s_op->write_super(sb);
-       unlock_super(sb);
-       if (sb->s_op->sync_fs)
-               sb->s_op->sync_fs(sb, 1);
-       sync_blockdev(sb->s_bdev);
-       sync_inodes_sb(sb, 1);
-}
-
-/*
- * Write out and wait upon all dirty data associated with this
- * superblock.  Filesystem data as well as the underlying block
- * device.  Takes the superblock lock.
- */
-int fsync_super(struct super_block *sb)
-{
-       __fsync_super(sb);
-       return sync_blockdev(sb->s_bdev);
-}
-EXPORT_SYMBOL_GPL(fsync_super);
-
 /**
  *     generic_shutdown_super  -       common helper for ->kill_sb()
  *     @sb: superblock to kill
@@ -338,21 +303,14 @@ void generic_shutdown_super(struct super_block *sb)
 
        if (sb->s_root) {
                shrink_dcache_for_umount(sb);
-               fsync_super(sb);
+               sync_filesystem(sb);
                lock_super(sb);
                sb->s_flags &= ~MS_ACTIVE;
 
-               /*
-                * wait for asynchronous fs operations to finish before going further
-                */
-               async_synchronize_full_domain(&sb->s_async_list);
-
                /* bad name - it should be evict_inodes() */
                invalidate_inodes(sb);
                lock_kernel();
 
-               if (sop->write_super && sb->s_dirt)
-                       sop->write_super(sb);
                if (sop->put_super)
                        sop->put_super(sb);
 
@@ -441,16 +399,14 @@ void drop_super(struct super_block *sb)
 
 EXPORT_SYMBOL(drop_super);
 
-static inline void write_super(struct super_block *sb)
-{
-       lock_super(sb);
-       if (sb->s_root && sb->s_dirt)
-               if (sb->s_op->write_super)
-                       sb->s_op->write_super(sb);
-       unlock_super(sb);
-}
-
-/*
+/**
+ * sync_supers - helper for periodic superblock writeback
+ *
+ * Call the write_super method if present on all dirty superblocks in
+ * the system.  This is for the periodic writeback used by most older
+ * filesystems.  For data integrity superblock writeback use
+ * sync_filesystems() instead.
+ *
  * Note: check the dirty flag before waiting, so we don't
  * hold up the sync while mounting a device. (The newly
  * mounted device won't need syncing.)
@@ -462,12 +418,17 @@ void sync_supers(void)
        spin_lock(&sb_lock);
 restart:
        list_for_each_entry(sb, &super_blocks, s_list) {
-               if (sb->s_dirt) {
+               if (sb->s_op->write_super && sb->s_dirt) {
                        sb->s_count++;
                        spin_unlock(&sb_lock);
+
                        down_read(&sb->s_umount);
-                       write_super(sb);
+                       lock_super(sb);
+                       if (sb->s_root && sb->s_dirt)
+                               sb->s_op->write_super(sb);
+                       unlock_super(sb);
                        up_read(&sb->s_umount);
+
                        spin_lock(&sb_lock);
                        if (__put_super_and_need_restart(sb))
                                goto restart;
@@ -476,60 +437,6 @@ restart:
        spin_unlock(&sb_lock);
 }
 
-/*
- * Call the ->sync_fs super_op against all filesystems 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_filesystems 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.
- *
- * (Fabian) Avoid sync_fs with clean fs & wait mode 0
- */
-void sync_filesystems(int wait)
-{
-       struct super_block *sb;
-       static DEFINE_MUTEX(mutex);
-
-       mutex_lock(&mutex);             /* Could be down_interruptible */
-       spin_lock(&sb_lock);
-       list_for_each_entry(sb, &super_blocks, s_list) {
-               if (!sb->s_op->sync_fs)
-                       continue;
-               if (sb->s_flags & MS_RDONLY)
-                       continue;
-               sb->s_need_sync_fs = 1;
-       }
-
-restart:
-       list_for_each_entry(sb, &super_blocks, s_list) {
-               if (!sb->s_need_sync_fs)
-                       continue;
-               sb->s_need_sync_fs = 0;
-               if (sb->s_flags & MS_RDONLY)
-                       continue;       /* hm.  Was remounted r/o meanwhile */
-               sb->s_count++;
-               spin_unlock(&sb_lock);
-               down_read(&sb->s_umount);
-               async_synchronize_full_domain(&sb->s_async_list);
-               if (sb->s_root && (wait || sb->s_dirt))
-                       sb->s_op->sync_fs(sb, wait);
-               up_read(&sb->s_umount);
-               /* restart only when sb is no longer on the list */
-               spin_lock(&sb_lock);
-               if (__put_super_and_need_restart(sb))
-                       goto restart;
-       }
-       spin_unlock(&sb_lock);
-       mutex_unlock(&mutex);
-}
-
 /**
  *     get_super - get the superblock of a device
  *     @bdev: device to get the superblock for
@@ -615,45 +522,6 @@ out:
        return err;
 }
 
-/**
- *     mark_files_ro - mark all files read-only
- *     @sb: superblock in question
- *
- *     All files are marked read-only.  We don't care about pending
- *     delete files so this should be used in 'force' mode only.
- */
-
-static void mark_files_ro(struct super_block *sb)
-{
-       struct file *f;
-
-retry:
-       file_list_lock();
-       list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
-               struct vfsmount *mnt;
-               if (!S_ISREG(f->f_path.dentry->d_inode->i_mode))
-                      continue;
-               if (!file_count(f))
-                       continue;
-               if (!(f->f_mode & FMODE_WRITE))
-                       continue;
-               f->f_mode &= ~FMODE_WRITE;
-               if (file_check_writeable(f) != 0)
-                       continue;
-               file_release_write(f);
-               mnt = mntget(f->f_path.mnt);
-               file_list_unlock();
-               /*
-                * This can sleep, so we can't hold
-                * the file_list_lock() spinlock.
-                */
-               mnt_drop_write(mnt);
-               mntput(mnt);
-               goto retry;
-       }
-       file_list_unlock();
-}
-
 /**
  *     do_remount_sb - asks filesystem to change mount options.
  *     @sb:    superblock in question
@@ -675,7 +543,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
        if (flags & MS_RDONLY)
                acct_auto_close(sb);
        shrink_dcache_sb(sb);
-       fsync_super(sb);
+       sync_filesystem(sb);
 
        /* If we are remounting RDONLY and current sb is read/write,
           make sure there are no rw files opened */