new helper: destroy_unused_super()
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 11 Oct 2017 17:48:55 +0000 (13:48 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 11 Oct 2017 17:55:42 +0000 (13:55 -0400)
Used for disposal of super_block instances that had never been reachable
via any shared data structures.  No need for RCU delay in there, everything
can be called directly.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/super.c

index 166c4ee0d0ed02a00591c9b00cdb69eb8759ca61..01b7e3fd09e820a02050ab88b3718ce65226a8ed 100644 (file)
@@ -171,6 +171,21 @@ static void destroy_super(struct super_block *s)
        call_rcu(&s->rcu, destroy_super_rcu);
 }
 
+/* Free a superblock that has never been seen by anyone */
+static void destroy_unused_super(struct super_block *s)
+{
+       if (!s)
+               return;
+       up_write(&s->s_umount);
+       list_lru_destroy(&s->s_dentry_lru);
+       list_lru_destroy(&s->s_inode_lru);
+       security_sb_free(s);
+       put_user_ns(s->s_user_ns);
+       kfree(s->s_subtype);
+       /* no delays needed */
+       destroy_super_work(&s->destroy_work);
+}
+
 /**
  *     alloc_super     -       create new superblock
  *     @type:  filesystem type superblock should belong to
@@ -256,7 +271,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
        return s;
 
 fail:
-       destroy_super(s);
+       destroy_unused_super(s);
        return NULL;
 }
 
@@ -484,19 +499,12 @@ retry:
                                continue;
                        if (user_ns != old->s_user_ns) {
                                spin_unlock(&sb_lock);
-                               if (s) {
-                                       up_write(&s->s_umount);
-                                       destroy_super(s);
-                               }
+                               destroy_unused_super(s);
                                return ERR_PTR(-EBUSY);
                        }
                        if (!grab_super(old))
                                goto retry;
-                       if (s) {
-                               up_write(&s->s_umount);
-                               destroy_super(s);
-                               s = NULL;
-                       }
+                       destroy_unused_super(s);
                        return old;
                }
        }
@@ -511,8 +519,7 @@ retry:
        err = set(s, data);
        if (err) {
                spin_unlock(&sb_lock);
-               up_write(&s->s_umount);
-               destroy_super(s);
+               destroy_unused_super(s);
                return ERR_PTR(err);
        }
        s->s_type = type;