Commit d549b9ab authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[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.
parent 1c21abfb
...@@ -231,13 +231,10 @@ struct super_block *sget(struct file_system_type *type, ...@@ -231,13 +231,10 @@ struct super_block *sget(struct file_system_type *type,
int (*set)(struct super_block *,void *), int (*set)(struct super_block *,void *),
void *data) void *data)
{ {
struct super_block *s = alloc_super(); struct super_block *s = NULL;
struct list_head *p; struct list_head *p;
int err; int err;
if (!s)
return ERR_PTR(-ENOMEM);
retry: retry:
spin_lock(&sb_lock); spin_lock(&sb_lock);
if (test) list_for_each(p, &type->fs_supers) { if (test) list_for_each(p, &type->fs_supers) {
...@@ -247,9 +244,18 @@ struct super_block *sget(struct file_system_type *type, ...@@ -247,9 +244,18 @@ struct super_block *sget(struct file_system_type *type,
continue; continue;
if (!grab_super(old)) if (!grab_super(old))
goto retry; goto retry;
destroy_super(s); if (s)
destroy_super(s);
return old; return old;
} }
if (!s) {
spin_unlock(&sb_lock);
s = alloc_super();
if (!s)
return ERR_PTR(-ENOMEM);
goto retry;
}
err = set(s, data); err = set(s, data);
if (err) { if (err) {
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment