sr_t *CInode::project_snaprealm(snapid_t snapid)
{
- if (projected_srnode.empty()) {
+ sr_t *new_snaprealm;
+ if (!projected_snaprealm_ptr) {
if (snaprealm)
- projected_srnode.push_back(new sr_t(snaprealm->srnode));
+ new_snaprealm = new sr_t(snaprealm->srnode);
else {
- projected_srnode.push_back(new sr_t());
- projected_srnode.back()->created = snapid;
- projected_srnode.back()->current_parent_since = snapid;
+ new_snaprealm = new sr_t();
+ new_snaprealm->created = snapid;
+ new_snaprealm->current_parent_since = snapid;
}
}
else
- projected_srnode.push_back(new sr_t(*projected_srnode.back()));
- dout(0) << "project_snaprealm " << projected_srnode.back() << dendl;
- return projected_srnode.back();
+ new_snaprealm = new sr_t(*projected_snaprealm_ptr);
+ dout(0) << "project_snaprealm " << new_snaprealm << dendl;
+ projected_nodes.back()->snapnode = new_snaprealm;
+ return new_snaprealm;
}
/* if newparent != parent, add parent to past_parents
new_snap->encode(snapbl);
}
-void CInode::pop_projected_snaprealm()
+void CInode::pop_projected_snaprealm(sr_t *next_snaprealm)
{
- assert(!projected_srnode.empty());
- dout(0) << "pop_projected_snaprealm " << projected_srnode.front()
- << " seq" << projected_srnode.front()->seq << dendl;
+ assert(next_snaprealm);
+ dout(0) << "pop_projected_snaprealm " << next_snaprealm
+ << " seq" << next_snaprealm->seq << dendl;
bool invalidate_cached_snaps = false;
if (!snaprealm)
open_snaprealm();
- else if (projected_srnode.front()->past_parents.size() !=
+ else if (next_snaprealm->past_parents.size() !=
snaprealm->srnode.past_parents.size())
invalidate_cached_snaps = true;
- snaprealm->srnode = *projected_srnode.front();
- delete projected_srnode.front();
- projected_srnode.pop_front();
+ snaprealm->srnode = *next_snaprealm;
+ delete next_snaprealm;
if (invalidate_cached_snaps)
snaprealm->invalidate_cached_snaps();
// relink as stray? (i.e. was primary link?)
CDentry::linkage_t *straydnl = 0;
+ sr_t *next_snap = 0;
if (straydn) {
dout(20) << " straydn is " << *straydn << dendl;
straydnl = straydn->pop_projected_linkage();
+ next_snap = straydnl->get_inode()->projected_nodes.front()->snapnode;
+ mdcache->touch_dentry_bottom(straydn);
+ }
+
+ dn->mark_dirty(dnpv, mdr->ls);
+ mdr->apply();
+
+ if (straydn) {
bool isnew = false;
if (!straydnl->get_inode()->snaprealm)
isnew = true;
- straydnl->get_inode()->pop_projected_snaprealm();
+ straydnl->get_inode()->pop_projected_snaprealm(next_snap);
if (isnew)
mdcache->do_realm_invalidate_and_update_notify(straydnl->get_inode(), CEPH_SNAP_OP_SPLIT, true);
-
- mdcache->touch_dentry_bottom(straydn);
}
-
- dn->mark_dirty(dnpv, mdr->ls);
- mdr->apply();
mds->mdcache->send_dentry_unlink(dn, straydn);
bool isnew = false;
if (!straydnl->get_inode()->snaprealm)
isnew = true;
- straydnl->get_inode()->pop_projected_snaprealm();
+ sr_t *next_snap = straydnl->get_inode()->projected_nodes.front()->snapnode;
+ straydnl->get_inode()->pop_projected_snaprealm(next_snap);
if (isnew)
mdcache->do_realm_invalidate_and_update_notify(straydnl->get_inode(), CEPH_SNAP_OP_SPLIT);
}
destdnl->get_inode()->state_set(CInode::STATE_AUTH);
}
+ sr_t *next_snap = NULL;
if (destdn->is_auth()) {
CInode *desti = destdnl->get_inode();
+ next_snap = desti->projected_nodes.front()->snapnode;
desti->pop_and_dirty_projected_inode(mdr->ls);
-
if (desti->is_dir()) {
mdr->ls->renamed_files.push_back(&desti->item_renamed_file);
desti->state_set(CInode::STATE_DIRTYPARENT);
}
// snap parent update?
- if (destdn->is_auth() && destdnl->get_inode()->snaprealm)
- destdnl->get_inode()->pop_projected_snaprealm();
+ if (next_snap)
+ destdnl->get_inode()->pop_projected_snaprealm(next_snap);
}
// src
pi->ctime = info.stamp;
pi->version = diri->pre_dirty();
- mdr->ls = mdlog->get_current_segment();
- EUpdate *le = new EUpdate(mdlog, "mksnap");
- 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_cow_inode(mdr, &le->metablob, diri);
-
// project the snaprealm
bufferlist snapbl;
sr_t *newsnap = diri->project_snaprealm(snapid);
newsnap->last_created = snapid;
newsnap->encode(snapbl);
+ // journal the inode changes
+ mdr->ls = mdlog->get_current_segment();
+ EUpdate *le = new EUpdate(mdlog, "mksnap");
+ 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_cow_inode(mdr, &le->metablob, diri);
+ // journal the snaprealm changes
le->metablob.add_primary_dentry(diri->get_projected_parent_dn(), true, 0, 0, &snapbl);
mdlog->submit_entry(le, new C_MDS_mksnap_finish(mds, mdr, diri, info));
{
dout(10) << "_mksnap_finish " << *mdr << " " << info << dendl;
+ sr_t *next_snaprealm = diri->projected_nodes.front()->snapnode;
+
diri->pop_and_dirty_projected_inode(mdr->ls);
mdr->apply();
// create snap
snapid_t snapid = info.snapid;
int op = (diri->snaprealm? CEPH_SNAP_OP_CREATE : CEPH_SNAP_OP_SPLIT);
- diri->pop_projected_snaprealm();
+ diri->pop_projected_snaprealm(next_snaprealm);
dout(10) << "snaprealm now " << *diri->snaprealm << dendl;
mdcache->do_realm_invalidate_and_update_notify(diri, op);
mdr->ls = mdlog->get_current_segment();
EUpdate *le = new EUpdate(mdlog, "rmsnap");
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_cow_inode(mdr, &le->metablob, diri);
// project the snaprealm
bufferlist snapbl;
newnode->last_destroyed = seq;
newnode->encode(snapbl);
+ 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_cow_inode(mdr, &le->metablob, diri);
+
le->metablob.add_primary_dentry(diri->get_projected_parent_dn(), true, 0, 0, &snapbl);
mdlog->submit_entry(le, new C_MDS_rmsnap_finish(mds, mdr, diri, snapid));
snapid_t seq;
::decode(seq, p);
+ sr_t *next_snaprealm = diri->projected_nodes.front()->snapnode;
+
diri->pop_and_dirty_projected_inode(mdr->ls);
mdr->apply();
mds->snapclient->commit(stid, mdr->ls);
// remove snap
- diri->pop_projected_snaprealm();
+ diri->pop_projected_snaprealm(next_snaprealm);
dout(10) << "snaprealm now " << *diri->snaprealm << dendl;
mdcache->do_realm_invalidate_and_update_notify(diri, CEPH_SNAP_OP_DESTROY);