Commit 46aeebdb authored by Pavel Emelyanov's avatar Pavel Emelyanov

kcmp: Make ID generation tree work on abstract elements, not fd-entries

Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent fe670c5a
...@@ -25,6 +25,12 @@ struct kid_tree { ...@@ -25,6 +25,12 @@ struct kid_tree {
}; };
struct kid_elem {
int pid;
unsigned genid;
unsigned idx;
};
static struct kid_tree fd_tree = { static struct kid_tree fd_tree = {
.root = RB_ROOT, .root = RB_ROOT,
.kcmp_type = KCMP_FILE, .kcmp_type = KCMP_FILE,
...@@ -77,18 +83,15 @@ struct kid_entry { ...@@ -77,18 +83,15 @@ struct kid_entry {
struct rb_root subtree_root; struct rb_root subtree_root;
struct rb_node subtree_node; struct rb_node subtree_node;
u32 genid; /* generic id, may have duplicates */
u32 subid; /* subid is always unique */ u32 subid; /* subid is always unique */
struct kid_elem elem;
pid_t pid;
int fd;
} __aligned(sizeof(long)); } __aligned(sizeof(long));
static void show_subnode(struct rb_node *node, int self) static void show_subnode(struct rb_node *node, int self)
{ {
struct kid_entry *this = rb_entry(node, struct kid_entry, subtree_node); struct kid_entry *this = rb_entry(node, struct kid_entry, subtree_node);
pr_info("\t\t| %x.%x %s\n", this->genid, this->subid, pr_info("\t\t| %x.%x %s\n", this->elem.genid, this->subid,
self ? "(self)" : ""); self ? "(self)" : "");
if (node->rb_left) { if (node->rb_left) {
pr_info("\t\t| left:\n"); pr_info("\t\t| left:\n");
...@@ -112,7 +115,7 @@ static void show_node(struct rb_node *node) ...@@ -112,7 +115,7 @@ static void show_node(struct rb_node *node)
{ {
struct kid_entry *this = rb_entry(node, struct kid_entry, node); struct kid_entry *this = rb_entry(node, struct kid_entry, node);
pr_info("\t%x.%x\n", this->genid, this->subid); pr_info("\t%x.%x\n", this->elem.genid, this->subid);
if (node->rb_left) { if (node->rb_left) {
pr_info("\tleft:\n"); pr_info("\tleft:\n");
show_node(node->rb_left); show_node(node->rb_left);
...@@ -137,7 +140,7 @@ void fd_id_show_tree(void) ...@@ -137,7 +140,7 @@ void fd_id_show_tree(void)
show_node(root->rb_node); show_node(root->rb_node);
} }
static struct kid_entry *alloc_kid_entry(struct kid_tree *tree, pid_t pid, struct fdinfo_entry *fe) static struct kid_entry *alloc_kid_entry(struct kid_tree *tree, struct kid_elem *elem)
{ {
struct kid_entry *e; struct kid_entry *e;
...@@ -146,9 +149,7 @@ static struct kid_entry *alloc_kid_entry(struct kid_tree *tree, pid_t pid, struc ...@@ -146,9 +149,7 @@ static struct kid_entry *alloc_kid_entry(struct kid_tree *tree, pid_t pid, struc
goto err; goto err;
e->subid = tree->subid++; e->subid = tree->subid++;
e->genid = fe->id; e->elem = *elem;
e->pid = pid;
e->fd = fe->fd;
/* Make sure no overflow here */ /* Make sure no overflow here */
BUG_ON(!e->subid); BUG_ON(!e->subid);
...@@ -163,7 +164,7 @@ err: ...@@ -163,7 +164,7 @@ err:
} }
static struct kid_entry *kid_generate_sub(struct kid_tree *tree, struct kid_entry *e, static struct kid_entry *kid_generate_sub(struct kid_tree *tree, struct kid_entry *e,
pid_t pid, struct fdinfo_entry *fe, int *new_id) struct kid_elem *elem, int *new_id)
{ {
struct rb_node *node = e->subtree_root.rb_node; struct rb_node *node = e->subtree_root.rb_node;
struct kid_entry *sub = NULL; struct kid_entry *sub = NULL;
...@@ -175,7 +176,8 @@ static struct kid_entry *kid_generate_sub(struct kid_tree *tree, struct kid_entr ...@@ -175,7 +176,8 @@ static struct kid_entry *kid_generate_sub(struct kid_tree *tree, struct kid_entr
while (node) { while (node) {
struct kid_entry *this = rb_entry(node, struct kid_entry, subtree_node); struct kid_entry *this = rb_entry(node, struct kid_entry, subtree_node);
int ret = sys_kcmp(this->pid, pid, tree->kcmp_type, this->fd, fe->fd); int ret = sys_kcmp(this->elem.pid, elem->pid, tree->kcmp_type,
this->elem.idx, elem->idx);
parent = *new; parent = *new;
if (ret < 0) if (ret < 0)
...@@ -186,7 +188,7 @@ static struct kid_entry *kid_generate_sub(struct kid_tree *tree, struct kid_entr ...@@ -186,7 +188,7 @@ static struct kid_entry *kid_generate_sub(struct kid_tree *tree, struct kid_entr
return this; return this;
} }
sub = alloc_kid_entry(tree, pid, fe); sub = alloc_kid_entry(tree, elem);
if (!sub) if (!sub)
return NULL; return NULL;
...@@ -196,7 +198,7 @@ static struct kid_entry *kid_generate_sub(struct kid_tree *tree, struct kid_entr ...@@ -196,7 +198,7 @@ static struct kid_entry *kid_generate_sub(struct kid_tree *tree, struct kid_entr
} }
static struct kid_entry *kid_generate_gen(struct kid_tree *tree, static struct kid_entry *kid_generate_gen(struct kid_tree *tree,
pid_t pid, struct fdinfo_entry *fe, int *new_id) struct kid_elem *elem, int *new_id)
{ {
struct rb_node *node = tree->root.rb_node; struct rb_node *node = tree->root.rb_node;
struct kid_entry *e = NULL; struct kid_entry *e = NULL;
...@@ -208,15 +210,15 @@ static struct kid_entry *kid_generate_gen(struct kid_tree *tree, ...@@ -208,15 +210,15 @@ static struct kid_entry *kid_generate_gen(struct kid_tree *tree,
struct kid_entry *this = rb_entry(node, struct kid_entry, node); struct kid_entry *this = rb_entry(node, struct kid_entry, node);
parent = *new; parent = *new;
if (fe->id < this->genid) if (elem->genid < this->elem.genid)
node = node->rb_left, new = &((*new)->rb_left); node = node->rb_left, new = &((*new)->rb_left);
else if (fe->id > this->genid) else if (elem->genid > this->elem.genid)
node = node->rb_right, new = &((*new)->rb_right); node = node->rb_right, new = &((*new)->rb_right);
else else
return kid_generate_sub(tree, this, pid, fe, new_id); return kid_generate_sub(tree, this, elem, new_id);
} }
e = alloc_kid_entry(tree, pid, fe); e = alloc_kid_entry(tree, elem);
if (!e) if (!e)
return NULL; return NULL;
...@@ -234,9 +236,14 @@ u32 fd_id_generate_special(void) ...@@ -234,9 +236,14 @@ u32 fd_id_generate_special(void)
int fd_id_generate(pid_t pid, struct fdinfo_entry *fe) int fd_id_generate(pid_t pid, struct fdinfo_entry *fe)
{ {
struct kid_entry *fid; struct kid_entry *fid;
struct kid_elem e;
int new_id = 0; int new_id = 0;
fid = kid_generate_gen(&fd_tree, pid, fe, &new_id); e.pid = pid;
e.genid = fe->id;
e.idx = fe->fd;
fid = kid_generate_gen(&fd_tree, &e, &new_id);
if (!fid) if (!fid)
return -ENOMEM; return -ENOMEM;
......
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