Commit 67bd254a authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Andrei Vagin

epoll: Add kid_lookup_epoll_tfd helper

To find target files with help of our collected
rbtree.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent d026ba1c
......@@ -19,7 +19,7 @@
#include "irmap.h"
#include "files.h"
static DECLARE_KCMP_TREE(fd_tree, KCMP_FILE);
DECLARE_KCMP_TREE(fd_tree, KCMP_FILE);
#define FDID_BITS 5
#define FDID_SIZE (1 << FDID_BITS)
......
......@@ -16,4 +16,6 @@ struct fd_parms;
extern int fd_id_generate(pid_t pid, FdinfoEntry *fe, struct fd_parms *p);
extern int fd_id_generate_special(struct fd_parms *p, u32 *id);
extern struct kid_tree fd_tree;
#endif /* __CR_FILE_IDS_H__ */
......@@ -29,4 +29,8 @@ struct kid_elem {
extern uint32_t kid_generate_gen(struct kid_tree *tree,
struct kid_elem *elem, int *new_id);
extern struct kid_elem *kid_lookup_epoll_tfd(struct kid_tree *tree,
struct kid_elem *elem,
kcmp_epoll_slot_t *slot);
#endif /* __CR_KCMP_IDS_H__ */
......@@ -152,5 +152,57 @@ uint32_t kid_generate_gen(struct kid_tree *tree,
rb_link_and_balance(&tree->root, &e->node, parent, new);
*new_id = 1;
return e->subid;
}
static struct kid_elem *kid_lookup_epoll_tfd_sub(struct kid_tree *tree,
struct kid_entry *e,
struct kid_elem *elem,
kcmp_epoll_slot_t *slot)
{
struct rb_node *node = e->subtree_root.rb_node;
struct rb_node **new = &e->subtree_root.rb_node;
BUG_ON(!node);
while (node) {
struct kid_entry *this = rb_entry(node, struct kid_entry, subtree_node);
int ret = syscall(SYS_kcmp, this->elem.pid, elem->pid, KCMP_EPOLL_TFD,
this->elem.idx, slot);
if (ret == 1)
node = node->rb_left, new = &((*new)->rb_left);
else if (ret == 2)
node = node->rb_right, new = &((*new)->rb_right);
else if (ret == 0)
return &this->elem;
else {
pr_perror("kcmp-epoll failed: pid (%d %d) type %u idx (%u %u)",
this->elem.pid, elem->pid, KCMP_EPOLL_TFD,
this->elem.idx, elem->idx);
return NULL;
}
}
return NULL;
}
struct kid_elem *kid_lookup_epoll_tfd(struct kid_tree *tree,
struct kid_elem *elem,
kcmp_epoll_slot_t *slot)
{
struct rb_node *node = tree->root.rb_node;
struct rb_node **new = &tree->root.rb_node;
while (node) {
struct kid_entry *this = rb_entry(node, struct kid_entry, node);
if (elem->genid < this->elem.genid)
node = node->rb_left, new = &((*new)->rb_left);
else if (elem->genid > this->elem.genid)
node = node->rb_right, new = &((*new)->rb_right);
else
return kid_lookup_epoll_tfd_sub(tree, this, elem, slot);
}
return NULL;
}
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