From 39258aa2db8175271d8079b7685a6e328a8c1a63 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Thu, 7 Nov 2019 17:16:23 +0100 Subject: rbd: introduce RBD_DEV_FLAG_READONLY 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 Reviewed-by: Jason Dillaman Reviewed-by: Dongsheng Yang --- drivers/block/rbd.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 2f65798c40c0..978549d21f4f 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; @@ -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); -- cgit v1.2.3