diff options
author | Bart Van Assche <bart.vanassche@sandisk.com> | 2017-04-26 13:47:51 -0700 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-04-26 15:09:04 -0600 |
commit | f05d1ba7871a2c20ca9ebb303aac89c9296d1f58 (patch) | |
tree | 3b501e9c6fff0d4888c7c82ab5d6b674d4188af0 /block | |
parent | 62d6c9496a2bded5262ac9f675b27facb3cd4ce8 (diff) |
blk-mq: Only unregister hctxs for which registration succeeded
Hctx unregistration involves calling kobject_del(). kobject_del()
must not be called if kobject_add() has not been called. Hence in
the error path only unregister hctxs for which registration succeeded.
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Hannes Reinecke <hare@suse.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-mq-sysfs.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c index c2cac20d981d..ec0afdf765e3 100644 --- a/block/blk-mq-sysfs.c +++ b/block/blk-mq-sysfs.c @@ -323,16 +323,24 @@ int __blk_mq_register_dev(struct device *dev, struct request_queue *q) queue_for_each_hw_ctx(q, hctx, i) { ret = blk_mq_register_hctx(hctx); if (ret) - break; + goto unreg; } - if (ret) - __blk_mq_unregister_dev(dev, q); - else - q->mq_sysfs_init_done = true; + q->mq_sysfs_init_done = true; out: return ret; + +unreg: + while (--i >= 0) + blk_mq_unregister_hctx(q->queue_hw_ctx[i]); + + blk_mq_debugfs_unregister_mq(q); + + kobject_uevent(&q->mq_kobj, KOBJ_REMOVE); + kobject_del(&q->mq_kobj); + kobject_put(&dev->kobj); + return ret; } int blk_mq_register_dev(struct device *dev, struct request_queue *q) |