srand(0);
if (1) {
+ bool renames = false; // thrash renames too?
for (int k=0; k<n; k++) {
- if (rand() % 10 == 0) {
+ if (renames && rand() % 10 == 0) {
// rename some directories. whee!
int dep = (rand() % depth) + 1;
string src = basedir;
switch (o) {
case 0:
client->mknod(src.c_str(), 0755);
- client->rename(src.c_str(), dst.c_str());
+ if (renames) client->rename(src.c_str(), dst.c_str());
break;
case 1:
client->mknod(src.c_str(), 0755);
if (in.is_freezing_inode()) out << " FREEZING=" << in.auth_pin_freeze_allowance;
if (in.is_frozen_inode()) out << " FROZEN";
+ if (in.get_nested_anchors())
+ out << " na=" << in.get_nested_anchors();
+
if (in.inode.is_dir()) {
out << " ds=" << in.inode.dirstat.size() << "="
<< in.inode.dirstat.nfiles << "+" << in.inode.dirstat.nsubdirs;
{
bool was_anchored = inode.anchored;
::decode(inode.anchored, p);
- if (was_anchored != inode.anchored)
+ if (parent && was_anchored != inode.anchored)
parent->adjust_nested_anchors((int)inode.anchored - (int)was_anchored);
}
break;
void auth_unpin();
void adjust_nested_anchors(int by);
+ int get_nested_anchors() { return nested_anchors; }
// -- freeze --
bool is_freezing_inode() { return state_test(STATE_FREEZING); }
// perform rollback (and journal a rollback entry)
// note: this will hold up the resolve a bit, until the rollback entries journal.
if (uncommitted_slave_updates[from][*p]->origop == ESlaveUpdate::LINK)
- mds->server->do_link_rollback(uncommitted_slave_updates[from][*p]->rollback, 0);
+ mds->server->do_link_rollback(uncommitted_slave_updates[from][*p]->rollback, from, 0);
else if (uncommitted_slave_updates[from][*p]->origop == ESlaveUpdate::RENAME)
- mds->server->do_rename_rollback(uncommitted_slave_updates[from][*p]->rollback, 0);
+ mds->server->do_rename_rollback(uncommitted_slave_updates[from][*p]->rollback, from, 0);
else
assert(0);
++p) {
CInode *in = get_inode(p->inode.ino);
if (!in) continue;
+ if (in->parent && in->inode.anchored != p->inode.anchored)
+ in->parent->adjust_nested_anchors( (int)p->inode.anchored - (int)in->inode.anchored );
in->inode = p->inode;
in->symlink = p->symlink;
in->dirfragtree = p->dirfragtree;
set<CInode*>::iterator q = rejoin_undef_inodes.find(in);
if (q != rejoin_undef_inodes.end()) {
CInode *in = *q;
+ if (in->parent && in->inode.anchored != p->inode.anchored)
+ in->parent->adjust_nested_anchors( (int)p->inode.anchored - (int)in->inode.anchored );
in->inode = p->inode;
in->symlink = p->symlink;
in->dirfragtree = p->dirfragtree;
}
dout(10) << " targeti auth has prepared nlink++" << dendl;
+ assert(0); // test hack: verify that remote slave can do a live rollback.
+
// go.
// predirty dentry
dn->pre_dirty();
mdlog->submit_entry(le);
mds->mdcache->request_finish(mdr);
} else {
- do_link_rollback(mdr->more()->rollback_bl, mdr);
+ do_link_rollback(mdr->more()->rollback_bl, mdr->slave_to_mds, mdr);
}
}
}
};
-void Server::do_link_rollback(bufferlist &rbl, MDRequest *mdr)
+void Server::do_link_rollback(bufferlist &rbl, int master, MDRequest *mdr)
{
link_rollback rollback;
bufferlist::iterator p = rbl.begin();
else
pi->nlink++;
- ESlaveUpdate *le = new ESlaveUpdate(mdlog, "slave_link_rollback", rollback.reqid, -1,
+ ESlaveUpdate *le = new ESlaveUpdate(mdlog, "slave_link_rollback", rollback.reqid, master,
ESlaveUpdate::OP_ROLLBACK, ESlaveUpdate::LINK);
le->commit.add_dir_context(parent);
le->commit.add_dir(parent, true);
_rename_prepare_witness(mdr, last, srcdn, destdn, straydn);
return;
}
+
+ // test hack: bail after slave does prepare, so we can verify it's _live_ rollback.
+ //if (!mdr->more()->slaves.empty()) assert(0);
// -- prepare anchor updates --
if (!linkmerge || srcdn->is_primary()) {
} else {
// abort
- do_rename_rollback(mdr->more()->rollback_bl, mdr);
+ do_rename_rollback(mdr->more()->rollback_bl, mdr->slave_to_mds, mdr);
// rollback export. readjust subtree map, if it was a dir.
assert(0); // write me
mds->mdcache->request_finish(mdr);
}
-void Server::do_rename_rollback(bufferlist &rbl, MDRequest *mdr)
+void Server::do_rename_rollback(bufferlist &rbl, int master, MDRequest *mdr)
{
rename_rollback rollback;
bufferlist::iterator p = rbl.begin();
::decode(rollback, p);
- ESlaveUpdate *le = new ESlaveUpdate(mdlog, "slave_rename_abort", rollback.reqid, -1,
+ ESlaveUpdate *le = new ESlaveUpdate(mdlog, "slave_rename_abort", rollback.reqid, master,
ESlaveUpdate::OP_ROLLBACK, ESlaveUpdate::RENAME);
void _logged_slave_link(MDRequest *mdr, CInode *targeti);
void _commit_slave_link(MDRequest *mdr, int r, CInode *targeti);
void handle_slave_link_prep_ack(MDRequest *mdr, MMDSSlaveRequest *m);
- void do_link_rollback(bufferlist &rbl, MDRequest *mdr);
+ void do_link_rollback(bufferlist &rbl, int master, MDRequest *mdr);
void _do_link_rollback_finish(Mutation *mut, MDRequest *mdr);
// unlink
void handle_slave_rename_prep_ack(MDRequest *mdr, MMDSSlaveRequest *m);
void _logged_slave_rename(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDentry *straydn);
void _commit_slave_rename(MDRequest *mdr, int r, CDentry *srcdn, CDentry *destdn, CDentry *straydn);
- void do_rename_rollback(bufferlist &rbl, MDRequest *mdr);
+ void do_rename_rollback(bufferlist &rbl, int master, MDRequest *mdr);
};
void print(ostream& out) {
if (type.length())
out << type << " ";
- out << " " << op;
+ out << " " << (int)op;
if (origop == LINK) out << " link";
if (origop == RENAME) out << " rename";
out << " " << reqid;
dout(10) << "EMetaBlob.replay unlinking " << *in << dendl;
in->get_parent_dn()->get_dir()->unlink_inode(in->get_parent_dn());
}
+ if (in->get_parent_dn() && in->inode.anchored != p->inode.anchored)
+ in->get_parent_dn()->adjust_nested_anchors( (int)p->inode.anchored - (int)in->inode.anchored );
in->inode = p->inode;
in->dirfragtree = p->dirfragtree;
in->xattrs = p->xattrs;
if (in->inode.is_symlink()) in->symlink = p->symlink;
if (p->dirty) in->_mark_dirty(logseg);
if (dn->get_inode() != in) {
+ if (!dn->is_null()) // note: might be remote. as with stray reintegration.
+ dir->unlink_inode(dn);
dir->link_primary_inode(dn, in);
dout(10) << "EMetaBlob.replay linked " << *in << dendl;
} else {
for (list<metareqid_t>::iterator p = client_reqs.begin();
p != client_reqs.end();
++p)
- mds->sessionmap.add_completed_request(*p);
+ if (p->name.is_client())
+ mds->sessionmap.add_completed_request(*p);
// update segment
} else {
dout(10) << "ESession.replay sessionmap " << mds->sessionmap.version
- << " < " << cmapv << dendl;
+ << " < " << cmapv << " " << (open ? "open":"close") << dendl;
mds->sessionmap.projected = ++mds->sessionmap.version;
assert(mds->sessionmap.version == cmapv);
if (open) {