block: fine-granular CAP_SYS_ADMIN for Persistent Reservation
[platform/kernel/linux-starfive.git] / block / blk-cgroup.c
index ff45649..cab33bd 100644 (file)
@@ -567,6 +567,9 @@ restart:
        list_for_each_entry_safe(blkg, n, &q->blkg_list, q_node) {
                struct blkcg *blkcg = blkg->blkcg;
 
+               if (hlist_unhashed(&blkg->blkcg_node))
+                       continue;
+
                spin_lock(&blkcg->lock);
                blkg_destroy(blkg);
                spin_unlock(&blkcg->lock);
@@ -607,8 +610,13 @@ static int blkcg_reset_stats(struct cgroup_subsys_state *css,
                        struct blkg_iostat_set *bis =
                                per_cpu_ptr(blkg->iostat_cpu, cpu);
                        memset(bis, 0, sizeof(*bis));
+
+                       /* Re-initialize the cleared blkg_iostat_set */
+                       u64_stats_init(&bis->sync);
+                       bis->blkg = blkg;
                }
                memset(&blkg->iostat, 0, sizeof(blkg->iostat));
+               u64_stats_init(&blkg->iostat.sync);
 
                for (i = 0; i < BLKCG_MAX_POLS; i++) {
                        struct blkcg_policy *pol = blkcg_policy[i];
@@ -745,6 +753,13 @@ int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx)
                return -ENODEV;
        }
 
+       mutex_lock(&bdev->bd_queue->rq_qos_mutex);
+       if (!disk_live(bdev->bd_disk)) {
+               blkdev_put_no_open(bdev);
+               mutex_unlock(&bdev->bd_queue->rq_qos_mutex);
+               return -ENODEV;
+       }
+
        ctx->body = input;
        ctx->bdev = bdev;
        return 0;
@@ -889,6 +904,7 @@ EXPORT_SYMBOL_GPL(blkg_conf_prep);
  */
 void blkg_conf_exit(struct blkg_conf_ctx *ctx)
        __releases(&ctx->bdev->bd_queue->queue_lock)
+       __releases(&ctx->bdev->bd_queue->rq_qos_mutex)
 {
        if (ctx->blkg) {
                spin_unlock_irq(&bdev_get_queue(ctx->bdev)->queue_lock);
@@ -896,6 +912,7 @@ void blkg_conf_exit(struct blkg_conf_ctx *ctx)
        }
 
        if (ctx->bdev) {
+               mutex_unlock(&ctx->bdev->bd_queue->rq_qos_mutex);
                blkdev_put_no_open(ctx->bdev);
                ctx->body = NULL;
                ctx->bdev = NULL;