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 | } |
