Skip to content

Commit

Permalink
rbd: don't take extra bio reference for osd client
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alex Elder authored and Sage Weil committed Feb 14, 2013
1 parent 72fe25e commit 1e32d34
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 6 deletions.
6 changes: 5 additions & 1 deletion drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,6 @@ static struct ceph_osd_request *rbd_osd_req_create(
case OBJ_REQUEST_BIO:
rbd_assert(obj_request->bio_list != NULL);
osd_req->r_bio = obj_request->bio_list;
bio_get(osd_req->r_bio);
/* osd client requires "num pages" even for bio */
osd_req->r_num_pages = calc_pages_for(offset, length);
break;
Expand Down Expand Up @@ -4149,6 +4148,11 @@ int __init rbd_init(void)
{
int rc;

if (!libceph_compatible(NULL)) {
rbd_warn(NULL, "libceph incompatibility (quitting)");

return -EINVAL;
}
rc = rbd_sysfs_init();
if (rc)
return rc;
Expand Down
2 changes: 1 addition & 1 deletion net/ceph/ceph_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
*/
bool libceph_compatible(void *data)
{
return false;
return true;
}
EXPORT_SYMBOL(libceph_compatible);

Expand Down
4 changes: 0 additions & 4 deletions net/ceph/osd_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,6 @@ void ceph_osdc_release_request(struct kref *kref)
if (req->r_own_pages)
ceph_release_page_vector(req->r_pages,
req->r_num_pages);
#ifdef CONFIG_BLOCK
if (req->r_bio)
bio_put(req->r_bio);
#endif
ceph_put_snap_context(req->r_snapc);
ceph_pagelist_release(&req->r_trail);
if (req->r_mempool)
Expand Down

0 comments on commit 1e32d34

Please sign in to comment.