Merge tag 'nfs-for-3.20-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[cascardo/linux.git] / fs / super.c
index a2b735a..65a53ef 100644 (file)
@@ -36,8 +36,8 @@
 #include "internal.h"
 
 
-LIST_HEAD(super_blocks);
-DEFINE_SPINLOCK(sb_lock);
+static LIST_HEAD(super_blocks);
+static DEFINE_SPINLOCK(sb_lock);
 
 static char *sb_writers_name[SB_FREEZE_LEVELS] = {
        "sb_writers",
@@ -91,14 +91,17 @@ static unsigned long super_cache_scan(struct shrinker *shrink,
        /*
         * prune the dcache first as the icache is pinned by it, then
         * prune the icache, followed by the filesystem specific caches
+        *
+        * Ensure that we always scan at least one object - memcg kmem
+        * accounting uses this to fully empty the caches.
         */
-       sc->nr_to_scan = dentries;
+       sc->nr_to_scan = dentries + 1;
        freed = prune_dcache_sb(sb, sc);
-       sc->nr_to_scan = inodes;
+       sc->nr_to_scan = inodes + 1;
        freed += prune_icache_sb(sb, sc);
 
        if (fs_objects) {
-               sc->nr_to_scan = fs_objects;
+               sc->nr_to_scan = fs_objects + 1;
                freed += sb->s_op->free_cached_objects(sb, sc);
        }
 
@@ -183,15 +186,15 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
        }
        init_waitqueue_head(&s->s_writers.wait);
        init_waitqueue_head(&s->s_writers.wait_unfrozen);
+       s->s_bdi = &noop_backing_dev_info;
        s->s_flags = flags;
-       s->s_bdi = &default_backing_dev_info;
        INIT_HLIST_NODE(&s->s_instances);
        INIT_HLIST_BL_HEAD(&s->s_anon);
        INIT_LIST_HEAD(&s->s_inodes);
 
-       if (list_lru_init(&s->s_dentry_lru))
+       if (list_lru_init_memcg(&s->s_dentry_lru))
                goto fail;
-       if (list_lru_init(&s->s_inode_lru))
+       if (list_lru_init_memcg(&s->s_inode_lru))
                goto fail;
 
        init_rwsem(&s->s_umount);
@@ -227,7 +230,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
        s->s_shrink.scan_objects = super_cache_scan;
        s->s_shrink.count_objects = super_cache_count;
        s->s_shrink.batch = 1024;
-       s->s_shrink.flags = SHRINKER_NUMA_AWARE;
+       s->s_shrink.flags = SHRINKER_NUMA_AWARE | SHRINKER_MEMCG_AWARE;
        return s;
 
 fail:
@@ -282,6 +285,14 @@ void deactivate_locked_super(struct super_block *s)
                unregister_shrinker(&s->s_shrink);
                fs->kill_sb(s);
 
+               /*
+                * Since list_lru_destroy() may sleep, we cannot call it from
+                * put_super(), where we hold the sb_lock. Therefore we destroy
+                * the lru lists right now.
+                */
+               list_lru_destroy(&s->s_dentry_lru);
+               list_lru_destroy(&s->s_inode_lru);
+
                put_filesystem(fs);
                put_super(s);
        } else {
@@ -704,9 +715,9 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
        remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
 
        if (remount_ro) {
-               if (sb->s_pins.first) {
+               if (!hlist_empty(&sb->s_pins)) {
                        up_write(&sb->s_umount);
-                       sb_pin_kill(sb);
+                       group_pin_kill(&sb->s_pins);
                        down_write(&sb->s_umount);
                        if (!sb->s_root)
                                return 0;
@@ -861,10 +872,7 @@ EXPORT_SYMBOL(free_anon_bdev);
 
 int set_anon_super(struct super_block *s, void *data)
 {
-       int error = get_anon_bdev(&s->s_dev);
-       if (!error)
-               s->s_bdi = &noop_backing_dev_info;
-       return error;
+       return get_anon_bdev(&s->s_dev);
 }
 
 EXPORT_SYMBOL(set_anon_super);
@@ -1109,7 +1117,6 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
        sb = root->d_sb;
        BUG_ON(!sb);
        WARN_ON(!sb->s_bdi);
-       WARN_ON(sb->s_bdi == &default_backing_dev_info);
        sb->s_flags |= MS_BORN;
 
        error = security_sb_kern_mount(sb, flags, secdata);