-restart:
- if ((cic = ioc->cic) == NULL) {
- cic = cfq_alloc_io_context(cfqd, gfp_mask);
-
- if (cic == NULL)
- goto err;
-
- /*
- * manually increment generic io_context usage count, it
- * cannot go away since we are already holding one ref to it
- */
- cic->ioc = ioc;
- cic->key = cfqd;
- read_lock(&cfq_exit_lock);
- ioc->set_ioprio = cfq_ioc_set_ioprio;
- ioc->cic = cic;
- list_add(&cic->queue_list, &cfqd->cic_list);
- read_unlock(&cfq_exit_lock);
- } else {
- struct cfq_io_context *__cic;
-
- /*
- * the first cic on the list is actually the head itself
- */
- if (cic->key == cfqd)
- goto out;
-
- if (unlikely(!cic->key)) {
- read_lock(&cfq_exit_lock);
- if (list_empty(&cic->list))
- ioc->cic = NULL;
- else
- ioc->cic = list_entry(cic->list.next,
- struct cfq_io_context,
- list);
- read_unlock(&cfq_exit_lock);
- kmem_cache_free(cfq_ioc_pool, cic);
- atomic_dec(&ioc_count);
- goto restart;
- }
-
- /*
- * cic exists, check if we already are there. linear search
- * should be ok here, the list will usually not be more than
- * 1 or a few entries long
- */
- list_for_each_entry(__cic, &cic->list, list) {
- /*
- * this process is already holding a reference to
- * this queue, so no need to get one more
- */
- if (__cic->key == cfqd) {
- cic = __cic;
- goto out;
- }
- if (unlikely(!__cic->key)) {
- read_lock(&cfq_exit_lock);
- list_del(&__cic->list);
- read_unlock(&cfq_exit_lock);
- kmem_cache_free(cfq_ioc_pool, __cic);
- atomic_dec(&ioc_count);
- goto restart;
- }
- }