aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-01-30 12:13:33 -0500
committerSage Weil <sage@inktank.com>2013-02-13 21:29:11 -0500
commit1e32d34cfa6759df58b5f4002664241f2a0fef6a (patch)
treeadec3c6652116c64ec295b35cac03f3fb255a6eb /drivers/block
parent72fe25e3460c8673984370208e0e6261101372d6 (diff)
rbd: don't take extra bio reference for osd client
Currently, if the OSD client finds an osd request has had a bio list attached to it, it drops a reference to it (or rather, to the first entry on that list) when the request is released. The code that added that reference (i.e., the rbd client) is therefore required to take an extra reference to that first bio structure. The osd client doesn't really do anything with the bio pointer other than transfer it from the osd request structure to outgoing (for writes) and ingoing (for reads) messages. So it really isn't the right place to be taking or dropping references. Furthermore, the rbd client already holds references to all bio structures it passes to the osd client, and holds them until the request is completed. So there's no need for this extra reference whatsoever. So remove the bio_put() call in ceph_osdc_release_request(), as well as its matching bio_get() call in rbd_osd_req_create(). This change could lead to a crash if old libceph.ko was used with new rbd.ko. Add a compatibility check at rbd initialization time to avoid this possibilty. This resolves: http://tracker.ceph.com/issues/3798 and http://tracker.ceph.com/issues/3799 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.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index ed0c91d81063..3ba4836f024c 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1342,7 +1342,6 @@ static struct ceph_osd_request *rbd_osd_req_create(
1342 case OBJ_REQUEST_BIO: 1342 case OBJ_REQUEST_BIO:
1343 rbd_assert(obj_request->bio_list != NULL); 1343 rbd_assert(obj_request->bio_list != NULL);
1344 osd_req->r_bio = obj_request->bio_list; 1344 osd_req->r_bio = obj_request->bio_list;
1345 bio_get(osd_req->r_bio);
1346 /* osd client requires "num pages" even for bio */ 1345 /* osd client requires "num pages" even for bio */
1347 osd_req->r_num_pages = calc_pages_for(offset, length); 1346 osd_req->r_num_pages = calc_pages_for(offset, length);
1348 break; 1347 break;
@@ -4149,6 +4148,11 @@ int __init rbd_init(void)
4149{ 4148{
4150 int rc; 4149 int rc;
4151 4150
4151 if (!libceph_compatible(NULL)) {
4152 rbd_warn(NULL, "libceph incompatibility (quitting)");
4153
4154 return -EINVAL;
4155 }
4152 rc = rbd_sysfs_init(); 4156 rc = rbd_sysfs_init();
4153 if (rc) 4157 if (rc)
4154 return rc; 4158 return rc;