From d549b9abf815265d18a83f75942135acddefd060 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Wed, 1 Oct 2003 17:38:22 -0700 Subject: [PATCH] [PATCH] Improve sget() performance sget() is pessimistic and assumes it won't find a superblock - and as a result it always pre-allocates a new one before even searching for an existing entry. If it finds an existing one, it free's the extra one it just allocated. Especially with /proc usage it usually _does_ find an existing superblock, so this is all extra work. It should allocate a new one only if it couldn't find an old one (and re-search). The same way as iget() does it. --- fs/super.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/fs/super.c b/fs/super.c index ea7737de993b5..67a0175290567 100644 --- a/fs/super.c +++ b/fs/super.c @@ -231,13 +231,10 @@ struct super_block *sget(struct file_system_type *type, int (*set)(struct super_block *,void *), void *data) { - struct super_block *s = alloc_super(); + struct super_block *s = NULL; struct list_head *p; int err; - if (!s) - return ERR_PTR(-ENOMEM); - retry: spin_lock(&sb_lock); if (test) list_for_each(p, &type->fs_supers) { @@ -247,9 +244,18 @@ retry: continue; if (!grab_super(old)) goto retry; - destroy_super(s); + if (s) + destroy_super(s); return old; } + if (!s) { + spin_unlock(&sb_lock); + s = alloc_super(); + if (!s) + return ERR_PTR(-ENOMEM); + goto retry; + } + err = set(s, data); if (err) { spin_unlock(&sb_lock); -- 2.53.0