Commit 7e12d2dd authored by Stanislav Kinsburskiy's avatar Stanislav Kinsburskiy Committed by Pavel Emelyanov

files: new "used" files list introduced

This list contains all per-process used file fdinfo's, sorted by fd number.
Will be used to safely create new artificial file descriptors and also allow
to recreate temporary descriptors with original number, if possible, like
AutoFS tries to preserve original pipe write end descriptor, when it was
closed.
This patch also adds a couple of simple helpers to find unused file
descriptor:
1) fd_is_used() does exactly what it is named
2) find_unused_fd() returns "hint_fd" if unused or last used descriptor plus
one.
Signed-off-by: 's avatarStanislav Kinsburskiy <skinsbursky@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 2429f08b
...@@ -653,6 +653,8 @@ static int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info) ...@@ -653,6 +653,8 @@ static int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info)
else else
collect_gen_fd(new_le, rst_info); collect_gen_fd(new_le, rst_info);
collect_used_fd(new_le, rst_info);
list_add_tail(&new_le->desc_list, &le->desc_list); list_add_tail(&new_le->desc_list, &le->desc_list);
new_le->desc = fdesc; new_le->desc = fdesc;
...@@ -693,6 +695,7 @@ int prepare_fd_pid(struct pstree_item *item) ...@@ -693,6 +695,7 @@ int prepare_fd_pid(struct pstree_item *item)
pid_t pid = item->pid.virt; pid_t pid = item->pid.virt;
struct rst_info *rst_info = rsti(item); struct rst_info *rst_info = rsti(item);
INIT_LIST_HEAD(&rst_info->used);
INIT_LIST_HEAD(&rst_info->fds); INIT_LIST_HEAD(&rst_info->fds);
INIT_LIST_HEAD(&rst_info->eventpoll); INIT_LIST_HEAD(&rst_info->eventpoll);
INIT_LIST_HEAD(&rst_info->tty_slaves); INIT_LIST_HEAD(&rst_info->tty_slaves);
......
...@@ -66,6 +66,7 @@ struct fdinfo_list_entry { ...@@ -66,6 +66,7 @@ struct fdinfo_list_entry {
struct list_head desc_list; /* To chain on @fd_info_head */ struct list_head desc_list; /* To chain on @fd_info_head */
struct file_desc *desc; /* Associated file descriptor */ struct file_desc *desc; /* Associated file descriptor */
struct list_head ps_list; /* To chain per-task files */ struct list_head ps_list; /* To chain per-task files */
struct list_head used_list; /* To chain per-task used fds */
int pid; int pid;
futex_t real_pid; futex_t real_pid;
FdinfoEntry *fe; FdinfoEntry *fe;
...@@ -107,11 +108,43 @@ struct file_desc_ops { ...@@ -107,11 +108,43 @@ struct file_desc_ops {
char * (*name)(struct file_desc *, char *b, size_t s); char * (*name)(struct file_desc *, char *b, size_t s);
}; };
static inline void collect_used_fd(struct fdinfo_list_entry *new_fle, struct rst_info *ri)
{
struct fdinfo_list_entry *fle;
list_for_each_entry(fle, &ri->used, used_list) {
if (new_fle->fe->fd < fle->fe->fd)
break;
}
list_add_tail(&new_fle->used_list, &fle->used_list);
}
static inline void collect_gen_fd(struct fdinfo_list_entry *fle, struct rst_info *ri) static inline void collect_gen_fd(struct fdinfo_list_entry *fle, struct rst_info *ri)
{ {
list_add_tail(&fle->ps_list, &ri->fds); list_add_tail(&fle->ps_list, &ri->fds);
} }
static inline bool fd_is_used(struct list_head *head, int fd)
{
struct fdinfo_list_entry *fle;
list_for_each_entry(fle, head, used_list) {
if (fle->fe->fd == fd)
return true;
}
return false;
}
static inline unsigned int find_unused_fd(struct list_head *head, int hint_fd)
{
if ((hint_fd >= 0) && (!fd_is_used(head, hint_fd)))
return hint_fd;
/* Return last used fd +1 */
return list_entry(head->prev, typeof(struct fdinfo_list_entry), used_list)->fe->fd + 1;
}
struct file_desc { struct file_desc {
u32 id; /* File id, unique */ u32 id; /* File id, unique */
struct hlist_node hash; /* Descriptor hashing and lookup */ struct hlist_node hash; /* Descriptor hashing and lookup */
......
...@@ -27,6 +27,7 @@ struct fdt { ...@@ -27,6 +27,7 @@ struct fdt {
struct _MmEntry; struct _MmEntry;
struct rst_info { struct rst_info {
struct list_head used;
struct list_head fds; struct list_head fds;
struct list_head eventpoll; struct list_head eventpoll;
struct list_head tty_slaves; struct list_head tty_slaves;
......
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