From 783fc66a000a47f94db5e2eb456b94b51042b6cc Mon Sep 17 00:00:00 2001 From: Sebastien Ponce Date: Mon, 8 Sep 2014 14:23:03 +0200 Subject: [PATCH] Fixed part of the seg fault described in bug 9356 by adding reference counting on RadosReadCompletionData Signed-off-by: Sebastien Ponce --- src/libradosstriper/RadosStriperImpl.cc | 10 +++++----- src/libradosstriper/RadosStriperImpl.h | 8 ++++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libradosstriper/RadosStriperImpl.cc b/src/libradosstriper/RadosStriperImpl.cc index 5685b2fefdbe8..3691e32fcc61c 100644 --- a/src/libradosstriper/RadosStriperImpl.cc +++ b/src/libradosstriper/RadosStriperImpl.cc @@ -392,10 +392,9 @@ static void rados_req_read_safe(rados_completion_t c, void *arg) // ENOENT means that we are dealing with a sparse file. This is fine, // data (0s) will be created on the fly by the rados_req_read_complete method if (rc == -ENOENT) rc = 0; - librados::AioCompletion *comp = reinterpret_cast(c); libradosstriper::MultiAioCompletionImpl *multiAioComp = data->m_multiAioCompl; - if (0 == comp->pc->ack) delete data; multiAioComp->safe_request(rc); + data->put(); } static void rados_req_read_complete(rados_completion_t c, void *arg) @@ -425,10 +424,9 @@ static void rados_req_read_complete(rados_completion_t c, void *arg) } rc = data->m_expectedBytes; } - librados::AioCompletion *comp = reinterpret_cast(c); libradosstriper::MultiAioCompletionImpl * multiAioComp = data->m_multiAioCompl; - if (0 == comp->pc->safe) delete data; multiAioComp->complete_request(rc); + data->put(); } int libradosstriper::RadosStriperImpl::aio_read(const std::string& soid, @@ -481,7 +479,9 @@ int libradosstriper::RadosStriperImpl::aio_read(const std::string& soid, } // read all extends of a given object in one go nc->add_request(); - RadosReadCompletionData *data = new RadosReadCompletionData(nc, p->length, oid_bl); + // we need 2 references on data as both rados_req_read_safe and rados_req_read_complete + // will release one + RadosReadCompletionData *data = new RadosReadCompletionData(nc, p->length, oid_bl, cct(), 2); librados::AioCompletion *rados_completion = m_radosCluster.aio_create_completion(data, rados_req_read_complete, rados_req_read_safe); r = m_ioCtx.aio_read(p->oid.name, rados_completion, oid_bl, p->length, p->offset); diff --git a/src/libradosstriper/RadosStriperImpl.h b/src/libradosstriper/RadosStriperImpl.h index 7f51895bbec5f..bc0203277fcd0 100644 --- a/src/libradosstriper/RadosStriperImpl.h +++ b/src/libradosstriper/RadosStriperImpl.h @@ -25,6 +25,7 @@ #include "include/radosstriper/libradosstriper.hpp" #include "librados/IoCtxImpl.h" +#include "common/RefCountedObj.h" struct libradosstriper::RadosStriperImpl { @@ -99,11 +100,14 @@ struct libradosstriper::RadosStriperImpl { * struct handling the data needed to pass to the call back * function in asynchronous read operations of a Rados File */ - struct RadosReadCompletionData { + struct RadosReadCompletionData : RefCountedObject { /// constructor RadosReadCompletionData(MultiAioCompletionImpl *multiAioCompl, uint64_t expectedBytes, - bufferlist *bl) : + bufferlist *bl, + CephContext *context, + int n = 1) : + RefCountedObject(context, n), m_multiAioCompl(multiAioCompl), m_expectedBytes(expectedBytes), m_bl(bl) {}; /// the multi asynch io completion object to be used MultiAioCompletionImpl *m_multiAioCompl; -- 2.39.5