osd/OSDMap.cc
common/histogram.cc
osd/osd_types.cc
+ osd/OpRequest.cc
common/blkdev.cc
common/common_init.cc
common/pipe.c
if(${WITH_LTTNG})
add_subdirectory(tracing)
+ add_dependencies(common-objs oprequest-tp)
endif(${WITH_LTTNG})
add_subdirectory(global)
void OpTracker::unregister_inflight_op(TrackedOp *i)
{
// caller checks;
- assert(i->is_tracked);
+ assert(i->state);
uint32_t shard_index = i->seq % num_optracker_shards;
ShardedTrackingData* sdata = sharded_in_flight_list[shard_index];
if (!tracking_enabled)
delete i;
else {
+ i->state = TrackedOp::STATE_HISTORY;
utime_t now = ceph_clock_now();
history.insert(now, TrackedOpRef(i));
}
void OpTracker::mark_event(TrackedOp *op, const string &dest, utime_t time)
{
- if (!op->is_tracked)
+ if (!op->state)
return;
return _mark_event(op, dest, time);
}
}
-void OpTracker::RemoveOnDelete::operator()(TrackedOp *op) {
- if (!op->is_tracked) {
- op->_unregistered();
- delete op;
- return;
- }
- op->mark_event("done");
- tracker->unregister_inflight_op(op);
- // Do not delete op, unregister_inflight_op took control
-}
-
void TrackedOp::mark_event(const string &event)
{
- if (!is_tracked)
+ if (!state)
return;
utime_t now = ceph_clock_now();
void TrackedOp::dump(utime_t now, Formatter *f) const
{
// Ignore if still in the constructor
- if (!is_tracked)
+ if (!state)
return;
stringstream name;
_dump_op_descriptor_unlocked(name);
#include <atomic>
class TrackedOp;
-typedef ceph::shared_ptr<TrackedOp> TrackedOpRef;
+typedef boost::intrusive_ptr<TrackedOp> TrackedOpRef;
class OpHistory {
set<pair<utime_t, TrackedOpRef> > arrived;
struct ShardedTrackingData;
class OpTracker {
- class RemoveOnDelete {
- OpTracker *tracker;
- public:
- explicit RemoveOnDelete(OpTracker *tracker) : tracker(tracker) {}
- void operator()(TrackedOp *op);
- };
- friend class RemoveOnDelete;
friend class OpHistory;
atomic64_t seq;
vector<ShardedTrackingData*> sharded_in_flight_list;
template <typename T, typename U>
typename T::Ref create_request(U params)
{
- typename T::Ref retval(new T(params, this),
- RemoveOnDelete(this));
+ typename T::Ref retval(new T(params, this));
retval->tracking_start();
return retval;
}
friend class OpTracker;
xlist<TrackedOp*>::item xitem;
protected:
- OpTracker *tracker; /// the tracker we are associated with
+ OpTracker *tracker; ///< the tracker we are associated with
+ std::atomic_int nref = {0}; ///< ref count
utime_t initiated_at;
list<pair<utime_t, string> > events; /// list of events and their times
uint64_t seq; /// a unique value set by the OpTracker
uint32_t warn_interval_multiplier; // limits output of a given op warning
- // Transitions from false -> true without locks being held
- atomic<bool> is_tracked; //whether in tracker and out of constructor
+
+ enum {
+ STATE_UNTRACKED = 0,
+ STATE_LIVE,
+ STATE_HISTORY
+ };
+ atomic<int> state = {STATE_UNTRACKED};
+
TrackedOp(OpTracker *_tracker, const utime_t& initiated) :
xitem(this),
tracker(_tracker),
initiated_at(initiated),
lock("TrackedOp::lock"),
seq(0),
- warn_interval_multiplier(1),
- is_tracked(false)
+ warn_interval_multiplier(1)
{ }
/// output any type-specific data you want to get when dump() is called
void tracking_start() {
if (tracker->register_inflight_op(&xitem)) {
events.push_back(make_pair(initiated_at, "initiated"));
- is_tracked = true;
+ state = STATE_LIVE;
+ }
+ }
+
+ // ref counting via intrusive_ptr, with special behavior on final
+ // put for historical op tracking
+ friend void intrusive_ptr_add_ref(TrackedOp *o) {
+ ++o->nref;
+ }
+ friend void intrusive_ptr_release(TrackedOp *o) {
+ if (--o->nref == 0) {
+ switch (o->state.load()) {
+ case STATE_UNTRACKED:
+ o->_unregistered();
+ delete o;
+ break;
+
+ case STATE_LIVE:
+ o->mark_event("done");
+ o->tracker->unregister_inflight_op(o);
+ break;
+
+ case STATE_HISTORY:
+ delete o;
+ break;
+
+ default:
+ ceph_abort();
+ }
}
}
};
#include "LocalLock.h"
#include "Capability.h"
#include "SnapRealm.h"
+#include "Mutation.h"
#include <list>
#include <set>
class MClientCaps;
struct ObjectOperation;
class EMetaBlob;
-struct MDRequestImpl;
-typedef ceph::shared_ptr<MDRequestImpl> MDRequestRef;
ostream& operator<<(ostream& out, const CInode& in);
class ScatterLock;
class LocalLock;
-class MDCache;
-typedef ceph::shared_ptr<MDRequestImpl> MDRequestRef;
-
#include "SimpleLock.h"
+#include "Mutation.h"
class Locker {
private:
}
// can cast only because i'm passing nowait=true in the sole user
- MDRequestRef mdmut =
- ceph::static_pointer_cast<MDRequestImpl,MutationImpl>(mut);
+ MDRequestRef mdmut = static_cast<MDRequestImpl*>(mut.get());
if (!stop &&
mut->wrlocks.count(&pin->nestlock) == 0 &&
(!pin->versionlock.can_wrlock() || // make sure we can take versionlock, too
#include "StrayManager.h"
#include "MDSContext.h"
#include "MDSMap.h"
+#include "Mutation.h"
#include "messages/MClientRequest.h"
#include "messages/MMDSSlaveRequest.h"
class ESubtreeMap;
-struct MDRequestImpl;
-typedef ceph::shared_ptr<MDRequestImpl> MDRequestRef;
-struct MDSlaveUpdate;
-
enum {
l_mdc_first = 3000,
// How many inodes currently in stray dentries
// drop locks
if (state == EXPORT_LOCKING || state == EXPORT_DISCOVERING) {
- MDRequestRef mdr = ceph::static_pointer_cast<MDRequestImpl, MutationImpl>(mut);
+ MDRequestRef mdr = static_cast<MDRequestImpl*>(mut.get());
assert(mdr);
if (mdr->more()->waiting_on_slave.empty())
mds->mdcache->request_finish(mdr);
} else {
assert(it->second.state == EXPORT_DISCOVERING);
// release locks to avoid deadlock
- MDRequestRef mdr = ceph::static_pointer_cast<MDRequestImpl,
- MutationImpl>(it->second.mut);
+ MDRequestRef mdr = static_cast<MDRequestImpl*>(it->second.mut.get());
assert(mdr);
mds->mdcache->request_finish(mdr);
it->second.mut.reset();
return out;
}
-typedef ceph::shared_ptr<MutationImpl> MutationRef;
+typedef boost::intrusive_ptr<MutationImpl> MutationRef;
void dump(Formatter *f) const override;
// TrackedOp stuff
- typedef ceph::shared_ptr<MDRequestImpl> Ref;
+ typedef boost::intrusive_ptr<MDRequestImpl> Ref;
protected:
void _dump(Formatter *f) const;
void _dump_op_descriptor_unlocked(ostream& stream) const;
};
-typedef ceph::shared_ptr<MDRequestImpl> MDRequestRef;
+typedef boost::intrusive_ptr<MDRequestImpl> MDRequestRef;
struct MDSlaveUpdate {
#define CEPH_MDS_SERVER_H
#include "MDSRank.h"
+#include "Mutation.h"
class OSDMap;
class PerfCounters;
class MClientReply;
class MDLog;
-struct MutationImpl;
-struct MDRequestImpl;
-typedef ceph::shared_ptr<MutationImpl> MutationRef;
-typedef ceph::shared_ptr<MDRequestImpl> MDRequestRef;
-
enum {
l_mdss_first = 1000,
l_mdss_handle_client_request,
#ifndef CEPH_SIMPLELOCK_H
#define CEPH_SIMPLELOCK_H
+#include <boost/intrusive_ptr.hpp>
+
#include "MDSCacheObject.h"
#include "MDSContext.h"
}
#include "include/memory.h"
+
struct MutationImpl;
-typedef ceph::shared_ptr<MutationImpl> MutationRef;
+typedef boost::intrusive_ptr<MutationImpl> MutationRef;
extern "C" {
#include "locks.h"
return (con && con->get_peer_type() & CEPH_ENTITY_TYPE_MON);
}
- typedef ceph::shared_ptr<MonOpRequest> Ref;
+ typedef boost::intrusive_ptr<MonOpRequest> Ref;
void set_op_type(op_type_t t) {
op_type = t;
OSD.cc
Watch.cc
ClassHandler.cc
- OpRequest.cc
PG.cc
PGLog.cc
PrimaryLogPG.cc
$<TARGET_OBJECTS:common_util_obj>)
target_link_libraries(osd ${LEVELDB_LIBRARIES} ${CMAKE_DL_LIBS} ${ALLOC_LIBS})
if(WITH_LTTNG)
- add_dependencies(osd oprequest-tp osd-tp pg-tp)
+ add_dependencies(osd osd-tp pg-tp)
endif()
if(WITH_LTTNG AND WITH_EVENTTRACE)
add_dependencies(osd eventtrace_tp)
return reqid;
}
- typedef ceph::shared_ptr<OpRequest> Ref;
+ typedef boost::intrusive_ptr<OpRequest> Ref;
private:
void set_rmw_flags(int flags);