aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-08-31 18:29:52 -0400
committerAlex Elder <elder@inktank.com>2012-10-01 15:30:52 -0400
commit304f68086f8206da7c5930a9cb0207c91d1983a6 (patch)
tree915bdd3d884dd36fb62acd4e761e98191d001f98
parent3fcf2581c2c3c910aa46f6d205e502a97243ca2c (diff)
rbd: defer registering snapshot devices
When a new snapshot is found in an rbd device's updated snapshot context, __rbd_add_snap_dev() is called to create and insert an entry in the rbd devices list of snapshots. In addition, a Linux device is registered to represent the snapshot. For version 2 rbd images, it will be undesirable to initialize the device right away. So in anticipation of that, this patch separates the insertion of a snapshot entry in the snaps list from the creation of devices for those snapshots. To do this, create a new function rbd_dev_snaps_register() which traverses the list of snapshots and calls rbd_register_snap_dev() on any that have not yet been registered. Rename rbd_dev_snap_devs_update() to be rbd_dev_snaps_update() to better reflect that only the entry in the snaps list and not the snapshot's device is affected by the function. For now, call rbd_dev_snaps_register() immediately after each call to rbd_dev_snaps_update(). Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r--drivers/block/rbd.c60
1 files changed, 50 insertions, 10 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 48901b51f648..0d812603e6d5 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -204,7 +204,9 @@ static DEFINE_SPINLOCK(rbd_dev_list_lock);
204static LIST_HEAD(rbd_client_list); /* clients */ 204static LIST_HEAD(rbd_client_list); /* clients */
205static DEFINE_SPINLOCK(rbd_client_list_lock); 205static DEFINE_SPINLOCK(rbd_client_list_lock);
206 206
207static int rbd_dev_snap_devs_update(struct rbd_device *rbd_dev); 207static int rbd_dev_snaps_update(struct rbd_device *rbd_dev);
208static int rbd_dev_snaps_register(struct rbd_device *rbd_dev);
209
208static void rbd_dev_release(struct device *dev); 210static void rbd_dev_release(struct device *dev);
209static ssize_t rbd_snap_add(struct device *dev, 211static ssize_t rbd_snap_add(struct device *dev,
210 struct device_attribute *attr, 212 struct device_attribute *attr,
@@ -1839,7 +1841,9 @@ static int __rbd_refresh_header(struct rbd_device *rbd_dev, u64 *hver)
1839 WARN_ON(strcmp(rbd_dev->header.object_prefix, h.object_prefix)); 1841 WARN_ON(strcmp(rbd_dev->header.object_prefix, h.object_prefix));
1840 kfree(h.object_prefix); 1842 kfree(h.object_prefix);
1841 1843
1842 ret = rbd_dev_snap_devs_update(rbd_dev); 1844 ret = rbd_dev_snaps_update(rbd_dev);
1845 if (!ret)
1846 ret = rbd_dev_snaps_register(rbd_dev);
1843 1847
1844 up_write(&rbd_dev->header_rwsem); 1848 up_write(&rbd_dev->header_rwsem);
1845 1849
@@ -2084,10 +2088,21 @@ static struct device_type rbd_snap_device_type = {
2084 .release = rbd_snap_dev_release, 2088 .release = rbd_snap_dev_release,
2085}; 2089};
2086 2090
2091static bool rbd_snap_registered(struct rbd_snap *snap)
2092{
2093 bool ret = snap->dev.type == &rbd_snap_device_type;
2094 bool reg = device_is_registered(&snap->dev);
2095
2096 rbd_assert(!ret ^ reg);
2097
2098 return ret;
2099}
2100
2087static void __rbd_remove_snap_dev(struct rbd_snap *snap) 2101static void __rbd_remove_snap_dev(struct rbd_snap *snap)
2088{ 2102{
2089 list_del(&snap->node); 2103 list_del(&snap->node);
2090 device_unregister(&snap->dev); 2104 if (device_is_registered(&snap->dev))
2105 device_unregister(&snap->dev);
2091} 2106}
2092 2107
2093static int rbd_register_snap_dev(struct rbd_snap *snap, 2108static int rbd_register_snap_dev(struct rbd_snap *snap,
@@ -2100,6 +2115,8 @@ static int rbd_register_snap_dev(struct rbd_snap *snap,
2100 dev->parent = parent; 2115 dev->parent = parent;
2101 dev->release = rbd_snap_dev_release; 2116 dev->release = rbd_snap_dev_release;
2102 dev_set_name(dev, "snap_%s", snap->name); 2117 dev_set_name(dev, "snap_%s", snap->name);
2118 dout("%s: registering device for snapshot %s\n", __func__, snap->name);
2119
2103 ret = device_register(dev); 2120 ret = device_register(dev);
2104 2121
2105 return ret; 2122 return ret;
@@ -2122,11 +2139,6 @@ static struct rbd_snap *__rbd_add_snap_dev(struct rbd_device *rbd_dev,
2122 2139
2123 snap->size = rbd_dev->header.snap_sizes[i]; 2140 snap->size = rbd_dev->header.snap_sizes[i];
2124 snap->id = rbd_dev->header.snapc->snaps[i]; 2141 snap->id = rbd_dev->header.snapc->snaps[i];
2125 if (device_is_registered(&rbd_dev->dev)) {
2126 ret = rbd_register_snap_dev(snap, &rbd_dev->dev);
2127 if (ret < 0)
2128 goto err;
2129 }
2130 2142
2131 return snap; 2143 return snap;
2132 2144
@@ -2149,7 +2161,7 @@ err:
2149 * snapshot id, highest id first. (Snapshots in the rbd_dev's list 2161 * snapshot id, highest id first. (Snapshots in the rbd_dev's list
2150 * are also maintained in that order.) 2162 * are also maintained in that order.)
2151 */ 2163 */
2152static int rbd_dev_snap_devs_update(struct rbd_device *rbd_dev) 2164static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
2153{ 2165{
2154 struct ceph_snap_context *snapc = rbd_dev->header.snapc; 2166 struct ceph_snap_context *snapc = rbd_dev->header.snapc;
2155 const u32 snap_count = snapc->num_snaps; 2167 const u32 snap_count = snapc->num_snaps;
@@ -2236,6 +2248,31 @@ static int rbd_dev_snap_devs_update(struct rbd_device *rbd_dev)
2236 return 0; 2248 return 0;
2237} 2249}
2238 2250
2251/*
2252 * Scan the list of snapshots and register the devices for any that
2253 * have not already been registered.
2254 */
2255static int rbd_dev_snaps_register(struct rbd_device *rbd_dev)
2256{
2257 struct rbd_snap *snap;
2258 int ret = 0;
2259
2260 dout("%s called\n", __func__);
2261 if (!device_is_registered(&rbd_dev->dev))
2262 return 0;
2263
2264 list_for_each_entry(snap, &rbd_dev->snaps, node) {
2265 if (!rbd_snap_registered(snap)) {
2266 ret = rbd_register_snap_dev(snap, &rbd_dev->dev);
2267 if (ret < 0)
2268 break;
2269 }
2270 }
2271 dout("%s: returning %d\n", __func__, ret);
2272
2273 return ret;
2274}
2275
2239static int rbd_bus_add_dev(struct rbd_device *rbd_dev) 2276static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
2240{ 2277{
2241 struct device *dev; 2278 struct device *dev;
@@ -2585,7 +2622,10 @@ static ssize_t rbd_add(struct bus_type *bus,
2585 goto err_out_bus; 2622 goto err_out_bus;
2586 2623
2587 /* no need to lock here, as rbd_dev is not registered yet */ 2624 /* no need to lock here, as rbd_dev is not registered yet */
2588 rc = rbd_dev_snap_devs_update(rbd_dev); 2625 rc = rbd_dev_snaps_update(rbd_dev);
2626 if (rc)
2627 goto err_out_bus;
2628 rc = rbd_dev_snaps_register(rbd_dev);
2589 if (rc) 2629 if (rc)
2590 goto err_out_bus; 2630 goto err_out_bus;
2591 2631