进程创建时IO处理

来源:互联网 发布:手机淘宝领取优惠券 编辑:程序博客网 时间:2024/05/16 08:02
 

static int copy_io(unsigned long clone_flags, struct task_struct *tsk){#ifdef CONFIG_BLOCK struct io_context *ioc = current->io_context; struct io_context *new_ioc;

 if (!ioc)  return 0; /*  * Share io context with parent, if CLONE_IO is set  */ if (clone_flags & CLONE_IO) {  ioc_task_link(ioc);  tsk->io_context = ioc; } else if (ioprio_valid(ioc->ioprio)) {  new_ioc = get_task_io_context(tsk, GFP_KERNEL, NUMA_NO_NODE);  if (unlikely(!new_ioc))   return -ENOMEM;

  new_ioc->ioprio = ioc->ioprio;  put_io_context(new_ioc); }#endif return 0;}

/** * get_task_io_context - get io_context of a task * @task: task of interest * @gfp_flags: allocation flags, used if allocation is necessary * @node: allocation node, used if allocation is necessary * * Return io_context of @task.  If it doesn't exist, it is created with * @gfp_flags and @node.  The returned io_context has its reference count * incremented. * * This function always goes through task_lock() and it's better to use * %current->io_context + get_io_context() for %current. */struct io_context *get_task_io_context(struct task_struct *task,           gfp_t gfp_flags, int node){ struct io_context *ioc;

 might_sleep_if(gfpflags_allow_blocking(gfp_flags));

 do {  task_lock(task);  ioc = task->io_context;  if (likely(ioc)) {   get_io_context(ioc);   task_unlock(task);   return ioc;  }  task_unlock(task); } while (!create_task_io_context(task, gfp_flags, node));

 return NULL;}

int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node){ struct io_context *ioc; int ret;

 ioc = kmem_cache_alloc_node(iocontext_cachep, gfp_flags | __GFP_ZERO,        node); if (unlikely(!ioc))  return -ENOMEM;

 /* initialize */ atomic_long_set(&ioc->refcount, 1); atomic_set(&ioc->nr_tasks, 1); atomic_set(&ioc->active_ref, 1); spin_lock_init(&ioc->lock); INIT_RADIX_TREE(&ioc->icq_tree, GFP_ATOMIC | __GFP_HIGH); INIT_HLIST_HEAD(&ioc->icq_list); INIT_WORK(&ioc->release_work, ioc_release_fn);

 /*  * Try to install.  ioc shouldn't be installed if someone else  * already did or @task, which isn't %current, is exiting.  Note  * that we need to allow ioc creation on exiting %current as exit  * path may issue IOs from e.g. exit_files().  The exit path is  * responsible for not issuing IO after exit_io_context().  */ task_lock(task); if (!task->io_context &&     (task == current || !(task->flags & PF_EXITING)))  task->io_context = ioc; else  kmem_cache_free(iocontext_cachep, ioc);

 ret = task->io_context ? 0 : -EBUSY;

 task_unlock(task);

 return ret;}

 
0 0
原创粉丝点击