* Ceph - scalable distributed file system
*
* Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
+ *
+ * Author: Loic Dachary <loic@dachary.org>
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
return;
}
- ObjectContext *obc;
+ ObjectContextRef obc;
bool can_create = op->may_write();
snapid_t snapid;
int r = find_object_context(
}
// src_oids
- map<hobject_t,ObjectContext*> src_obc;
+ map<hobject_t,ObjectContextRef> src_obc;
for (vector<OSDOp>::iterator p = m->ops.begin(); p != m->ops.end(); ++p) {
OSDOp& osd_op = *p;
hobject_t src_oid(osd_op.soid, src_oloc.key, m->get_pg().ps(),
info.pgid.pool(), m->get_object_locator().nspace);
if (!src_obc.count(src_oid)) {
- ObjectContext *sobc;
+ ObjectContextRef sobc;
snapid_t ssnapid;
int r = find_object_context(src_oid, &sobc, false, &ssnapid);
hobject_t clone_oid = obc->obs.oi.soid;
clone_oid.snap = *p;
if (!src_obc.count(clone_oid)) {
- ObjectContext *sobc;
+ ObjectContextRef sobc;
snapid_t ssnapid;
int r = find_object_context(clone_oid, &sobc, false, &ssnapid);
dout(10) << " taking ondisk_read_lock" << dendl;
obc->ondisk_read_lock();
}
- for (map<hobject_t,ObjectContext*>::iterator p = src_obc.begin(); p != src_obc.end(); ++p) {
+ for (map<hobject_t,ObjectContextRef>::iterator p = src_obc.begin(); p != src_obc.end(); ++p) {
dout(10) << " taking ondisk_read_lock for src " << p->first << dendl;
p->second->ondisk_read_lock();
}
dout(10) << " dropping ondisk_read_lock" << dendl;
obc->ondisk_read_unlock();
}
- for (map<hobject_t,ObjectContext*>::iterator p = src_obc.begin(); p != src_obc.end(); ++p) {
+ for (map<hobject_t,ObjectContextRef>::iterator p = src_obc.begin(); p != src_obc.end(); ++p) {
dout(10) << " dropping ondisk_read_lock for src " << p->first << dendl;
p->second->ondisk_read_unlock();
}
{
// load clone info
bufferlist bl;
- ObjectContext *obc = 0;
+ ObjectContextRef obc;
int r = find_object_context(coid, &obc, false, NULL);
if (r == -ENOENT || coid.snap != obc->obs.oi.soid.snap) {
derr << __func__ << "could not find coid " << coid << dendl;
ctx->user_modify = true;
}
- ObjectContext *src_obc = 0;
+ ObjectContextRef src_obc;
if (ceph_osd_op_type_multi(op.op)) {
MOSDOp *m = static_cast<MOSDOp *>(ctx->op->request);
object_locator_t src_oloc;
hobject_t clone_oid = soid;
clone_oid.snap = *clone_iter;
- ObjectContext *clone_obc = ctx->src_obc[clone_oid];
+ ObjectContextRef clone_obc = ctx->src_obc[clone_oid];
assert(clone_obc);
for (vector<snapid_t>::reverse_iterator p = clone_obc->obs.oi.snaps.rbegin();
p != clone_obc->obs.oi.snaps.rend();
uint64_t cookie = op.watch.cookie;
bool do_watch = op.watch.flag & 1;
entity_name_t entity = ctx->reqid.name;
- ObjectContext *obc = ctx->obc;
+ ObjectContextRef obc = ctx->obc;
- dout(10) << "watch: ctx->obc=" << (void *)obc << " cookie=" << cookie
+ dout(10) << "watch: ctx->obc=" << (void *)obc.get() << " cookie=" << cookie
<< " oi.version=" << oi.version.version << " ctx->at_version=" << ctx->at_version << dendl;
dout(10) << "watch: oi.user_version=" << oi.user_version.version << dendl;
dout(10) << "watch: peer_addr="
dout(10) << "_rollback_to " << soid << " snapid " << snapid << dendl;
- ObjectContext *rollback_to;
+ ObjectContextRef rollback_to;
int ret = find_object_context(
hobject_t(soid.oid, soid.get_key(), snapid, soid.hash, info.pgid.pool(), soid.get_namespace()),
&rollback_to, false, &cloneid);
if (repop->ctx->clone_obc) {
put_object_context(repop->ctx->clone_obc);
- repop->ctx->clone_obc = 0;
+ repop->ctx->clone_obc = ObjectContextRef();
}
if (repop->ctx->snapset_obc) {
- put_object_context(repop->ctx->snapset_obc);
- repop->ctx->snapset_obc = 0;
+ repop->ctx->snapset_obc = ObjectContextRef();
}
put_object_context(repop->obc);
put_object_contexts(repop->src_obc);
- repop->obc = 0;
+ repop->src_obc.clear();
+ repop->obc = ObjectContextRef();
if (!repop->aborted) {
assert(repop->waitfor_ack.count(whoami) ||
}
}
-ReplicatedPG::RepGather *ReplicatedPG::new_repop(OpContext *ctx, ObjectContext *obc,
+ReplicatedPG::RepGather *ReplicatedPG::new_repop(OpContext *ctx, ObjectContextRef obc,
tid_t rep_tid)
{
if (ctx->op)
}
}
-void ReplicatedPG::get_obc_watchers(ObjectContext *obc, list<obj_watch_item_t> &pg_watchers)
+void ReplicatedPG::get_obc_watchers(ObjectContextRef obc, list<obj_watch_item_t> &pg_watchers)
{
for (map<pair<uint64_t, entity_name_t>, WatchRef>::iterator j =
obc->watchers.begin();
}
}
-void ReplicatedPG::check_blacklisted_obc_watchers(ObjectContext *obc)
+void ReplicatedPG::check_blacklisted_obc_watchers(ObjectContextRef obc)
{
dout(20) << "ReplicatedPG::check_blacklisted_obc_watchers for obc " << obc->obs.oi.soid << dendl;
for (map<pair<uint64_t, entity_name_t>, WatchRef>::iterator k =
}
}
-void ReplicatedPG::populate_obc_watchers(ObjectContext *obc)
+void ReplicatedPG::populate_obc_watchers(ObjectContextRef obc)
{
assert(is_active());
assert(!is_missing_object(obc->obs.oi.soid) ||
void ReplicatedPG::handle_watch_timeout(WatchRef watch)
{
- ObjectContext *obc = watch->get_obc(); // handle_watch_timeout owns this ref
+ ObjectContextRef obc = watch->get_obc(); // handle_watch_timeout owns this ref
dout(10) << "handle_watch_timeout obc " << obc << dendl;
if (is_degraded_object(obc->obs.oi.soid)) {
return NULL;
}
-ObjectContext *ReplicatedPG::create_object_context(const object_info_t& oi,
- SnapSetContext *ssc)
+ObjectContextRef ReplicatedPG::create_object_context(const object_info_t& oi,
+ SnapSetContext *ssc)
{
ObjectContext *obc = new ObjectContext(oi, false, ssc);
dout(10) << "create_object_context " << obc << " " << oi.soid << " " << obc->ref << dendl;
return obc;
}
-ObjectContext *ReplicatedPG::get_object_context(const hobject_t& soid,
- bool can_create)
+ObjectContextRef ReplicatedPG::get_object_context(const hobject_t& soid,
+ bool can_create)
{
map<hobject_t, ObjectContext*>::iterator p = object_contexts.find(soid);
ObjectContext *obc;
int r = osd->store->getattr(coll, soid, OI_ATTR, bv);
if (r < 0) {
if (!can_create)
- return NULL; // -ENOENT!
+ return ObjectContextRef(); // -ENOENT!
// new object.
object_info_t oi(soid);
int ReplicatedPG::find_object_context(const hobject_t& oid,
- ObjectContext **pobc,
+ ObjectContextRef *pobc,
bool can_create,
snapid_t *psnapid)
{
// want the snapdir?
if (oid.snap == CEPH_SNAPDIR) {
// return head or snapdir, whichever exists.
- ObjectContext *obc = get_object_context(head, can_create);
+ ObjectContextRef obc = get_object_context(head, can_create);
if (obc && !obc->obs.exists) {
// ignore it if the obc exists but the object doesn't
put_object_context(obc);
- obc = NULL;
+ obc = ObjectContextRef();
}
if (!obc) {
obc = get_object_context(snapdir, can_create);
// want the head?
if (oid.snap == CEPH_NOSNAP) {
- ObjectContext *obc = get_object_context(head, can_create);
+ ObjectContextRef obc = get_object_context(head, can_create);
if (!obc)
return -ENOENT;
dout(10) << "find_object_context " << oid << " @" << oid.snap << dendl;
// head?
if (oid.snap > ssc->snapset.seq) {
if (ssc->snapset.head_exists) {
- ObjectContext *obc = get_object_context(head, false);
+ ObjectContextRef obc = get_object_context(head, false);
dout(10) << "find_object_context " << head
<< " want " << oid.snap << " > snapset seq " << ssc->snapset.seq
<< " -- HIT " << obc->obs
return -EAGAIN;
}
- ObjectContext *obc = get_object_context(soid, false);
+ ObjectContextRef obc = get_object_context(soid, false);
assert(obc);
// clone
// ===========================================================
-void ReplicatedPG::calc_head_subsets(ObjectContext *obc, SnapSet& snapset, const hobject_t& head,
+void ReplicatedPG::calc_head_subsets(ObjectContextRef obc, SnapSet& snapset, const hobject_t& head,
pg_missing_t& missing,
const hobject_t &last_backfill,
interval_set<uint64_t>& data_subset,
* clones/heads and dup data ranges where possible.
*/
void ReplicatedPG::prep_push_to_replica(
- ObjectContext *obc, const hobject_t& soid, int peer,
+ ObjectContextRef obc, const hobject_t& soid, int peer,
int prio,
PushOp *pop)
{
}
void ReplicatedPG::prep_push(int prio,
- ObjectContext *obc,
+ ObjectContextRef obc,
const hobject_t& soid, int peer,
PushOp *pop)
{
void ReplicatedPG::prep_push(
int prio,
- ObjectContext *obc,
+ ObjectContextRef obc,
const hobject_t& soid, int peer,
eversion_t version,
interval_set<uint64_t> &data_subset,
hoid.get_namespace());
assert(ssc);
}
- ObjectContext *obc = create_object_context(pi.recovery_info.oi, ssc);
+ ObjectContextRef obc = create_object_context(pi.recovery_info.oi, ssc);
obc->obs.exists = true;
obc->ondisk_write_lock();
j != i->second->blocking.end();
i->second->blocking.erase(j++)) {
dout(10) << " no longer blocking writes for " << (*j)->obs.oi.soid << dendl;
- (*j)->blocked_by = NULL;
+ (*j)->blocked_by = ObjectContextRef();
put_object_context(*j);
put_object_context(i->second);
}
unlock();
}
-void ReplicatedPG::_applied_recovered_object(ObjectContext *obc)
+void ReplicatedPG::_applied_recovered_object(ObjectContextRef obc)
{
lock();
dout(10) << "_applied_recovered_object " << *obc << dendl;
/* Mark an object as lost
*/
-ObjectContext *ReplicatedPG::mark_object_lost(ObjectStore::Transaction *t,
+ObjectContextRef ReplicatedPG::mark_object_lost(ObjectStore::Transaction *t,
const hobject_t &oid, eversion_t version,
utime_t mtime, int what)
{
pg_log_entry_t e(what, oid, info.last_update, version, osd_reqid_t(), mtime);
pg_log.add(e);
- ObjectContext *obc = get_object_context(oid, true);
+ ObjectContextRef obc = get_object_context(oid, true);
obc->ondisk_write_lock();
struct C_PG_MarkUnfoundLost : public Context {
ReplicatedPGRef pg;
- list<ObjectContext*> obcs;
+ list<ObjectContextRef> obcs;
C_PG_MarkUnfoundLost(ReplicatedPG *p) : pg(p) {}
void finish(int r) {
pg->_finish_mark_all_unfound_lost(obcs);
continue;
}
- ObjectContext *obc = NULL;
+ ObjectContextRef obc;
eversion_t prev;
switch (what) {
osd->queue_for_recovery(this);
}
-void ReplicatedPG::_finish_mark_all_unfound_lost(list<ObjectContext*>& obcs)
+void ReplicatedPG::_finish_mark_all_unfound_lost(list<ObjectContextRef>& obcs)
{
lock();
dout(10) << "_finish_mark_all_unfound_lost " << dendl;
case pg_log_entry_t::LOST_REVERT:
{
if (item.have == latest->reverting_to) {
- ObjectContext *obc = get_object_context(soid, true);
+ ObjectContextRef obc = get_object_context(soid, true);
if (obc->obs.oi.version == latest->version) {
// I'm already reverting
dout(10) << __func__ << ": on " << soid << dendl;
// NOTE: we know we will get a valid oloc off of disk here.
- ObjectContext *obc = get_object_context(soid, false);
+ ObjectContextRef obc = get_object_context(soid, false);
if (!obc) {
pg_log.missing_add(soid, v, eversion_t());
bool uhoh = true;
for (set<hobject_t>::iterator i = add_to_stat.begin();
i != add_to_stat.end();
++i) {
- ObjectContext *obc = get_object_context(*i, false);
+ ObjectContextRef obc = get_object_context(*i, false);
pg_stat_t stat;
add_object_context_to_pg_stat(obc, &stat);
pending_backfill_updates[*i] = stat;
if (!pushing.count(oid))
start_recovery_op(oid);
- ObjectContext *obc = get_object_context(oid, false);
+ ObjectContextRef obc = get_object_context(oid, false);
obc->ondisk_read_lock();
(*pushes)[peer].push_back(PushOp());
prep_push_to_replica(obc, oid, peer, g_conf->osd_recovery_op_priority,
for (vector<hobject_t>::iterator p = ls.begin(); p != ls.end(); ++p) {
handle.reset_tp_timeout();
- ObjectContext *obc = NULL;
+ ObjectContextRef obc;
if (is_primary())
obc = _lookup_object_context(*p);
if (obc) {
* Ceph - scalable distributed file system
*
* Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
+ *
+ * Author: Loic Dachary <loic@dachary.org>
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include "messages/MOSDOp.h"
#include "messages/MOSDOpReply.h"
#include "messages/MOSDSubOp.h"
+
+#include "common/sharedptr_registry.hpp"
+
class MOSDSubOpReply;
class ReplicatedPG;
vector<pg_log_entry_t> log;
interval_set<uint64_t> modified_ranges;
- ObjectContext *obc; // For ref counting purposes
- map<hobject_t,ObjectContext*> src_obc;
- ObjectContext *clone_obc; // if we created a clone
- ObjectContext *snapset_obc; // if we created/deleted a snapdir
+ ObjectContextRef obc;
+ map<hobject_t,ObjectContextRef> src_obc;
+ ObjectContextRef clone_obc; // if we created a clone
+ ObjectContextRef snapset_obc; // if we created/deleted a snapdir
int data_off; // FIXME: we may want to kill this msgr hint off at some point!
modify(false), user_modify(false),
bytes_written(0), bytes_read(0),
current_osd_subop_num(0),
- obc(0), clone_obc(0), snapset_obc(0), data_off(0), reply(NULL), pg(_pg),
+ data_off(0), reply(NULL), pg(_pg),
num_read(0),
num_write(0) {
if (_ssc) {
eversion_t v;
OpContext *ctx;
- ObjectContext *obc;
- map<hobject_t,ObjectContext*> src_obc;
+ ObjectContextRef obc;
+ map<hobject_t,ObjectContextRef> src_obc;
tid_t rep_tid;
list<ObjectStore::Transaction*> tls;
bool queue_snap_trimmer;
- RepGather(OpContext *c, ObjectContext *pi, tid_t rt,
+ RepGather(OpContext *c, ObjectContextRef pi, tid_t rt,
eversion_t lc) :
queue_item(this),
nref(1),
void eval_repop(RepGather*);
void issue_repop(RepGather *repop, utime_t now,
eversion_t old_last_update, bool old_exists, uint64_t old_size, eversion_t old_version);
- RepGather *new_repop(OpContext *ctx, ObjectContext *obc, tid_t rep_tid);
+ RepGather *new_repop(OpContext *ctx, ObjectContextRef obc, tid_t rep_tid);
void remove_repop(RepGather *repop);
void repop_ack(RepGather *repop,
int result, int ack_type,
friend struct C_OnPushCommit;
// projected object info
- map<hobject_t, ObjectContext*> object_contexts;
+ SharedPtrRegistry<hobject_t, ObjectContext> object_contexts;
map<object_t, SnapSetContext*> snapset_contexts;
Mutex snapset_contexts_lock;
// debug order that client ops are applied
map<hobject_t, map<client_t, tid_t> > debug_op_order;
- void populate_obc_watchers(ObjectContext *obc);
- void check_blacklisted_obc_watchers(ObjectContext *);
+ void populate_obc_watchers(ObjectContextRef obc);
+ void check_blacklisted_obc_watchers(ObjectContextRef obc);
void check_blacklisted_watchers();
void get_watchers(list<obj_watch_item_t> &pg_watchers);
- void get_obc_watchers(ObjectContext *obc, list<obj_watch_item_t> &pg_watchers);
+ void get_obc_watchers(ObjectContextRef obc, list<obj_watch_item_t> &pg_watchers);
public:
void handle_watch_timeout(WatchRef watch);
protected:
return NULL;
}
ObjectContext *_lookup_object_context(const hobject_t& oid);
- ObjectContext *create_object_context(const object_info_t& oi, SnapSetContext *ssc);
- ObjectContext *get_object_context(const hobject_t& soid, bool can_create);
+ ObjectContextRef create_object_context(const object_info_t& oi, SnapSetContext *ssc);
+ ObjectContextRef get_object_context(const hobject_t& soid, bool can_create);
void register_object_context(ObjectContext *obc) {
if (!obc->registered) {
assert(object_contexts.count(obc->obs.oi.soid) == 0);
void put_object_context(ObjectContext *obc);
void put_object_contexts(map<hobject_t,ObjectContext*>& obcv);
int find_object_context(const hobject_t& oid,
- ObjectContext **pobc,
+ ObjectContextRef *pobc,
bool can_create, snapid_t *psnapid=NULL);
- void add_object_context_to_pg_stat(ObjectContext *obc, pg_stat_t *stat);
+ void add_object_context_to_pg_stat(ObjectContextRef obc, pg_stat_t *stat);
void get_src_oloc(const object_t& oid, const object_locator_t& oloc, object_locator_t& src_oloc);
int prep_object_replica_pushes(const hobject_t& soid, eversion_t v,
int priority,
map<int, vector<PushOp> > *pushes);
- void calc_head_subsets(ObjectContext *obc, SnapSet& snapset, const hobject_t& head,
+ void calc_head_subsets(ObjectContextRef obc, SnapSet& snapset, const hobject_t& head,
pg_missing_t& missing,
const hobject_t &last_backfill,
interval_set<uint64_t>& data_subset,
interval_set<uint64_t>& data_subset,
map<hobject_t, interval_set<uint64_t> >& clone_subsets);
void prep_push_to_replica(
- ObjectContext *obc,
+ ObjectContextRef obc,
const hobject_t& oid,
int dest,
int priority,
PushOp *push_op);
void prep_push(int priority,
- ObjectContext *obc,
+ ObjectContextRef obc,
const hobject_t& oid, int dest,
PushOp *op);
void prep_push(int priority,
- ObjectContext *obc,
+ ObjectContextRef obc,
const hobject_t& soid, int peer,
eversion_t version,
interval_set<uint64_t> &data_subset,
}
};
struct C_OSD_OndiskWriteUnlock : public Context {
- ObjectContext *obc, *obc2;
- C_OSD_OndiskWriteUnlock(ObjectContext *o, ObjectContext *o2=0) : obc(o), obc2(o2) {}
+ ObjectContextRef obc, obc2;
+ C_OSD_OndiskWriteUnlock(ObjectContextRef o, ObjectContextRef o2 = ObjectContextRef()) : obc(o), obc2(o2) {}
void finish(int r) {
obc->ondisk_write_unlock();
if (obc2)
}
};
struct C_OSD_OndiskWriteUnlockList : public Context {
- list<ObjectContext*> *pls;
- C_OSD_OndiskWriteUnlockList(list<ObjectContext*> *l) : pls(l) {}
+ list<ObjectContextRef> *pls;
+ C_OSD_OndiskWriteUnlockList(list<ObjectContextRef> *l) : pls(l) {}
void finish(int r) {
- for (list<ObjectContext*>::iterator p = pls->begin(); p != pls->end(); ++p)
+ for (list<ObjectContextRef>::iterator p = pls->begin(); p != pls->end(); ++p)
(*p)->ondisk_write_unlock();
}
};
struct C_OSD_AppliedRecoveredObject : public Context {
ReplicatedPGRef pg;
- ObjectContext *obc;
- C_OSD_AppliedRecoveredObject(ReplicatedPG *p, ObjectContext *o) :
+ ObjectContextRef obc;
+ C_OSD_AppliedRecoveredObject(ReplicatedPG *p, ObjectContextRef o) :
pg(p), obc(o) {}
void finish(int r) {
pg->_applied_recovered_object(obc);
void sub_op_modify_commit(RepModify *rm);
void sub_op_modify_reply(OpRequestRef op);
- void _applied_recovered_object(ObjectContext *obc);
+ void _applied_recovered_object(ObjectContextRef obc);
void _applied_recovered_object_replica();
void _committed_pushed_object(epoch_t epoch, eversion_t lc);
void recover_got(hobject_t oid, eversion_t v);
void mark_all_unfound_lost(int what);
eversion_t pick_newest_available(const hobject_t& oid);
- ObjectContext *mark_object_lost(ObjectStore::Transaction *t,
+ ObjectContextRef mark_object_lost(ObjectStore::Transaction *t,
const hobject_t& oid, eversion_t version,
utime_t mtime, int what);
- void _finish_mark_all_unfound_lost(list<ObjectContext*>& obcs);
+ void _finish_mark_all_unfound_lost(list<ObjectContextRef>& obcs);
void on_role_change();
void on_change(ObjectStore::Transaction *t);