aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 39d22b3357de..2a86c9dff744 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -51,6 +51,7 @@
51#include <linux/random.h> 51#include <linux/random.h>
52#include <linux/tty.h> 52#include <linux/tty.h>
53#include <linux/proc_fs.h> 53#include <linux/proc_fs.h>
54#include <linux/blkdev.h>
54 55
55#include <asm/pgtable.h> 56#include <asm/pgtable.h>
56#include <asm/pgalloc.h> 57#include <asm/pgalloc.h>
@@ -791,6 +792,26 @@ out:
791 return error; 792 return error;
792} 793}
793 794
795static int copy_io(struct task_struct *tsk)
796{
797#ifdef CONFIG_BLOCK
798 struct io_context *ioc = current->io_context;
799
800 if (!ioc)
801 return 0;
802
803 if (ioprio_valid(ioc->ioprio)) {
804 tsk->io_context = alloc_io_context(GFP_KERNEL, -1);
805 if (unlikely(!tsk->io_context))
806 return -ENOMEM;
807
808 tsk->io_context->task = tsk;
809 tsk->io_context->ioprio = ioc->ioprio;
810 }
811#endif
812 return 0;
813}
814
794/* 815/*
795 * Helper to unshare the files of the current task. 816 * Helper to unshare the files of the current task.
796 * We don't want to expose copy_files internals to 817 * We don't want to expose copy_files internals to
@@ -1156,15 +1177,17 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1156 goto bad_fork_cleanup_mm; 1177 goto bad_fork_cleanup_mm;
1157 if ((retval = copy_namespaces(clone_flags, p))) 1178 if ((retval = copy_namespaces(clone_flags, p)))
1158 goto bad_fork_cleanup_keys; 1179 goto bad_fork_cleanup_keys;
1180 if ((retval = copy_io(p)))
1181 goto bad_fork_cleanup_namespaces;
1159 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); 1182 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
1160 if (retval) 1183 if (retval)
1161 goto bad_fork_cleanup_namespaces; 1184 goto bad_fork_cleanup_io;
1162 1185
1163 if (pid != &init_struct_pid) { 1186 if (pid != &init_struct_pid) {
1164 retval = -ENOMEM; 1187 retval = -ENOMEM;
1165 pid = alloc_pid(task_active_pid_ns(p)); 1188 pid = alloc_pid(task_active_pid_ns(p));
1166 if (!pid) 1189 if (!pid)
1167 goto bad_fork_cleanup_namespaces; 1190 goto bad_fork_cleanup_io;
1168 1191
1169 if (clone_flags & CLONE_NEWPID) { 1192 if (clone_flags & CLONE_NEWPID) {
1170 retval = pid_ns_prepare_proc(task_active_pid_ns(p)); 1193 retval = pid_ns_prepare_proc(task_active_pid_ns(p));
@@ -1234,9 +1257,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1234 /* Need tasklist lock for parent etc handling! */ 1257 /* Need tasklist lock for parent etc handling! */
1235 write_lock_irq(&tasklist_lock); 1258 write_lock_irq(&tasklist_lock);
1236 1259
1237 /* for sys_ioprio_set(IOPRIO_WHO_PGRP) */
1238 p->ioprio = current->ioprio;
1239
1240 /* 1260 /*
1241 * The task hasn't been attached yet, so its cpus_allowed mask will 1261 * The task hasn't been attached yet, so its cpus_allowed mask will
1242 * not be changed, nor will its assigned CPU. 1262 * not be changed, nor will its assigned CPU.
@@ -1328,6 +1348,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1328bad_fork_free_pid: 1348bad_fork_free_pid:
1329 if (pid != &init_struct_pid) 1349 if (pid != &init_struct_pid)
1330 free_pid(pid); 1350 free_pid(pid);
1351bad_fork_cleanup_io:
1352 put_io_context(p->io_context);
1331bad_fork_cleanup_namespaces: 1353bad_fork_cleanup_namespaces:
1332 exit_task_namespaces(p); 1354 exit_task_namespaces(p);
1333bad_fork_cleanup_keys: 1355bad_fork_cleanup_keys: