rbd: introduce RBD_DEV_FLAG_READONLY
authorIlya Dryomov <idryomov@gmail.com>
Thu, 7 Nov 2019 16:16:23 +0000 (17:16 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 25 Nov 2019 10:44:02 +0000 (11:44 +0100)
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: Jason Dillaman <dillaman@redhat.com>
Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
drivers/block/rbd.c

index 2f65798..978549d 100644 (file)
@@ -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;
@@ -6843,6 +6849,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;
@@ -6894,7 +6902,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)
@@ -7084,6 +7092,11 @@ static ssize_t do_rbd_add(struct bus_type *bus,
        spec = NULL;            /* rbd_dev now owns this */
        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;
@@ -7097,10 +7110,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);