fork: add kernel_clone_args flag to not dup/clone files
Each vhost device gets a thread that is used to perform IO and management operations. Instead of a thread that is accessing a device, the thread is part of the device, so when it creates a thread using a helper based on copy_process we can't dup or clone the parent's files/FDS because it would do an extra increment on ourself. Later, when we do: Qemu process exits: do_exit -> exit_files -> put_files_struct -> close_files we would leak the device's resources because of that extra refcount on the fd or file_struct. This patch adds a no_files option so these worker threads can prevent taking an extra refcount on themselves. Signed-off-by: Mike Christie <michael.christie@oracle.com> Acked-by: Christian Brauner <brauner@kernel.org> Acked-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
This commit is contained in:
parent
54e6842d07
commit
11f3f500ec
@ -28,6 +28,7 @@ struct kernel_clone_args {
|
||||
u32 kthread:1;
|
||||
u32 io_thread:1;
|
||||
u32 user_worker:1;
|
||||
u32 no_files:1;
|
||||
unsigned long stack;
|
||||
unsigned long stack_size;
|
||||
unsigned long tls;
|
||||
|
@ -1627,7 +1627,8 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int copy_files(unsigned long clone_flags, struct task_struct *tsk)
|
||||
static int copy_files(unsigned long clone_flags, struct task_struct *tsk,
|
||||
int no_files)
|
||||
{
|
||||
struct files_struct *oldf, *newf;
|
||||
int error = 0;
|
||||
@ -1639,6 +1640,11 @@ static int copy_files(unsigned long clone_flags, struct task_struct *tsk)
|
||||
if (!oldf)
|
||||
goto out;
|
||||
|
||||
if (no_files) {
|
||||
tsk->files = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (clone_flags & CLONE_FILES) {
|
||||
atomic_inc(&oldf->count);
|
||||
goto out;
|
||||
@ -2259,7 +2265,7 @@ static __latent_entropy struct task_struct *copy_process(
|
||||
retval = copy_semundo(clone_flags, p);
|
||||
if (retval)
|
||||
goto bad_fork_cleanup_security;
|
||||
retval = copy_files(clone_flags, p);
|
||||
retval = copy_files(clone_flags, p, args->no_files);
|
||||
if (retval)
|
||||
goto bad_fork_cleanup_semundo;
|
||||
retval = copy_fs(clone_flags, p);
|
||||
|
Loading…
Reference in New Issue
Block a user