super: fix calculation of shrinkable objects for small numbers
[linux-block.git] / fs / super.c
index 68307c029228c51efc0e7967c90c39edd1a85113..63b6863bac7b0bf2e7736c7d05f96df02501d849 100644 (file)
@@ -71,7 +71,7 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc)
        if (!grab_super_passive(sb))
                return -1;
 
-       if (sb->s_op && sb->s_op->nr_cached_objects)
+       if (sb->s_op->nr_cached_objects)
                fs_objects = sb->s_op->nr_cached_objects(sb);
 
        total_objects = sb->s_nr_dentry_unused +
@@ -82,13 +82,13 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc)
                int     inodes;
 
                /* proportion the scan between the caches */
-               dentries = (sc->nr_to_scan * sb->s_nr_dentry_unused) /
-                                                       total_objects;
-               inodes = (sc->nr_to_scan * sb->s_nr_inodes_unused) /
-                                                       total_objects;
+               dentries = mult_frac(sc->nr_to_scan, sb->s_nr_dentry_unused,
+                                                       total_objects);
+               inodes = mult_frac(sc->nr_to_scan, sb->s_nr_inodes_unused,
+                                                       total_objects);
                if (fs_objects)
-                       fs_objects = (sc->nr_to_scan * fs_objects) /
-                                                       total_objects;
+                       fs_objects = mult_frac(sc->nr_to_scan, fs_objects,
+                                                       total_objects);
                /*
                 * prune the dcache first as the icache is pinned by it, then
                 * prune the icache, followed by the filesystem specific caches
@@ -104,7 +104,7 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc)
                                sb->s_nr_inodes_unused + fs_objects;
        }
 
-       total_objects = (total_objects / 100) * sysctl_vfs_cache_pressure;
+       total_objects = vfs_pressure_ratio(total_objects);
        drop_super(sb);
        return total_objects;
 }
@@ -152,15 +152,9 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
        static const struct super_operations default_op;
 
        if (s) {
-               if (security_sb_alloc(s)) {
-                       /*
-                        * We cannot call security_sb_free() without
-                        * security_sb_alloc() succeeding. So bail out manually
-                        */
-                       kfree(s);
-                       s = NULL;
-                       goto out;
-               }
+               if (security_sb_alloc(s))
+                       goto out_free_sb;
+
 #ifdef CONFIG_SMP
                s->s_files = alloc_percpu(struct list_head);
                if (!s->s_files)
@@ -228,6 +222,7 @@ err_out:
                free_percpu(s->s_files);
 #endif
        destroy_sb_writers(s);
+out_free_sb:
        kfree(s);
        s = NULL;
        goto out;
@@ -414,6 +409,11 @@ void generic_shutdown_super(struct super_block *sb)
 
                evict_inodes(sb);
 
+               if (sb->s_dio_done_wq) {
+                       destroy_workqueue(sb->s_dio_done_wq);
+                       sb->s_dio_done_wq = NULL;
+               }
+
                if (sop->put_super)
                        sop->put_super(sb);