|
@@ -2028,6 +2028,41 @@ int bio_associate_blkg(struct bio *bio, struct blkcg_gq *blkg)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * bio_associate_create_blkg - associate a bio with a blkg from q
|
|
|
+ * @q: request_queue where bio is going
|
|
|
+ * @bio: target bio
|
|
|
+ *
|
|
|
+ * Associate @bio with the blkg found from the bio's css and the request_queue.
|
|
|
+ * If one is not found, bio_lookup_blkg creates the blkg.
|
|
|
+ */
|
|
|
+int bio_associate_create_blkg(struct request_queue *q, struct bio *bio)
|
|
|
+{
|
|
|
+ struct blkcg *blkcg;
|
|
|
+ struct blkcg_gq *blkg;
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ /* someone has already associated this bio with a blkg */
|
|
|
+ if (bio->bi_blkg)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+
|
|
|
+ bio_associate_blkcg(bio, NULL);
|
|
|
+ blkcg = bio_blkcg(bio);
|
|
|
+
|
|
|
+ if (!blkcg->css.parent) {
|
|
|
+ ret = bio_associate_blkg(bio, q->root_blkg);
|
|
|
+ } else {
|
|
|
+ blkg = blkg_lookup_create(blkcg, q);
|
|
|
+
|
|
|
+ ret = bio_associate_blkg(bio, blkg);
|
|
|
+ }
|
|
|
+
|
|
|
+ rcu_read_unlock();
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* bio_disassociate_task - undo bio_associate_current()
|
|
|
* @bio: target bio
|
|
@@ -2057,6 +2092,9 @@ void bio_clone_blkcg_association(struct bio *dst, struct bio *src)
|
|
|
{
|
|
|
if (src->bi_css)
|
|
|
WARN_ON(bio_associate_blkcg(dst, src->bi_css));
|
|
|
+
|
|
|
+ if (src->bi_blkg)
|
|
|
+ bio_associate_blkg(dst, src->bi_blkg);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(bio_clone_blkcg_association);
|
|
|
#endif /* CONFIG_BLK_CGROUP */
|