aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-10-26 00:34:42 -0400
committerAlex Elder <elder@inktank.com>2012-11-01 08:55:42 -0400
commitc53d589337e9a211413484a604c76072e8474dc0 (patch)
treebd9718b7d7648e80f64e09d6ee483d262815b340 /drivers/block
parentbd4ba6554dcbae652b8b27a44f5a7795c9f3178a (diff)
rbd: define rbd_dev_{create,destroy}() helpers
Encapsulate the creation/initialization and destruction of rbd device structures. The rbd_client and the rbd_spec structures provided on creation hold references whose ownership is transferred to the new rbd_device structure. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c62
1 files changed, 41 insertions, 21 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 4771de2fba8a..a8ad8f8370b6 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -504,7 +504,8 @@ static void rbd_client_release(struct kref *kref)
504 */ 504 */
505static void rbd_put_client(struct rbd_client *rbdc) 505static void rbd_put_client(struct rbd_client *rbdc)
506{ 506{
507 kref_put(&rbdc->kref, rbd_client_release); 507 if (rbdc)
508 kref_put(&rbdc->kref, rbd_client_release);
508} 509}
509 510
510/* 511/*
@@ -2166,6 +2167,34 @@ static void rbd_spec_free(struct kref *kref)
2166 kfree(spec); 2167 kfree(spec);
2167} 2168}
2168 2169
2170struct rbd_device *rbd_dev_create(struct rbd_client *rbdc,
2171 struct rbd_spec *spec)
2172{
2173 struct rbd_device *rbd_dev;
2174
2175 rbd_dev = kzalloc(sizeof (*rbd_dev), GFP_KERNEL);
2176 if (!rbd_dev)
2177 return NULL;
2178
2179 spin_lock_init(&rbd_dev->lock);
2180 INIT_LIST_HEAD(&rbd_dev->node);
2181 INIT_LIST_HEAD(&rbd_dev->snaps);
2182 init_rwsem(&rbd_dev->header_rwsem);
2183
2184 rbd_dev->spec = spec;
2185 rbd_dev->rbd_client = rbdc;
2186
2187 return rbd_dev;
2188}
2189
2190static void rbd_dev_destroy(struct rbd_device *rbd_dev)
2191{
2192 kfree(rbd_dev->header_name);
2193 rbd_put_client(rbd_dev->rbd_client);
2194 rbd_spec_put(rbd_dev->spec);
2195 kfree(rbd_dev);
2196}
2197
2169static bool rbd_snap_registered(struct rbd_snap *snap) 2198static bool rbd_snap_registered(struct rbd_snap *snap)
2170{ 2199{
2171 bool ret = snap->dev.type == &rbd_snap_device_type; 2200 bool ret = snap->dev.type == &rbd_snap_device_type;
@@ -3242,7 +3271,7 @@ static ssize_t rbd_add(struct bus_type *bus,
3242 rc = PTR_ERR(rbdc); 3271 rc = PTR_ERR(rbdc);
3243 goto err_out_args; 3272 goto err_out_args;
3244 } 3273 }
3245 ceph_opts = NULL; /* ceph_opts now owned by rbd_dev client */ 3274 ceph_opts = NULL; /* rbd_dev client now owns this */
3246 3275
3247 /* pick the pool */ 3276 /* pick the pool */
3248 osdc = &rbdc->client->osdc; 3277 osdc = &rbdc->client->osdc;
@@ -3251,22 +3280,19 @@ static ssize_t rbd_add(struct bus_type *bus,
3251 goto err_out_client; 3280 goto err_out_client;
3252 spec->pool_id = (u64) rc; 3281 spec->pool_id = (u64) rc;
3253 3282
3254 rbd_dev = kzalloc(sizeof (*rbd_dev), GFP_KERNEL); 3283 rbd_dev = rbd_dev_create(rbdc, spec);
3255 if (!rbd_dev) 3284 if (!rbd_dev)
3256 goto err_out_client; 3285 goto err_out_client;
3257 3286 rbdc = NULL; /* rbd_dev now owns this */
3258 spin_lock_init(&rbd_dev->lock); 3287 spec = NULL; /* rbd_dev now owns this */
3259 INIT_LIST_HEAD(&rbd_dev->node);
3260 INIT_LIST_HEAD(&rbd_dev->snaps);
3261 init_rwsem(&rbd_dev->header_rwsem);
3262 rbd_dev->rbd_client = rbdc;
3263 rbd_dev->spec = spec;
3264 3288
3265 rbd_dev->mapping.read_only = rbd_opts->read_only; 3289 rbd_dev->mapping.read_only = rbd_opts->read_only;
3290 kfree(rbd_opts);
3291 rbd_opts = NULL; /* done with this */
3266 3292
3267 rc = rbd_dev_probe(rbd_dev); 3293 rc = rbd_dev_probe(rbd_dev);
3268 if (rc < 0) 3294 if (rc < 0)
3269 goto err_out_mem; 3295 goto err_out_rbd_dev;
3270 3296
3271 /* no need to lock here, as rbd_dev is not registered yet */ 3297 /* no need to lock here, as rbd_dev is not registered yet */
3272 rc = rbd_dev_snaps_update(rbd_dev); 3298 rc = rbd_dev_snaps_update(rbd_dev);
@@ -3317,8 +3343,6 @@ static ssize_t rbd_add(struct bus_type *bus,
3317 if (rc) 3343 if (rc)
3318 goto err_out_bus; 3344 goto err_out_bus;
3319 3345
3320 kfree(rbd_opts);
3321
3322 /* Everything's ready. Announce the disk to the world. */ 3346 /* Everything's ready. Announce the disk to the world. */
3323 3347
3324 add_disk(rbd_dev->disk); 3348 add_disk(rbd_dev->disk);
@@ -3332,7 +3356,6 @@ err_out_bus:
3332 /* this will also clean up rest of rbd_dev stuff */ 3356 /* this will also clean up rest of rbd_dev stuff */
3333 3357
3334 rbd_bus_del_dev(rbd_dev); 3358 rbd_bus_del_dev(rbd_dev);
3335 kfree(rbd_opts);
3336 3359
3337 return rc; 3360 return rc;
3338 3361
@@ -3346,9 +3369,8 @@ err_out_snaps:
3346 rbd_remove_all_snaps(rbd_dev); 3369 rbd_remove_all_snaps(rbd_dev);
3347err_out_probe: 3370err_out_probe:
3348 rbd_header_free(&rbd_dev->header); 3371 rbd_header_free(&rbd_dev->header);
3349 kfree(rbd_dev->header_name); 3372err_out_rbd_dev:
3350err_out_mem: 3373 rbd_dev_destroy(rbd_dev);
3351 kfree(rbd_dev);
3352err_out_client: 3374err_out_client:
3353 rbd_put_client(rbdc); 3375 rbd_put_client(rbdc);
3354err_out_args: 3376err_out_args:
@@ -3394,7 +3416,6 @@ static void rbd_dev_release(struct device *dev)
3394 if (rbd_dev->watch_event) 3416 if (rbd_dev->watch_event)
3395 rbd_req_sync_unwatch(rbd_dev); 3417 rbd_req_sync_unwatch(rbd_dev);
3396 3418
3397 rbd_put_client(rbd_dev->rbd_client);
3398 3419
3399 /* clean up and free blkdev */ 3420 /* clean up and free blkdev */
3400 rbd_free_disk(rbd_dev); 3421 rbd_free_disk(rbd_dev);
@@ -3404,10 +3425,9 @@ static void rbd_dev_release(struct device *dev)
3404 rbd_header_free(&rbd_dev->header); 3425 rbd_header_free(&rbd_dev->header);
3405 3426
3406 /* done with the id, and with the rbd_dev */ 3427 /* done with the id, and with the rbd_dev */
3407 kfree(rbd_dev->header_name);
3408 rbd_dev_id_put(rbd_dev); 3428 rbd_dev_id_put(rbd_dev);
3409 rbd_spec_put(rbd_dev->spec); 3429 rbd_assert(rbd_dev->rbd_client != NULL);
3410 kfree(rbd_dev); 3430 rbd_dev_destroy(rbd_dev);
3411 3431
3412 /* release module ref */ 3432 /* release module ref */
3413 module_put(THIS_MODULE); 3433 module_put(THIS_MODULE);