diff options
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r-- | block/cfq-iosched.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 16ace89613bc..4c12869fcf77 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -3184,7 +3184,7 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, | |||
3184 | } | 3184 | } |
3185 | } | 3185 | } |
3186 | 3186 | ||
3187 | if (ret) | 3187 | if (ret && ret != -EEXIST) |
3188 | printk(KERN_ERR "cfq: cic link failed!\n"); | 3188 | printk(KERN_ERR "cfq: cic link failed!\n"); |
3189 | 3189 | ||
3190 | return ret; | 3190 | return ret; |
@@ -3200,6 +3200,7 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) | |||
3200 | { | 3200 | { |
3201 | struct io_context *ioc = NULL; | 3201 | struct io_context *ioc = NULL; |
3202 | struct cfq_io_context *cic; | 3202 | struct cfq_io_context *cic; |
3203 | int ret; | ||
3203 | 3204 | ||
3204 | might_sleep_if(gfp_mask & __GFP_WAIT); | 3205 | might_sleep_if(gfp_mask & __GFP_WAIT); |
3205 | 3206 | ||
@@ -3207,6 +3208,7 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) | |||
3207 | if (!ioc) | 3208 | if (!ioc) |
3208 | return NULL; | 3209 | return NULL; |
3209 | 3210 | ||
3211 | retry: | ||
3210 | cic = cfq_cic_lookup(cfqd, ioc); | 3212 | cic = cfq_cic_lookup(cfqd, ioc); |
3211 | if (cic) | 3213 | if (cic) |
3212 | goto out; | 3214 | goto out; |
@@ -3215,7 +3217,12 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) | |||
3215 | if (cic == NULL) | 3217 | if (cic == NULL) |
3216 | goto err; | 3218 | goto err; |
3217 | 3219 | ||
3218 | if (cfq_cic_link(cfqd, ioc, cic, gfp_mask)) | 3220 | ret = cfq_cic_link(cfqd, ioc, cic, gfp_mask); |
3221 | if (ret == -EEXIST) { | ||
3222 | /* someone has linked cic to ioc already */ | ||
3223 | cfq_cic_free(cic); | ||
3224 | goto retry; | ||
3225 | } else if (ret) | ||
3219 | goto err_free; | 3226 | goto err_free; |
3220 | 3227 | ||
3221 | out: | 3228 | out: |
@@ -4036,6 +4043,11 @@ static void *cfq_init_queue(struct request_queue *q) | |||
4036 | 4043 | ||
4037 | if (blkio_alloc_blkg_stats(&cfqg->blkg)) { | 4044 | if (blkio_alloc_blkg_stats(&cfqg->blkg)) { |
4038 | kfree(cfqg); | 4045 | kfree(cfqg); |
4046 | |||
4047 | spin_lock(&cic_index_lock); | ||
4048 | ida_remove(&cic_index_ida, cfqd->cic_index); | ||
4049 | spin_unlock(&cic_index_lock); | ||
4050 | |||
4039 | kfree(cfqd); | 4051 | kfree(cfqd); |
4040 | return NULL; | 4052 | return NULL; |
4041 | } | 4053 | } |