#undef dout_prefix
#define dout_prefix *_dout << objecter->messenger->get_myname() << ".journalpointer"
+
+std::string JournalPointer::get_object_id() const
+{
+ inodeno_t const pointer_ino = MDS_INO_LOG_POINTER_OFFSET + node_id;
+ char buf[32];
+ snprintf(buf, sizeof(buf), "%llx.%08llx", (long long unsigned)pointer_ino, (long long unsigned)0);
+
+ return std::string(buf);
+}
+
+
/**
* Blocking read of JournalPointer for this MDS
*/
assert(objecter != NULL);
assert(!lock->is_locked_by_me());
- inodeno_t const pointer_ino = MDS_INO_LOG_POINTER_OFFSET + node_id;
- char buf[32];
- snprintf(buf, sizeof(buf), "%llx.%08llx", (long long unsigned)pointer_ino, (long long unsigned)0);
-
// Blocking read of data
- dout(4) << "Reading journal pointer '" << buf << "'" << dendl;
+ std::string const object_id = get_object_id();
+ dout(4) << "Reading journal pointer '" << object_id << "'" << dendl;
bufferlist data;
C_SaferCond waiter;
lock->Lock();
- objecter->read_full(object_t(buf), object_locator_t(pool_id),
+ objecter->read_full(object_t(object_id), object_locator_t(pool_id),
CEPH_NOSNAP, &data, 0, &waiter);
lock->Unlock();
int r = waiter.wait();
bufferlist::iterator q = data.begin();
decode(q);
} else {
- dout(1) << "Journal pointer '" << buf << "' read failed: " << cpp_strerror(r) << dendl;
+ dout(1) << "Journal pointer '" << object_id << "' read failed: " << cpp_strerror(r) << dendl;
}
return r;
}
// It is not valid to persist a null pointer
assert(!is_null());
- // Calculate object ID
- inodeno_t const pointer_ino = MDS_INO_LOG_POINTER_OFFSET + node_id;
- char buf[32];
- snprintf(buf, sizeof(buf), "%llx.%08llx", (long long unsigned)pointer_ino, (long long unsigned)0);
- dout(4) << "Writing pointer object '" << buf << "': 0x"
- << std::hex << front << ":0x" << back << std::dec << dendl;
-
// Serialize JournalPointer object
bufferlist data;
encode(data);
// Write to RADOS and wait for durability
+ std::string const object_id = get_object_id();
+ dout(4) << "Writing pointer object '" << object_id << "': 0x"
+ << std::hex << front << ":0x" << back << std::dec << dendl;
+
C_SaferCond waiter;
lock->Lock();
- objecter->write_full(object_t(buf), object_locator_t(pool_id),
+ objecter->write_full(object_t(object_id), object_locator_t(pool_id),
SnapContext(), data, ceph_clock_now(g_ceph_context), 0, NULL, &waiter);
lock->Unlock();
int write_result = waiter.wait();
if (write_result < 0) {
- derr << "Error writing pointer object '" << buf << "': " << cpp_strerror(write_result) << dendl;
+ derr << "Error writing pointer object '" << object_id << "': " << cpp_strerror(write_result) << dendl;
}
return write_result;
}
+
+/**
+ * Non-blocking variant of save() that assumes objecter lock already held by
+ * caller
+ */
+void JournalPointer::save(Objecter *objecter, Context *completion) const
+{
+ assert(objecter != NULL);
+
+ bufferlist data;
+ encode(data);
+
+ objecter->write_full(object_t(get_object_id()), object_locator_t(pool_id),
+ SnapContext(), data, ceph_clock_now(g_ceph_context), 0, NULL, completion);
+}
+
g_ceph_context->get_perfcounters_collection()->add(logger);
}
-void MDLog::init_journaler()
-{
- // inode
- ino = MDS_INO_LOG_OFFSET + mds->get_nodeid();
-
- // log streamer
- if (journaler) delete journaler;
- journaler = new Journaler(ino, mds->mdsmap->get_metadata_pool(), CEPH_FS_ONDISK_MAGIC, mds->objecter,
- logger, l_mdl_jlat,
- &mds->timer);
- assert(journaler->is_readonly());
- journaler->set_write_error_handler(new C_MDL_WriteError(this));
-}
-
void MDLog::handle_journaler_write_error(int r)
{
if (r == -EBLACKLISTED) {
void MDLog::create(Context *c)
{
dout(5) << "create empty log" << dendl;
- init_journaler();
+
+ C_GatherBuilder gather(g_ceph_context);
+ gather.set_finisher(c);
+
+ // The inode of the default Journaler we will create
+ ino = MDS_INO_LOG_OFFSET + mds->get_nodeid();
+
+ // Instantiate Journaler and start async write to RADOS
+ assert(journaler == NULL);
+ journaler = new Journaler(ino, mds->mdsmap->get_metadata_pool(), CEPH_FS_ONDISK_MAGIC, mds->objecter,
+ logger, l_mdl_jlat,
+ &mds->timer);
+ assert(journaler->is_readonly());
+ journaler->set_write_error_handler(new C_MDL_WriteError(this));
journaler->set_writeable();
journaler->create(&mds->mdcache->default_log_layout, g_conf->mds_journal_format);
- journaler->write_head(c);
+ journaler->write_head(gather.new_sub());
+
+ // Async write JournalPointer to RADOS
+ JournalPointer jp(mds->get_nodeid(), mds->mdsmap->get_metadata_pool());
+ jp.front = ino;
+ jp.back = 0;
+ jp.save(mds->objecter, gather.new_sub());
+
+ gather.activate();
logger->set(l_mdl_expos, journaler->get_expire_pos());
logger->set(l_mdl_wrpos, journaler->get_write_pos());