|
@@ -268,9 +268,8 @@ err_free_blkg:
|
|
|
* that all non-root blkg's have access to the parent blkg. This function
|
|
|
* should be called under RCU read lock and @q->queue_lock.
|
|
|
*
|
|
|
- * Returns pointer to the looked up or created blkg on success, ERR_PTR()
|
|
|
- * value on error. If @q is dead, returns ERR_PTR(-EINVAL). If @q is not
|
|
|
- * dead and bypassing, returns ERR_PTR(-EBUSY).
|
|
|
+ * Returns the blkg or the closest blkg if blkg_create fails as it walks
|
|
|
+ * down from root.
|
|
|
*/
|
|
|
struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
|
|
|
struct request_queue *q)
|
|
@@ -285,7 +284,7 @@ struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
|
|
|
* we shouldn't allow anything to go through for a bypassing queue.
|
|
|
*/
|
|
|
if (unlikely(blk_queue_bypass(q)))
|
|
|
- return ERR_PTR(blk_queue_dying(q) ? -ENODEV : -EBUSY);
|
|
|
+ return q->root_blkg;
|
|
|
|
|
|
blkg = __blkg_lookup(blkcg, q, true);
|
|
|
if (blkg)
|
|
@@ -293,19 +292,29 @@ struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
|
|
|
|
|
|
/*
|
|
|
* Create blkgs walking down from blkcg_root to @blkcg, so that all
|
|
|
- * non-root blkgs have access to their parents.
|
|
|
+ * non-root blkgs have access to their parents. Returns the closest
|
|
|
+ * blkg to the intended blkg should blkg_create() fail.
|
|
|
*/
|
|
|
while (true) {
|
|
|
struct blkcg *pos = blkcg;
|
|
|
struct blkcg *parent = blkcg_parent(blkcg);
|
|
|
-
|
|
|
- while (parent && !__blkg_lookup(parent, q, false)) {
|
|
|
+ struct blkcg_gq *ret_blkg = q->root_blkg;
|
|
|
+
|
|
|
+ while (parent) {
|
|
|
+ blkg = __blkg_lookup(parent, q, false);
|
|
|
+ if (blkg) {
|
|
|
+ /* remember closest blkg */
|
|
|
+ ret_blkg = blkg;
|
|
|
+ break;
|
|
|
+ }
|
|
|
pos = parent;
|
|
|
parent = blkcg_parent(parent);
|
|
|
}
|
|
|
|
|
|
blkg = blkg_create(pos, q, NULL);
|
|
|
- if (pos == blkcg || IS_ERR(blkg))
|
|
|
+ if (IS_ERR(blkg))
|
|
|
+ return ret_blkg;
|
|
|
+ if (pos == blkcg)
|
|
|
return blkg;
|
|
|
}
|
|
|
}
|