[2/9] rbd: introduce RBD_DEV_FLAG_READONLY
diff mbox series

Message ID 20191118133816.3963-3-idryomov@gmail.com
State New
Headers show
Series
  • wip-krbd-readonly
Related show

Commit Message

Ilya Dryomov Nov. 18, 2019, 1:38 p.m. UTC
rbd_dev->opts is not available for parent images, making checking
rbd_dev->opts->read_only in various places (rbd_dev_image_probe(),
need_exclusive_lock(), use_object_map() in the following patches)
harder than it needs to be.

Keeping rbd_dev_image_probe() in mind, move the initialization in
do_rbd_add() up.  snap_id isn't filled in at that point, so replace
rbd_is_snap() with a snap_name comparison.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 drivers/block/rbd.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

Comments

Dongsheng Yang Nov. 19, 2019, 8:37 a.m. UTC | #1
On 11/18/2019 09:38 PM, Ilya Dryomov wrote:
> rbd_dev->opts is not available for parent images, making checking
> rbd_dev->opts->read_only in various places (rbd_dev_image_probe(),
> need_exclusive_lock(), use_object_map() in the following patches)
> harder than it needs to be.
>
> Keeping rbd_dev_image_probe() in mind, move the initialization in
> do_rbd_add() up.  snap_id isn't filled in at that point, so replace
> rbd_is_snap() with a snap_name comparison.
>
> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>

Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
> ---
>   drivers/block/rbd.c | 19 ++++++++++++++-----
>   1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index cf2a7d094890..330d2789f373 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -464,6 +464,7 @@ struct rbd_device {
>   enum rbd_dev_flags {
>   	RBD_DEV_FLAG_EXISTS,	/* mapped snapshot has not been deleted */
>   	RBD_DEV_FLAG_REMOVING,	/* this mapping is being removed */
> +	RBD_DEV_FLAG_READONLY,  /* -o ro or snapshot */
>   };
>   
>   static DEFINE_MUTEX(client_mutex);	/* Serialize client creation */
> @@ -514,6 +515,11 @@ static int minor_to_rbd_dev_id(int minor)
>   	return minor >> RBD_SINGLE_MAJOR_PART_SHIFT;
>   }
>   
> +static bool rbd_is_ro(struct rbd_device *rbd_dev)
> +{
> +	return test_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags);
> +}
> +
>   static bool rbd_is_snap(struct rbd_device *rbd_dev)
>   {
>   	return rbd_dev->spec->snap_id != CEPH_NOSNAP;
> @@ -6867,6 +6873,8 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth)
>   	__rbd_get_client(rbd_dev->rbd_client);
>   	rbd_spec_get(rbd_dev->parent_spec);
>   
> +	__set_bit(RBD_DEV_FLAG_READONLY, &parent->flags);
> +
>   	ret = rbd_dev_image_probe(parent, depth);
>   	if (ret < 0)
>   		goto out_err;
> @@ -6918,7 +6926,7 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
>   		goto err_out_blkdev;
>   
>   	set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE);
> -	set_disk_ro(rbd_dev->disk, rbd_dev->opts->read_only);
> +	set_disk_ro(rbd_dev->disk, rbd_is_ro(rbd_dev));
>   
>   	ret = dev_set_name(&rbd_dev->dev, "%d", rbd_dev->dev_id);
>   	if (ret)
> @@ -7107,6 +7115,11 @@ static ssize_t do_rbd_add(struct bus_type *bus,
>   	ctx.rbd_spec = NULL;	/* rbd_dev now owns this */
>   	ctx.rbd_opts = NULL;	/* rbd_dev now owns this */
>   
> +	/* if we are mapping a snapshot it will be a read-only mapping */
> +	if (rbd_dev->opts->read_only ||
> +	    strcmp(rbd_dev->spec->snap_name, RBD_SNAP_HEAD_NAME))
> +		__set_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags);
> +
>   	rbd_dev->config_info = kstrdup(buf, GFP_KERNEL);
>   	if (!rbd_dev->config_info) {
>   		rc = -ENOMEM;
> @@ -7120,10 +7133,6 @@ static ssize_t do_rbd_add(struct bus_type *bus,
>   		goto err_out_rbd_dev;
>   	}
>   
> -	/* If we are mapping a snapshot it must be marked read-only */
> -	if (rbd_is_snap(rbd_dev))
> -		rbd_dev->opts->read_only = true;
> -
>   	if (rbd_dev->opts->alloc_size > rbd_dev->layout.object_size) {
>   		rbd_warn(rbd_dev, "alloc_size adjusted to %u",
>   			 rbd_dev->layout.object_size);

Patch
diff mbox series

diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index cf2a7d094890..330d2789f373 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -464,6 +464,7 @@  struct rbd_device {
 enum rbd_dev_flags {
 	RBD_DEV_FLAG_EXISTS,	/* mapped snapshot has not been deleted */
 	RBD_DEV_FLAG_REMOVING,	/* this mapping is being removed */
+	RBD_DEV_FLAG_READONLY,  /* -o ro or snapshot */
 };
 
 static DEFINE_MUTEX(client_mutex);	/* Serialize client creation */
@@ -514,6 +515,11 @@  static int minor_to_rbd_dev_id(int minor)
 	return minor >> RBD_SINGLE_MAJOR_PART_SHIFT;
 }
 
+static bool rbd_is_ro(struct rbd_device *rbd_dev)
+{
+	return test_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags);
+}
+
 static bool rbd_is_snap(struct rbd_device *rbd_dev)
 {
 	return rbd_dev->spec->snap_id != CEPH_NOSNAP;
@@ -6867,6 +6873,8 @@  static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth)
 	__rbd_get_client(rbd_dev->rbd_client);
 	rbd_spec_get(rbd_dev->parent_spec);
 
+	__set_bit(RBD_DEV_FLAG_READONLY, &parent->flags);
+
 	ret = rbd_dev_image_probe(parent, depth);
 	if (ret < 0)
 		goto out_err;
@@ -6918,7 +6926,7 @@  static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
 		goto err_out_blkdev;
 
 	set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE);
-	set_disk_ro(rbd_dev->disk, rbd_dev->opts->read_only);
+	set_disk_ro(rbd_dev->disk, rbd_is_ro(rbd_dev));
 
 	ret = dev_set_name(&rbd_dev->dev, "%d", rbd_dev->dev_id);
 	if (ret)
@@ -7107,6 +7115,11 @@  static ssize_t do_rbd_add(struct bus_type *bus,
 	ctx.rbd_spec = NULL;	/* rbd_dev now owns this */
 	ctx.rbd_opts = NULL;	/* rbd_dev now owns this */
 
+	/* if we are mapping a snapshot it will be a read-only mapping */
+	if (rbd_dev->opts->read_only ||
+	    strcmp(rbd_dev->spec->snap_name, RBD_SNAP_HEAD_NAME))
+		__set_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags);
+
 	rbd_dev->config_info = kstrdup(buf, GFP_KERNEL);
 	if (!rbd_dev->config_info) {
 		rc = -ENOMEM;
@@ -7120,10 +7133,6 @@  static ssize_t do_rbd_add(struct bus_type *bus,
 		goto err_out_rbd_dev;
 	}
 
-	/* If we are mapping a snapshot it must be marked read-only */
-	if (rbd_is_snap(rbd_dev))
-		rbd_dev->opts->read_only = true;
-
 	if (rbd_dev->opts->alloc_size > rbd_dev->layout.object_size) {
 		rbd_warn(rbd_dev, "alloc_size adjusted to %u",
 			 rbd_dev->layout.object_size);