Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[cascardo/linux.git] / fs / super.c
index 48377f7..b9a214d 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <linux/export.h>
 #include <linux/slab.h>
-#include <linux/acct.h>
 #include <linux/blkdev.h>
 #include <linux/mount.h>
 #include <linux/security.h>
@@ -112,9 +111,14 @@ static unsigned long super_cache_count(struct shrinker *shrink,
 
        sb = container_of(shrink, struct super_block, s_shrink);
 
-       if (!grab_super_passive(sb))
-               return 0;
-
+       /*
+        * Don't call grab_super_passive as it is a potential
+        * scalability bottleneck. The counts could get updated
+        * between super_cache_count and super_cache_scan anyway.
+        * Call to super_cache_count with shrinker_rwsem held
+        * ensures the safety of call to list_lru_count_node() and
+        * s_op->nr_cached_objects().
+        */
        if (sb->s_op && sb->s_op->nr_cached_objects)
                total_objects = sb->s_op->nr_cached_objects(sb,
                                                 sc->nid);
@@ -125,7 +129,6 @@ static unsigned long super_cache_count(struct shrinker *shrink,
                                                 sc->nid);
 
        total_objects = vfs_pressure_ratio(total_objects);
-       drop_super(sb);
        return total_objects;
 }
 
@@ -214,7 +217,6 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
        lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key);
        mutex_init(&s->s_dquot.dqio_mutex);
        mutex_init(&s->s_dquot.dqonoff_mutex);
-       init_rwsem(&s->s_dquot.dqptr_sem);
        s->s_maxbytes = MAX_NON_LFS;
        s->s_op = &default_op;
        s->s_time_gran = 1000000000;
@@ -276,10 +278,8 @@ void deactivate_locked_super(struct super_block *s)
        struct file_system_type *fs = s->s_type;
        if (atomic_dec_and_test(&s->s_active)) {
                cleancache_invalidate_fs(s);
-               fs->kill_sb(s);
-
-               /* caches are now gone, we can safely kill the shrinker now */
                unregister_shrinker(&s->s_shrink);
+               fs->kill_sb(s);
 
                put_filesystem(fs);
                put_super(s);
@@ -700,12 +700,22 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
                return -EACCES;
 #endif
 
-       if (flags & MS_RDONLY)
-               acct_auto_close(sb);
-       shrink_dcache_sb(sb);
-
        remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
 
+       if (remount_ro) {
+               if (sb->s_pins.first) {
+                       up_write(&sb->s_umount);
+                       sb_pin_kill(sb);
+                       down_write(&sb->s_umount);
+                       if (!sb->s_root)
+                               return 0;
+                       if (sb->s_writers.frozen != SB_UNFROZEN)
+                               return -EBUSY;
+                       remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
+               }
+       }
+       shrink_dcache_sb(sb);
+
        /* If we are remounting RDONLY and current sb is read/write,
           make sure there are no rw files opened */
        if (remount_ro) {