[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 24/45] blk-cgroup: stop abusing get_gendisk



Properly open the device instead of relying on deep internals by
using get_gendisk.  Note that this uses FMODE_NDELAY without either
FMODE_READ or FMODE_WRITE, which is a special open mode to allow
for opening without media access, thus avoiding unexpexted interactions
especially on removable media.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
 block/blk-cgroup.c         | 42 +++++++++++++++++++-------------------
 block/blk-iocost.c         | 36 ++++++++++++++++----------------
 include/linux/blk-cgroup.h |  4 ++--
 3 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 54fbe1e80cc41a..23437b96ea41e6 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -556,22 +556,22 @@ static struct blkcg_gq *blkg_lookup_check(struct blkcg 
*blkcg,
 }
 
 /**
- * blkg_conf_prep - parse and prepare for per-blkg config update
+ * blkcg_conf_open_bdev - parse and open bdev for per-blkg config update
  * @inputp: input string pointer
  *
  * Parse the device node prefix part, MAJ:MIN, of per-blkg config update
- * from @input and get and return the matching gendisk.  *@inputp is
+ * from @input and get and return the matching bdev.  *@inputp is
  * updated to point past the device node prefix.  Returns an ERR_PTR()
  * value on error.
  *
  * Use this function iff blkg_conf_prep() can't be used for some reason.
  */
-struct gendisk *blkcg_conf_get_disk(char **inputp)
+struct block_device *blkcg_conf_open_bdev(char **inputp)
 {
        char *input = *inputp;
        unsigned int major, minor;
-       struct gendisk *disk;
-       int key_len, part;
+       struct block_device *bdev;
+       int key_len;
 
        if (sscanf(input, "%u:%u%n", &major, &minor, &key_len) != 2)
                return ERR_PTR(-EINVAL);
@@ -581,16 +581,16 @@ struct gendisk *blkcg_conf_get_disk(char **inputp)
                return ERR_PTR(-EINVAL);
        input = skip_spaces(input);
 
-       disk = get_gendisk(MKDEV(major, minor), &part);
-       if (!disk)
+       bdev = blkdev_get_by_dev(MKDEV(major, minor), FMODE_NDELAY, NULL);
+       if (!bdev)
                return ERR_PTR(-ENODEV);
-       if (part) {
-               put_disk_and_module(disk);
+       if (bdev_is_partition(bdev)) {
+               blkdev_put(bdev, FMODE_NDELAY);
                return ERR_PTR(-ENODEV);
        }
 
        *inputp = input;
-       return disk;
+       return bdev;
 }
 
 /**
@@ -607,18 +607,18 @@ struct gendisk *blkcg_conf_get_disk(char **inputp)
  */
 int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
                   char *input, struct blkg_conf_ctx *ctx)
-       __acquires(rcu) __acquires(&disk->queue->queue_lock)
+       __acquires(rcu) __acquires(&bdev->bd_disk->queue->queue_lock)
 {
-       struct gendisk *disk;
+       struct block_device *bdev;
        struct request_queue *q;
        struct blkcg_gq *blkg;
        int ret;
 
-       disk = blkcg_conf_get_disk(&input);
-       if (IS_ERR(disk))
-               return PTR_ERR(disk);
+       bdev = blkcg_conf_open_bdev(&input);
+       if (IS_ERR(bdev))
+               return PTR_ERR(bdev);
 
-       q = disk->queue;
+       q = bdev->bd_disk->queue;
 
        rcu_read_lock();
        spin_lock_irq(&q->queue_lock);
@@ -689,7 +689,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct 
blkcg_policy *pol,
                        goto success;
        }
 success:
-       ctx->disk = disk;
+       ctx->bdev = bdev;
        ctx->blkg = blkg;
        ctx->body = input;
        return 0;
@@ -700,7 +700,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct 
blkcg_policy *pol,
        spin_unlock_irq(&q->queue_lock);
        rcu_read_unlock();
 fail:
-       put_disk_and_module(disk);
+       blkdev_put(bdev, FMODE_NDELAY);
        /*
         * If queue was bypassing, we should retry.  Do so after a
         * short msleep().  It isn't strictly necessary but queue
@@ -723,11 +723,11 @@ EXPORT_SYMBOL_GPL(blkg_conf_prep);
  * with blkg_conf_prep().
  */
 void blkg_conf_finish(struct blkg_conf_ctx *ctx)
-       __releases(&ctx->disk->queue->queue_lock) __releases(rcu)
+       __releases(&ctx->bdev->bd_disk->queue->queue_lock) __releases(rcu)
 {
-       spin_unlock_irq(&ctx->disk->queue->queue_lock);
+       spin_unlock_irq(&ctx->bdev->bd_disk->queue->queue_lock);
        rcu_read_unlock();
-       put_disk_and_module(ctx->disk);
+       blkdev_put(ctx->bdev, FMODE_NDELAY);
 }
 EXPORT_SYMBOL_GPL(blkg_conf_finish);
 
diff --git a/block/blk-iocost.c b/block/blk-iocost.c
index bbe86d1199dc5b..9f219718e9813c 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -3120,23 +3120,23 @@ static const match_table_t qos_tokens = {
 static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
                             size_t nbytes, loff_t off)
 {
-       struct gendisk *disk;
+       struct block_device *bdev;
        struct ioc *ioc;
        u32 qos[NR_QOS_PARAMS];
        bool enable, user;
        char *p;
        int ret;
 
-       disk = blkcg_conf_get_disk(&input);
-       if (IS_ERR(disk))
-               return PTR_ERR(disk);
+       bdev = blkcg_conf_open_bdev(&input);
+       if (IS_ERR(bdev))
+               return PTR_ERR(bdev);
 
-       ioc = q_to_ioc(disk->queue);
+       ioc = q_to_ioc(bdev->bd_disk->queue);
        if (!ioc) {
-               ret = blk_iocost_init(disk->queue);
+               ret = blk_iocost_init(bdev->bd_disk->queue);
                if (ret)
                        goto err;
-               ioc = q_to_ioc(disk->queue);
+               ioc = q_to_ioc(bdev->bd_disk->queue);
        }
 
        spin_lock_irq(&ioc->lock);
@@ -3231,12 +3231,12 @@ static ssize_t ioc_qos_write(struct kernfs_open_file 
*of, char *input,
        ioc_refresh_params(ioc, true);
        spin_unlock_irq(&ioc->lock);
 
-       put_disk_and_module(disk);
+       blkdev_put(bdev, FMODE_NDELAY);
        return nbytes;
 einval:
        ret = -EINVAL;
 err:
-       put_disk_and_module(disk);
+       blkdev_put(bdev, FMODE_NDELAY);
        return ret;
 }
 
@@ -3287,23 +3287,23 @@ static const match_table_t i_lcoef_tokens = {
 static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
                                    size_t nbytes, loff_t off)
 {
-       struct gendisk *disk;
+       struct block_device *bdev;
        struct ioc *ioc;
        u64 u[NR_I_LCOEFS];
        bool user;
        char *p;
        int ret;
 
-       disk = blkcg_conf_get_disk(&input);
-       if (IS_ERR(disk))
-               return PTR_ERR(disk);
+       bdev = blkcg_conf_open_bdev(&input);
+       if (IS_ERR(bdev))
+               return PTR_ERR(bdev);
 
-       ioc = q_to_ioc(disk->queue);
+       ioc = q_to_ioc(bdev->bd_disk->queue);
        if (!ioc) {
-               ret = blk_iocost_init(disk->queue);
+               ret = blk_iocost_init(bdev->bd_disk->queue);
                if (ret)
                        goto err;
-               ioc = q_to_ioc(disk->queue);
+               ioc = q_to_ioc(bdev->bd_disk->queue);
        }
 
        spin_lock_irq(&ioc->lock);
@@ -3356,13 +3356,13 @@ static ssize_t ioc_cost_model_write(struct 
kernfs_open_file *of, char *input,
        ioc_refresh_params(ioc, true);
        spin_unlock_irq(&ioc->lock);
 
-       put_disk_and_module(disk);
+       blkdev_put(bdev, FMODE_NDELAY);
        return nbytes;
 
 einval:
        ret = -EINVAL;
 err:
-       put_disk_and_module(disk);
+       blkdev_put(bdev, FMODE_NDELAY);
        return ret;
 }
 
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index c8fc9792ac776d..b9f3c246c3c908 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -197,12 +197,12 @@ void blkcg_print_blkgs(struct seq_file *sf, struct blkcg 
*blkcg,
 u64 __blkg_prfill_u64(struct seq_file *sf, struct blkg_policy_data *pd, u64 v);
 
 struct blkg_conf_ctx {
-       struct gendisk                  *disk;
+       struct block_device             *bdev;
        struct blkcg_gq                 *blkg;
        char                            *body;
 };
 
-struct gendisk *blkcg_conf_get_disk(char **inputp);
+struct block_device *blkcg_conf_open_bdev(char **inputp);
 int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
                   char *input, struct blkg_conf_ctx *ctx);
 void blkg_conf_finish(struct blkg_conf_ctx *ctx);
-- 
2.29.2




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.