if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
return;
+ // prepare
+ if (!mdr->more()->stid) {
+ mds->snapclient->prepare_update(diri->ino(), snapid, dstname, utime_t(),
+ &mdr->more()->stid, &mdr->more()->snapidbl,
+ new C_MDS_RetryRequest(mds->mdcache, mdr));
+ return;
+ }
+
+ version_t stid = mdr->more()->stid;
+ bufferlist::iterator p = mdr->more()->snapidbl.begin();
+ snapid_t seq;
+ ::decode(seq, p);
+ dout(10) << " stid is " << stid << ", seq is " << seq << dendl;
+
// journal
inode_t *pi = diri->project_inode();
pi->ctime = mdr->get_op_stamp();
mdlog->start_entry(le);
le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid());
+ le->metablob.add_table_transaction(TABLE_SNAP, stid);
mdcache->predirty_journal_parents(mdr, &le->metablob, diri, 0, PREDIRTY_PRIMARY, false);
mdcache->journal_dirty_inode(mdr.get(), &le->metablob, diri);
diri->pop_and_dirty_projected_inode(mdr->ls);
mdr->apply();
+ mds->snapclient->commit(mdr->more()->stid, mdr->ls);
+
dout(10) << "snaprealm now " << *diri->snaprealm << dendl;
mdcache->do_realm_invalidate_and_update_notify(diri, CEPH_SNAP_OP_CREATE, true);
::decode(info.name, p);
::decode(info.stamp, p);
info.snapid = ++last_snap;
- pending_create[version] = info;
+ info.long_name = "create";
+ pending_update[version] = info;
dout(10) << "prepare v" << version << " create " << info << dendl;
} else {
pending_noop.insert(version);
}
break;
+ case TABLE_OP_UPDATE:
+ {
+ SnapInfo info;
+ ::decode(info.ino, p);
+ ::decode(info.snapid, p);
+ ::decode(info.name, p);
+ ::decode(info.stamp, p);
+ info.long_name = "update";
+
+ version++;
+ // bump last_snap... we use it as a version value on the snaprealm.
+ ++last_snap;
+ pending_update[version] = info;
+ dout(10) << "prepare v" << version << " update " << info << dendl;
+
+ bl.clear();
+ ::encode(last_snap, bl);
+ }
+ break;
+
default:
assert(0);
}
bool SnapServer::_is_prepared(version_t tid)
{
return
- pending_create.count(tid) ||
+ pending_update.count(tid) ||
pending_destroy.count(tid);
}
bool SnapServer::_commit(version_t tid, MMDSTableRequest *req)
{
- if (pending_create.count(tid)) {
- dout(7) << "commit " << tid << " create " << pending_create[tid] << dendl;
- snaps[pending_create[tid].snapid] = pending_create[tid];
- pending_create.erase(tid);
- }
+ if (pending_update.count(tid)) {
+ SnapInfo &info = pending_update[tid];
+ string opname;
+ if (info.long_name.empty())
+ opname = "create";
+ else
+ opname.swap(info.long_name);
+ if (info.stamp == utime_t() && snaps.count(info.snapid))
+ info.stamp = snaps[info.snapid].stamp;
+ dout(7) << "commit " << tid << " " << opname << " " << info << dendl;
+ snaps[info.snapid] = info;
+ pending_update.erase(tid);
+ }
else if (pending_destroy.count(tid)) {
snapid_t sn = pending_destroy[tid].first;
void SnapServer::_rollback(version_t tid)
{
- if (pending_create.count(tid)) {
- dout(7) << "rollback " << tid << " create " << pending_create[tid] << dendl;
- pending_create.erase(tid);
+ if (pending_update.count(tid)) {
+ SnapInfo &info = pending_update[tid];
+ string opname;
+ if (info.long_name.empty())
+ opname = "create";
+ else
+ opname.swap(info.long_name);
+ dout(7) << "rollback " << tid << " " << opname << " " << info << dendl;
+ pending_update.erase(tid);
}
else if (pending_destroy.count(tid)) {
}
f->close_section();
- f->open_array_section("pending_create");
- for(map<version_t, SnapInfo>::const_iterator i = pending_create.begin(); i != pending_create.end(); ++i) {
+ f->open_array_section("pending_update");
+ for(map<version_t, SnapInfo>::const_iterator i = pending_update.begin(); i != pending_update.end(); ++i) {
f->open_object_section("snap");
f->dump_unsigned("version", i->first);
f->open_object_section("snapinfo");
populated->last_snap = 123;
populated->snaps[456] = populated_snapinfo;
populated->need_to_purge[2].insert(012);
- populated->pending_create[234] = populated_snapinfo;
+ populated->pending_update[234] = populated_snapinfo;
populated->pending_destroy[345].first = 567;
populated->pending_destroy[345].second = 768;
populated->pending_noop.insert(890);
map<snapid_t, SnapInfo> snaps;
map<int, set<snapid_t> > need_to_purge;
- map<version_t, SnapInfo> pending_create;
+ map<version_t, SnapInfo> pending_update;
map<version_t, pair<snapid_t,snapid_t> > pending_destroy; // (removed_snap, seq)
set<version_t> pending_noop;
::encode(last_snap, bl);
::encode(snaps, bl);
::encode(need_to_purge, bl);
- ::encode(pending_create, bl);
+ ::encode(pending_update, bl);
::encode(pending_destroy, bl);
::encode(pending_noop, bl);
ENCODE_FINISH(bl);
::decode(last_snap, bl);
::decode(snaps, bl);
::decode(need_to_purge, bl);
- ::decode(pending_create, bl);
+ ::decode(pending_update, bl);
if (struct_v >= 2)
::decode(pending_destroy, bl);
else {