|
@@ -3184,7 +3184,7 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (ret)
|
|
|
+ if (ret && ret != -EEXIST)
|
|
|
printk(KERN_ERR "cfq: cic link failed!\n");
|
|
|
|
|
|
return ret;
|
|
@@ -3200,6 +3200,7 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
|
|
|
{
|
|
|
struct io_context *ioc = NULL;
|
|
|
struct cfq_io_context *cic;
|
|
|
+ int ret;
|
|
|
|
|
|
might_sleep_if(gfp_mask & __GFP_WAIT);
|
|
|
|
|
@@ -3207,6 +3208,7 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
|
|
|
if (!ioc)
|
|
|
return NULL;
|
|
|
|
|
|
+retry:
|
|
|
cic = cfq_cic_lookup(cfqd, ioc);
|
|
|
if (cic)
|
|
|
goto out;
|
|
@@ -3215,7 +3217,12 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
|
|
|
if (cic == NULL)
|
|
|
goto err;
|
|
|
|
|
|
- if (cfq_cic_link(cfqd, ioc, cic, gfp_mask))
|
|
|
+ ret = cfq_cic_link(cfqd, ioc, cic, gfp_mask);
|
|
|
+ if (ret == -EEXIST) {
|
|
|
+ /* someone has linked cic to ioc already */
|
|
|
+ cfq_cic_free(cic);
|
|
|
+ goto retry;
|
|
|
+ } else if (ret)
|
|
|
goto err_free;
|
|
|
|
|
|
out:
|