blk-cgroup: synchronize blkg creation against policy deactivation
[sfrench/cifs-2.6.git] / block / blk-cgroup.c
index 8908298d6ad3f1ea4b04ac6b9f0ab9ad3d4c94d1..88b1fce905200c1f2897598298733d7a0699aa9c 100644 (file)
@@ -634,6 +634,14 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
 
        q = bdev_get_queue(bdev);
 
 
        q = bdev_get_queue(bdev);
 
+       /*
+        * blkcg_deactivate_policy() requires queue to be frozen, we can grab
+        * q_usage_counter to prevent concurrent with blkcg_deactivate_policy().
+        */
+       ret = blk_queue_enter(q, 0);
+       if (ret)
+               return ret;
+
        rcu_read_lock();
        spin_lock_irq(&q->queue_lock);
 
        rcu_read_lock();
        spin_lock_irq(&q->queue_lock);
 
@@ -703,6 +711,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
                        goto success;
        }
 success:
                        goto success;
        }
 success:
+       blk_queue_exit(q);
        ctx->bdev = bdev;
        ctx->blkg = blkg;
        ctx->body = input;
        ctx->bdev = bdev;
        ctx->blkg = blkg;
        ctx->body = input;
@@ -715,6 +724,7 @@ fail_unlock:
        rcu_read_unlock();
 fail:
        blkdev_put_no_open(bdev);
        rcu_read_unlock();
 fail:
        blkdev_put_no_open(bdev);
+       blk_queue_exit(q);
        /*
         * If queue was bypassing, we should retry.  Do so after a
         * short msleep().  It isn't strictly necessary but queue
        /*
         * If queue was bypassing, we should retry.  Do so after a
         * short msleep().  It isn't strictly necessary but queue