Commit c92c9e23 authored by Pavel Emelyanov's avatar Pavel Emelyanov

file-ids: Enlighten ID generation and storage

The unique id is 32 bit and consists only of the subid value. This
is _really_ enough. The genid part is just a hint for the tree-search
algirythm to avoid unneeded sys_kcmp calls.

Plus, generate IDs for special files. This will make it easier to
move the regfiles into into separate files (see the respective patch
for details).
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 5b44cbd8
...@@ -93,7 +93,7 @@ struct fd_parms { ...@@ -93,7 +93,7 @@ struct fd_parms {
unsigned int flags; unsigned int flags;
unsigned int type; unsigned int type;
u64 id; u32 id;
pid_t pid; pid_t pid;
}; };
...@@ -125,18 +125,11 @@ static int dump_one_reg_file(const struct fd_parms *p, int lfd, ...@@ -125,18 +125,11 @@ static int dump_one_reg_file(const struct fd_parms *p, int lfd,
e.flags = p->flags; e.flags = p->flags;
e.pos = p->pos; e.pos = p->pos;
e.addr = p->fd_name; e.addr = p->fd_name;
e.id = FD_ID_INVALID; e.id = p->id;
if (likely(!fd_is_special(&e))) { ret = fd_id_generate(p->pid, &e);
u64 id; if (ret < 0)
goto err;
id = fd_id_entry_collect(p->id, p->pid, p->fd_name);
if (id < 0)
goto err;
/* Now it might have completely new ID here */
e.id = id;
}
pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8lx addr: %16lx\n", pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8lx addr: %16lx\n",
p->type, len, p->flags, p->pos, p->fd_name); p->type, len, p->flags, p->pos, p->fd_name);
......
...@@ -84,7 +84,7 @@ static void show_files(int fd_files) ...@@ -84,7 +84,7 @@ static void show_files(int fd_files)
goto out; goto out;
pr_msg("type: %s flags: %4x pos: %8x " pr_msg("type: %s flags: %4x pos: %8x "
"addr: %16lx id: %16lx", "addr: %16lx id: %8lx",
fdtype2s(e.type), e.flags, e.pos, e.addr, e.id); fdtype2s(e.type), e.flags, e.pos, e.addr, e.id);
if (e.len) { if (e.len) {
......
...@@ -64,13 +64,8 @@ struct fd_id_entry { ...@@ -64,13 +64,8 @@ struct fd_id_entry {
struct rb_root subtree_root; struct rb_root subtree_root;
struct rb_node subtree_node; struct rb_node subtree_node;
union { u32 genid; /* generic id, may have duplicates */
struct { u32 subid; /* subid is always unique */
u32 genid; /* generic id, may have duplicates */
u32 subid; /* subid is always unique */
} key;
u64 id;
} u;
pid_t pid; pid_t pid;
int fd; int fd;
...@@ -80,7 +75,7 @@ static void show_subnode(struct rb_node *node, int self) ...@@ -80,7 +75,7 @@ static void show_subnode(struct rb_node *node, int self)
{ {
struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, subtree_node); struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, subtree_node);
pr_info("\t\t| %x.%x %s\n", this->u.key.genid, this->u.key.subid, pr_info("\t\t| %x.%x %s\n", this->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");
...@@ -104,7 +99,7 @@ static void show_node(struct rb_node *node) ...@@ -104,7 +99,7 @@ static void show_node(struct rb_node *node)
{ {
struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, node); struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, node);
pr_info("\t%x.%x\n", this->u.key.genid, this->u.key.subid); pr_info("\t%x.%x\n", this->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);
...@@ -133,7 +128,7 @@ void fd_id_show_tree(void) ...@@ -133,7 +128,7 @@ void fd_id_show_tree(void)
static unsigned long fd_id_entries_subid = 1; static unsigned long fd_id_entries_subid = 1;
static struct fd_id_entry *alloc_fd_id_entry(u32 genid, pid_t pid, int fd) static struct fd_id_entry *alloc_fd_id_entry(pid_t pid, struct fdinfo_entry *fe)
{ {
struct fd_id_entry *e; struct fd_id_entry *e;
...@@ -141,13 +136,13 @@ static struct fd_id_entry *alloc_fd_id_entry(u32 genid, pid_t pid, int fd) ...@@ -141,13 +136,13 @@ static struct fd_id_entry *alloc_fd_id_entry(u32 genid, pid_t pid, int fd)
if (!e) if (!e)
goto err; goto err;
e->u.key.subid = fd_id_entries_subid++; e->subid = fd_id_entries_subid++;
e->u.key.genid = genid; e->genid = fe->id;
e->pid = pid; e->pid = pid;
e->fd = fd; e->fd = (int)fe->addr;
/* Make sure no overflow here */ /* Make sure no overflow here */
BUG_ON(!e->u.key.subid); BUG_ON(!e->subid);
rb_init_node(&e->node); rb_init_node(&e->node);
rb_init_node(&e->subtree_node); rb_init_node(&e->subtree_node);
...@@ -158,8 +153,8 @@ err: ...@@ -158,8 +153,8 @@ err:
return e; return e;
} }
static struct fd_id_entry * static struct fd_id_entry *fd_id_generate_sub(struct fd_id_entry *e,
lookup_alloc_subtree(struct fd_id_entry *e, u32 genid, pid_t pid, int fd) pid_t pid, struct fdinfo_entry *fe)
{ {
struct rb_node *node = e->subtree_root.rb_node; struct rb_node *node = e->subtree_root.rb_node;
struct fd_id_entry *sub = NULL; struct fd_id_entry *sub = NULL;
...@@ -171,7 +166,7 @@ lookup_alloc_subtree(struct fd_id_entry *e, u32 genid, pid_t pid, int fd) ...@@ -171,7 +166,7 @@ lookup_alloc_subtree(struct fd_id_entry *e, u32 genid, pid_t pid, int fd)
while (node) { while (node) {
struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, subtree_node); struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, subtree_node);
int ret = sys_kcmp(this->pid, pid, KCMP_FILE, this->fd, fd); int ret = sys_kcmp(this->pid, pid, KCMP_FILE, this->fd, (int)fe->addr);
parent = *new; parent = *new;
if (ret < 0) if (ret < 0)
...@@ -182,16 +177,15 @@ lookup_alloc_subtree(struct fd_id_entry *e, u32 genid, pid_t pid, int fd) ...@@ -182,16 +177,15 @@ lookup_alloc_subtree(struct fd_id_entry *e, u32 genid, pid_t pid, int fd)
return this; return this;
} }
sub = alloc_fd_id_entry(genid, pid, fd); sub = alloc_fd_id_entry(pid, fe);
if (!sub) if (!sub)
goto err; return NULL;
rb_link_and_balance(&e->subtree_root, &sub->subtree_node, parent, new); rb_link_and_balance(&e->subtree_root, &sub->subtree_node, parent, new);
err:
return sub; return sub;
} }
static struct fd_id_entry *lookup_alloc_node(u32 genid, pid_t pid, int fd) static struct fd_id_entry *fd_id_generate_gen(pid_t pid, struct fdinfo_entry *fe)
{ {
struct rb_node *node = fd_id_root.rb_node; struct rb_node *node = fd_id_root.rb_node;
struct fd_id_entry *e = NULL; struct fd_id_entry *e = NULL;
...@@ -203,31 +197,36 @@ static struct fd_id_entry *lookup_alloc_node(u32 genid, pid_t pid, int fd) ...@@ -203,31 +197,36 @@ static struct fd_id_entry *lookup_alloc_node(u32 genid, pid_t pid, int fd)
struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, node); struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, node);
parent = *new; parent = *new;
if (genid < this->u.key.genid) if (fe->id < this->genid)
node = node->rb_left, new = &((*new)->rb_left); node = node->rb_left, new = &((*new)->rb_left);
else if (genid > this->u.key.genid) else if (fe->id > this->genid)
node = node->rb_right, new = &((*new)->rb_right); node = node->rb_right, new = &((*new)->rb_right);
else else
return lookup_alloc_subtree(this, genid, pid, fd); return fd_id_generate_sub(this, pid, fe);
} }
e = alloc_fd_id_entry(genid, pid, fd); e = alloc_fd_id_entry(pid, fe);
if (!e) if (!e)
goto err; return NULL;
rb_link_and_balance(&fd_id_root, &e->node, parent, new); rb_link_and_balance(&fd_id_root, &e->node, parent, new);
err:
return e; return e;
} }
long fd_id_entry_collect(u32 genid, pid_t pid, int fd) int fd_id_generate(pid_t pid, struct fdinfo_entry *fe)
{ {
struct fd_id_entry *e = NULL; struct fd_id_entry *fid;
if (fd_is_special(fe)) {
fe->id = fd_id_entries_subid++;
return 0;
}
e = lookup_alloc_node(genid, pid, fd); fid = fd_id_generate_gen(pid, fe);
if (e == NULL) if (!fid)
return -ENOMEM; return -ENOMEM;
return e->u.id; fe->id = fid->subid;
return 0;
} }
...@@ -5,13 +5,14 @@ ...@@ -5,13 +5,14 @@
#include "types.h" #include "types.h"
#include "rbtree.h" #include "rbtree.h"
#define FD_ID_INVALID (-1UL) #define FD_ID_INVALID (-1U)
#define FD_PID_INVALID ((int)-2UL) #define FD_PID_INVALID (-2U)
#define MAKE_FD_GENID(dev, ino, pos) \ #define MAKE_FD_GENID(dev, ino, pos) \
(((u32)(dev) ^ (u32)(ino) ^ (u32)(pos))) (((u32)(dev) ^ (u32)(ino) ^ (u32)(pos)))
extern long fd_id_entry_collect(u32 genid, pid_t pid, int fd); struct fdinfo_entry;
extern int fd_id_generate(pid_t pid, struct fdinfo_entry *fe);
extern void fd_id_show_tree(void); extern void fd_id_show_tree(void);
#endif /* FILE_IDS_H__ */ #endif /* FILE_IDS_H__ */
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