mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
sysfs: use rb-tree for name lookups
sysfs: use rb-tree for name lookups Use red-black tree for name lookups. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
7f9838fd01
commit
4f72c0cab4
@ -45,6 +45,9 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd)
|
|||||||
struct sysfs_dirent *parent_sd = sd->s_parent;
|
struct sysfs_dirent *parent_sd = sd->s_parent;
|
||||||
struct sysfs_dirent **pos;
|
struct sysfs_dirent **pos;
|
||||||
|
|
||||||
|
struct rb_node **p;
|
||||||
|
struct rb_node *parent;
|
||||||
|
|
||||||
BUG_ON(sd->s_sibling);
|
BUG_ON(sd->s_sibling);
|
||||||
|
|
||||||
if (sysfs_type(sd) == SYSFS_DIR)
|
if (sysfs_type(sd) == SYSFS_DIR)
|
||||||
@ -60,6 +63,23 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd)
|
|||||||
}
|
}
|
||||||
sd->s_sibling = *pos;
|
sd->s_sibling = *pos;
|
||||||
*pos = sd;
|
*pos = sd;
|
||||||
|
|
||||||
|
p = &parent_sd->s_dir.name_tree.rb_node;
|
||||||
|
parent = NULL;
|
||||||
|
while (*p) {
|
||||||
|
int c;
|
||||||
|
parent = *p;
|
||||||
|
#define node rb_entry(parent, struct sysfs_dirent, name_node)
|
||||||
|
c = strcmp(sd->s_name, node->s_name);
|
||||||
|
if (c < 0) {
|
||||||
|
p = &node->name_node.rb_left;
|
||||||
|
} else {
|
||||||
|
p = &node->name_node.rb_right;
|
||||||
|
}
|
||||||
|
#undef node
|
||||||
|
}
|
||||||
|
rb_link_node(&sd->name_node, parent, p);
|
||||||
|
rb_insert_color(&sd->name_node, &parent_sd->s_dir.name_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,6 +107,8 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rb_erase(&sd->name_node, &sd->s_parent->s_dir.name_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -546,15 +568,36 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
|
|||||||
const void *ns,
|
const void *ns,
|
||||||
const unsigned char *name)
|
const unsigned char *name)
|
||||||
{
|
{
|
||||||
struct sysfs_dirent *sd;
|
struct rb_node *p = parent_sd->s_dir.name_tree.rb_node;
|
||||||
|
struct sysfs_dirent *found = NULL;
|
||||||
|
|
||||||
for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) {
|
while (p) {
|
||||||
if (ns && sd->s_ns && (sd->s_ns != ns))
|
int c;
|
||||||
continue;
|
#define node rb_entry(p, struct sysfs_dirent, name_node)
|
||||||
if (!strcmp(sd->s_name, name))
|
c = strcmp(name, node->s_name);
|
||||||
return sd;
|
if (c < 0) {
|
||||||
|
p = node->name_node.rb_left;
|
||||||
|
} else if (c > 0) {
|
||||||
|
p = node->name_node.rb_right;
|
||||||
|
} else {
|
||||||
|
found = node;
|
||||||
|
p = node->name_node.rb_left;
|
||||||
|
}
|
||||||
|
#undef node
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
|
if (found && ns) {
|
||||||
|
while (found->s_ns && found->s_ns != ns) {
|
||||||
|
p = rb_next(&found->name_node);
|
||||||
|
if (!p)
|
||||||
|
return NULL;
|
||||||
|
found = rb_entry(p, struct sysfs_dirent, name_node);
|
||||||
|
if (strcmp(name, found->s_name))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <linux/lockdep.h>
|
#include <linux/lockdep.h>
|
||||||
#include <linux/kobject_ns.h>
|
#include <linux/kobject_ns.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
#include <linux/rbtree.h>
|
||||||
|
|
||||||
struct sysfs_open_dirent;
|
struct sysfs_open_dirent;
|
||||||
|
|
||||||
@ -21,6 +22,8 @@ struct sysfs_elem_dir {
|
|||||||
struct sysfs_dirent *children;
|
struct sysfs_dirent *children;
|
||||||
|
|
||||||
unsigned long subdirs;
|
unsigned long subdirs;
|
||||||
|
|
||||||
|
struct rb_root name_tree;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sysfs_elem_symlink {
|
struct sysfs_elem_symlink {
|
||||||
@ -61,6 +64,8 @@ struct sysfs_dirent {
|
|||||||
struct sysfs_dirent *s_sibling;
|
struct sysfs_dirent *s_sibling;
|
||||||
const char *s_name;
|
const char *s_name;
|
||||||
|
|
||||||
|
struct rb_node name_node;
|
||||||
|
|
||||||
const void *s_ns; /* namespace tag */
|
const void *s_ns; /* namespace tag */
|
||||||
union {
|
union {
|
||||||
struct sysfs_elem_dir s_dir;
|
struct sysfs_elem_dir s_dir;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user