aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-05-08 23:50:04 -0400
committerAlex Elder <elder@inktank.com>2013-05-13 16:06:44 -0400
commite93f3152357ca75284284bef8eeea7d45fe1bab1 (patch)
tree772595e38dcf482119c938228c2e4db699bcbaa3 /drivers/block/rbd.c
parentfb65d2284c117cfc28d30217d25a14a8e7a75a94 (diff)
rbd: define parent image request routines
Define rbd_parent_request_create() and rbd_parent_request_destroy() to handle the creation of parent image requests submitted for layered image objects. For simplicity, let rbd_img_request_put() handle dropping the reference to any image request (parent or not), and call whichever destructor is appropriate on the last put. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c78
1 files changed, 55 insertions, 23 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 9c2b20a88be2..1ffdfbfbf3c4 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1359,13 +1359,18 @@ static void rbd_obj_request_put(struct rbd_obj_request *obj_request)
1359 kref_put(&obj_request->kref, rbd_obj_request_destroy); 1359 kref_put(&obj_request->kref, rbd_obj_request_destroy);
1360} 1360}
1361 1361
1362static bool img_request_child_test(struct rbd_img_request *img_request);
1363static void rbd_parent_request_destroy(struct kref *kref);
1362static void rbd_img_request_destroy(struct kref *kref); 1364static void rbd_img_request_destroy(struct kref *kref);
1363static void rbd_img_request_put(struct rbd_img_request *img_request) 1365static void rbd_img_request_put(struct rbd_img_request *img_request)
1364{ 1366{
1365 rbd_assert(img_request != NULL); 1367 rbd_assert(img_request != NULL);
1366 dout("%s: img %p (was %d)\n", __func__, img_request, 1368 dout("%s: img %p (was %d)\n", __func__, img_request,
1367 atomic_read(&img_request->kref.refcount)); 1369 atomic_read(&img_request->kref.refcount));
1368 kref_put(&img_request->kref, rbd_img_request_destroy); 1370 if (img_request_child_test(img_request))
1371 kref_put(&img_request->kref, rbd_parent_request_destroy);
1372 else
1373 kref_put(&img_request->kref, rbd_img_request_destroy);
1369} 1374}
1370 1375
1371static inline void rbd_img_obj_request_add(struct rbd_img_request *img_request, 1376static inline void rbd_img_obj_request_add(struct rbd_img_request *img_request,
@@ -1482,6 +1487,12 @@ static void img_request_child_set(struct rbd_img_request *img_request)
1482 smp_mb(); 1487 smp_mb();
1483} 1488}
1484 1489
1490static void img_request_child_clear(struct rbd_img_request *img_request)
1491{
1492 clear_bit(IMG_REQ_CHILD, &img_request->flags);
1493 smp_mb();
1494}
1495
1485static bool img_request_child_test(struct rbd_img_request *img_request) 1496static bool img_request_child_test(struct rbd_img_request *img_request)
1486{ 1497{
1487 smp_mb(); 1498 smp_mb();
@@ -1856,8 +1867,7 @@ static void rbd_dev_unparent(struct rbd_device *rbd_dev)
1856static struct rbd_img_request *rbd_img_request_create( 1867static struct rbd_img_request *rbd_img_request_create(
1857 struct rbd_device *rbd_dev, 1868 struct rbd_device *rbd_dev,
1858 u64 offset, u64 length, 1869 u64 offset, u64 length,
1859 bool write_request, 1870 bool write_request)
1860 bool child_request)
1861{ 1871{
1862 struct rbd_img_request *img_request; 1872 struct rbd_img_request *img_request;
1863 1873
@@ -1882,8 +1892,6 @@ static struct rbd_img_request *rbd_img_request_create(
1882 } else { 1892 } else {
1883 img_request->snap_id = rbd_dev->spec->snap_id; 1893 img_request->snap_id = rbd_dev->spec->snap_id;
1884 } 1894 }
1885 if (child_request)
1886 img_request_child_set(img_request);
1887 if (rbd_dev->parent_overlap) 1895 if (rbd_dev->parent_overlap)
1888 img_request_layered_set(img_request); 1896 img_request_layered_set(img_request);
1889 spin_lock_init(&img_request->completion_lock); 1897 spin_lock_init(&img_request->completion_lock);
@@ -1918,12 +1926,46 @@ static void rbd_img_request_destroy(struct kref *kref)
1918 if (img_request_write_test(img_request)) 1926 if (img_request_write_test(img_request))
1919 ceph_put_snap_context(img_request->snapc); 1927 ceph_put_snap_context(img_request->snapc);
1920 1928
1921 if (img_request_child_test(img_request))
1922 rbd_obj_request_put(img_request->obj_request);
1923
1924 kmem_cache_free(rbd_img_request_cache, img_request); 1929 kmem_cache_free(rbd_img_request_cache, img_request);
1925} 1930}
1926 1931
1932static struct rbd_img_request *rbd_parent_request_create(
1933 struct rbd_obj_request *obj_request,
1934 u64 img_offset, u64 length)
1935{
1936 struct rbd_img_request *parent_request;
1937 struct rbd_device *rbd_dev;
1938
1939 rbd_assert(obj_request->img_request);
1940 rbd_dev = obj_request->img_request->rbd_dev;
1941
1942 parent_request = rbd_img_request_create(rbd_dev->parent,
1943 img_offset, length, false);
1944 if (!parent_request)
1945 return NULL;
1946
1947 img_request_child_set(parent_request);
1948 rbd_obj_request_get(obj_request);
1949 parent_request->obj_request = obj_request;
1950
1951 return parent_request;
1952}
1953
1954static void rbd_parent_request_destroy(struct kref *kref)
1955{
1956 struct rbd_img_request *parent_request;
1957 struct rbd_obj_request *orig_request;
1958
1959 parent_request = container_of(kref, struct rbd_img_request, kref);
1960 orig_request = parent_request->obj_request;
1961
1962 parent_request->obj_request = NULL;
1963 rbd_obj_request_put(orig_request);
1964 img_request_child_clear(parent_request);
1965
1966 rbd_img_request_destroy(kref);
1967}
1968
1927static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request) 1969static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request)
1928{ 1970{
1929 struct rbd_img_request *img_request; 1971 struct rbd_img_request *img_request;
@@ -2321,13 +2363,10 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request)
2321 } 2363 }
2322 2364
2323 result = -ENOMEM; 2365 result = -ENOMEM;
2324 parent_request = rbd_img_request_create(rbd_dev->parent, 2366 parent_request = rbd_parent_request_create(obj_request,
2325 img_offset, length, 2367 img_offset, length);
2326 false, true);
2327 if (!parent_request) 2368 if (!parent_request)
2328 goto out_err; 2369 goto out_err;
2329 rbd_obj_request_get(obj_request);
2330 parent_request->obj_request = obj_request;
2331 2370
2332 result = rbd_img_request_fill(parent_request, OBJ_REQUEST_PAGES, pages); 2371 result = rbd_img_request_fill(parent_request, OBJ_REQUEST_PAGES, pages);
2333 if (result) 2372 if (result)
@@ -2580,7 +2619,6 @@ out:
2580 2619
2581static void rbd_img_parent_read(struct rbd_obj_request *obj_request) 2620static void rbd_img_parent_read(struct rbd_obj_request *obj_request)
2582{ 2621{
2583 struct rbd_device *rbd_dev;
2584 struct rbd_img_request *img_request; 2622 struct rbd_img_request *img_request;
2585 int result; 2623 int result;
2586 2624
@@ -2589,20 +2627,14 @@ static void rbd_img_parent_read(struct rbd_obj_request *obj_request)
2589 rbd_assert(obj_request->result == (s32) -ENOENT); 2627 rbd_assert(obj_request->result == (s32) -ENOENT);
2590 rbd_assert(obj_request_type_valid(obj_request->type)); 2628 rbd_assert(obj_request_type_valid(obj_request->type));
2591 2629
2592 rbd_dev = obj_request->img_request->rbd_dev;
2593 rbd_assert(rbd_dev->parent != NULL);
2594 /* rbd_read_finish(obj_request, obj_request->length); */ 2630 /* rbd_read_finish(obj_request, obj_request->length); */
2595 img_request = rbd_img_request_create(rbd_dev->parent, 2631 img_request = rbd_parent_request_create(obj_request,
2596 obj_request->img_offset, 2632 obj_request->img_offset,
2597 obj_request->length, 2633 obj_request->length);
2598 false, true);
2599 result = -ENOMEM; 2634 result = -ENOMEM;
2600 if (!img_request) 2635 if (!img_request)
2601 goto out_err; 2636 goto out_err;
2602 2637
2603 rbd_obj_request_get(obj_request);
2604 img_request->obj_request = obj_request;
2605
2606 if (obj_request->type == OBJ_REQUEST_BIO) 2638 if (obj_request->type == OBJ_REQUEST_BIO)
2607 result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO, 2639 result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO,
2608 obj_request->bio_list); 2640 obj_request->bio_list);
@@ -2913,7 +2945,7 @@ static void rbd_request_fn(struct request_queue *q)
2913 2945
2914 result = -ENOMEM; 2946 result = -ENOMEM;
2915 img_request = rbd_img_request_create(rbd_dev, offset, length, 2947 img_request = rbd_img_request_create(rbd_dev, offset, length,
2916 write_request, false); 2948 write_request);
2917 if (!img_request) 2949 if (!img_request)
2918 goto end_request; 2950 goto end_request;
2919 2951