aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-04-23 14:52:53 -0400
committerSage Weil <sage@inktank.com>2013-05-02 00:19:25 -0400
commit3e83b65bb9a9f3a4d7f0200139bd947c940ec3ab (patch)
tree1bc9a9b4e88958364e1abdfa3e5ce9d1123f585d
parent9ef1ee5a1b6ccb3220fb822523716e56c3629dbe (diff)
rbd: don't create sysfs entries for non-mapped snapshots
When an rbd image gets mapped a device entry gets created for it under /sys/bus/rbd/devices/<id>/. Inside that directory there are sysfs files that contain information about the image: its size, feature bits, major device number, and so on. Additionally, if that image has any snapshots, a device entry gets created for each of those as a "child" of the mapped device. Each of these is a subdirectory of the mapped device, and each directory contains a few files with information about the snapshot (its snapshot id, size, and feature mask). There is no clear benefit to having those device entries for the snapshots. The information provided via sysfs of of little real value--and all of it is available via rbd CLI commands. If we still wanted to see the kernel's view of this information it could be done much more simply by including it in a single sysfs file for the mapped image. But there *is* a clear cost to supporting them. Every time a snapshot context changes, these entries need to be updated (deleted snapshots removed, new snapshots created). The rbd driver is notified of changes to the snapshot context via callbacks from an osd, and care must be taken to coordinate removal of snapshot data structures with the possibility of one these notifications occurring. Things would be considerably simpler if we just didn't have to maintain device entries for the snapshots. So get rid of them. The ability to map a snapshot of an rbd image will remain; the only thing lost will be the ability to query these sysfs directories for information about snapshots of mapped images. This resolves: http://tracker.ceph.com/issues/4796 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r--Documentation/ABI/testing/sysfs-bus-rbd20
-rw-r--r--drivers/block/rbd.c137
2 files changed, 4 insertions, 153 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-rbd b/Documentation/ABI/testing/sysfs-bus-rbd
index cd9213ccf3dc..0a306476424e 100644
--- a/Documentation/ABI/testing/sysfs-bus-rbd
+++ b/Documentation/ABI/testing/sysfs-bus-rbd
@@ -66,27 +66,7 @@ current_snap
66 66
67 The current snapshot for which the device is mapped. 67 The current snapshot for which the device is mapped.
68 68
69snap_*
70
71 A directory per each snapshot
72
73parent 69parent
74 70
75 Information identifying the pool, image, and snapshot id for 71 Information identifying the pool, image, and snapshot id for
76 the parent image in a layered rbd image (format 2 only). 72 the parent image in a layered rbd image (format 2 only).
77
78Entries under /sys/bus/rbd/devices/<dev-id>/snap_<snap-name>
79-------------------------------------------------------------
80
81snap_id
82
83 The rados internal snapshot id assigned for this snapshot
84
85snap_size
86
87 The size of the image when this snapshot was taken.
88
89snap_features
90
91 A hexadecimal encoding of the feature bits for this snapshot.
92
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 4d99d40034e1..515fbf967ef3 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -272,7 +272,6 @@ struct rbd_img_request {
272 list_for_each_entry_safe_reverse(oreq, n, &(ireq)->obj_requests, links) 272 list_for_each_entry_safe_reverse(oreq, n, &(ireq)->obj_requests, links)
273 273
274struct rbd_snap { 274struct rbd_snap {
275 struct device dev;
276 const char *name; 275 const char *name;
277 u64 size; 276 u64 size;
278 struct list_head node; 277 struct list_head node;
@@ -358,7 +357,6 @@ static DEFINE_SPINLOCK(rbd_client_list_lock);
358static int rbd_img_request_submit(struct rbd_img_request *img_request); 357static int rbd_img_request_submit(struct rbd_img_request *img_request);
359 358
360static int rbd_dev_snaps_update(struct rbd_device *rbd_dev); 359static int rbd_dev_snaps_update(struct rbd_device *rbd_dev);
361static int rbd_dev_snaps_register(struct rbd_device *rbd_dev);
362 360
363static void rbd_dev_release(struct device *dev); 361static void rbd_dev_release(struct device *dev);
364static void rbd_remove_snap_dev(struct rbd_snap *snap); 362static void rbd_remove_snap_dev(struct rbd_snap *snap);
@@ -3069,8 +3067,6 @@ static int rbd_dev_v1_refresh(struct rbd_device *rbd_dev, u64 *hver)
3069 kfree(h.object_prefix); 3067 kfree(h.object_prefix);
3070 3068
3071 ret = rbd_dev_snaps_update(rbd_dev); 3069 ret = rbd_dev_snaps_update(rbd_dev);
3072 if (!ret)
3073 ret = rbd_dev_snaps_register(rbd_dev);
3074 3070
3075 up_write(&rbd_dev->header_rwsem); 3071 up_write(&rbd_dev->header_rwsem);
3076 3072
@@ -3344,71 +3340,6 @@ static struct device_type rbd_device_type = {
3344 .release = rbd_sysfs_dev_release, 3340 .release = rbd_sysfs_dev_release,
3345}; 3341};
3346 3342
3347
3348/*
3349 sysfs - snapshots
3350*/
3351
3352static ssize_t rbd_snap_size_show(struct device *dev,
3353 struct device_attribute *attr,
3354 char *buf)
3355{
3356 struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
3357
3358 return sprintf(buf, "%llu\n", (unsigned long long)snap->size);
3359}
3360
3361static ssize_t rbd_snap_id_show(struct device *dev,
3362 struct device_attribute *attr,
3363 char *buf)
3364{
3365 struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
3366
3367 return sprintf(buf, "%llu\n", (unsigned long long)snap->id);
3368}
3369
3370static ssize_t rbd_snap_features_show(struct device *dev,
3371 struct device_attribute *attr,
3372 char *buf)
3373{
3374 struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
3375
3376 return sprintf(buf, "0x%016llx\n",
3377 (unsigned long long) snap->features);
3378}
3379
3380static DEVICE_ATTR(snap_size, S_IRUGO, rbd_snap_size_show, NULL);
3381static DEVICE_ATTR(snap_id, S_IRUGO, rbd_snap_id_show, NULL);
3382static DEVICE_ATTR(snap_features, S_IRUGO, rbd_snap_features_show, NULL);
3383
3384static struct attribute *rbd_snap_attrs[] = {
3385 &dev_attr_snap_size.attr,
3386 &dev_attr_snap_id.attr,
3387 &dev_attr_snap_features.attr,
3388 NULL,
3389};
3390
3391static struct attribute_group rbd_snap_attr_group = {
3392 .attrs = rbd_snap_attrs,
3393};
3394
3395static void rbd_snap_dev_release(struct device *dev)
3396{
3397 struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
3398 kfree(snap->name);
3399 kfree(snap);
3400}
3401
3402static const struct attribute_group *rbd_snap_attr_groups[] = {
3403 &rbd_snap_attr_group,
3404 NULL
3405};
3406
3407static struct device_type rbd_snap_device_type = {
3408 .groups = rbd_snap_attr_groups,
3409 .release = rbd_snap_dev_release,
3410};
3411
3412static struct rbd_spec *rbd_spec_get(struct rbd_spec *spec) 3343static struct rbd_spec *rbd_spec_get(struct rbd_spec *spec)
3413{ 3344{
3414 kref_get(&spec->kref); 3345 kref_get(&spec->kref);
@@ -3483,38 +3414,11 @@ static void rbd_dev_destroy(struct rbd_device *rbd_dev)
3483 kfree(rbd_dev); 3414 kfree(rbd_dev);
3484} 3415}
3485 3416
3486static bool rbd_snap_registered(struct rbd_snap *snap)
3487{
3488 bool ret = snap->dev.type == &rbd_snap_device_type;
3489 bool reg = device_is_registered(&snap->dev);
3490
3491 rbd_assert(!ret ^ reg);
3492
3493 return ret;
3494}
3495
3496static void rbd_remove_snap_dev(struct rbd_snap *snap) 3417static void rbd_remove_snap_dev(struct rbd_snap *snap)
3497{ 3418{
3498 list_del(&snap->node); 3419 list_del(&snap->node);
3499 if (device_is_registered(&snap->dev)) 3420 kfree(snap->name);
3500 device_unregister(&snap->dev); 3421 kfree(snap);
3501}
3502
3503static int rbd_register_snap_dev(struct rbd_snap *snap,
3504 struct device *parent)
3505{
3506 struct device *dev = &snap->dev;
3507 int ret;
3508
3509 dev->type = &rbd_snap_device_type;
3510 dev->parent = parent;
3511 dev->release = rbd_snap_dev_release;
3512 dev_set_name(dev, "%s%s", RBD_SNAP_DEV_NAME_PREFIX, snap->name);
3513 dout("%s: registering device for snapshot %s\n", __func__, snap->name);
3514
3515 ret = device_register(dev);
3516
3517 return ret;
3518} 3422}
3519 3423
3520static struct rbd_snap *__rbd_add_snap_dev(struct rbd_device *rbd_dev, 3424static struct rbd_snap *__rbd_add_snap_dev(struct rbd_device *rbd_dev,
@@ -4089,8 +3993,6 @@ static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev, u64 *hver)
4089 dout("rbd_dev_snaps_update returned %d\n", ret); 3993 dout("rbd_dev_snaps_update returned %d\n", ret);
4090 if (ret) 3994 if (ret)
4091 goto out; 3995 goto out;
4092 ret = rbd_dev_snaps_register(rbd_dev);
4093 dout("rbd_dev_snaps_register returned %d\n", ret);
4094out: 3996out:
4095 up_write(&rbd_dev->header_rwsem); 3997 up_write(&rbd_dev->header_rwsem);
4096 3998
@@ -4145,11 +4047,11 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
4145 */ 4047 */
4146 if (rbd_dev->spec->snap_id == snap->id) 4048 if (rbd_dev->spec->snap_id == snap->id)
4147 clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); 4049 clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags);
4148 rbd_remove_snap_dev(snap); 4050 dout("removing %ssnap id %llu\n",
4149 dout("%ssnap id %llu has been removed\n",
4150 rbd_dev->spec->snap_id == snap->id ? 4051 rbd_dev->spec->snap_id == snap->id ?
4151 "mapped " : "", 4052 "mapped " : "",
4152 (unsigned long long) snap->id); 4053 (unsigned long long) snap->id);
4054 rbd_remove_snap_dev(snap);
4153 4055
4154 /* Done with this list entry; advance */ 4056 /* Done with this list entry; advance */
4155 4057
@@ -4209,31 +4111,6 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
4209 return 0; 4111 return 0;
4210} 4112}
4211 4113
4212/*
4213 * Scan the list of snapshots and register the devices for any that
4214 * have not already been registered.
4215 */
4216static int rbd_dev_snaps_register(struct rbd_device *rbd_dev)
4217{
4218 struct rbd_snap *snap;
4219 int ret = 0;
4220
4221 dout("%s:\n", __func__);
4222 if (WARN_ON(!device_is_registered(&rbd_dev->dev)))
4223 return -EIO;
4224
4225 list_for_each_entry(snap, &rbd_dev->snaps, node) {
4226 if (!rbd_snap_registered(snap)) {
4227 ret = rbd_register_snap_dev(snap, &rbd_dev->dev);
4228 if (ret < 0)
4229 break;
4230 }
4231 }
4232 dout("%s: returning %d\n", __func__, ret);
4233
4234 return ret;
4235}
4236
4237static int rbd_bus_add_dev(struct rbd_device *rbd_dev) 4114static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
4238{ 4115{
4239 struct device *dev; 4116 struct device *dev;
@@ -4840,12 +4717,6 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev)
4840 rbd_dev->parent = parent; 4717 rbd_dev->parent = parent;
4841 } 4718 }
4842 4719
4843 down_write(&rbd_dev->header_rwsem);
4844 ret = rbd_dev_snaps_register(rbd_dev);
4845 up_write(&rbd_dev->header_rwsem);
4846 if (ret)
4847 goto err_out_bus;
4848
4849 ret = rbd_dev_header_watch_sync(rbd_dev, 1); 4720 ret = rbd_dev_header_watch_sync(rbd_dev, 1);
4850 if (ret) 4721 if (ret)
4851 goto err_out_bus; 4722 goto err_out_bus;