}
}
+void MDCache::clear_dirty_bits_for_stray(CInode* diri) {
+ dout(10) << __func__ << " " << *diri << dendl;
+ assert(diri->get_projected_parent_dir()->inode->is_stray());
+ list<CDir*> ls;
+ diri->get_dirfrags(ls);
+ for (auto p : ls) {
+ if (p->is_auth() && !(p->is_frozen() || p->is_freezing()))
+ p->try_remove_dentries_for_stray();
+ }
+}
+
struct C_MDS_SlaveRmdirCommit : public ServerContext {
MDRequestRef mdr;
- C_MDS_SlaveRmdirCommit(Server *s, MDRequestRef& r)
- : ServerContext(s), mdr(r) { }
+ CDentry *straydn;
+ C_MDS_SlaveRmdirCommit(Server *s, MDRequestRef& r, CDentry *sd)
+ : ServerContext(s), mdr(r), straydn(sd) { }
void finish(int r) override {
- server->_commit_slave_rmdir(mdr, r);
+ server->_commit_slave_rmdir(mdr, r, straydn);
}
};
dout(20) << " rollback is " << mdr->more()->rollback_bl.length() << " bytes" << dendl;
// set up commit waiter
- mdr->more()->slave_commit = new C_MDS_SlaveRmdirCommit(this, mdr);
+ mdr->more()->slave_commit = new C_MDS_SlaveRmdirCommit(this, mdr, straydn);
if (!in->has_subtree_root_dirfrag(mds->get_nodeid())) {
dout(10) << " no auth subtree in " << *in << ", skipping journal" << dendl;
dout(10) << "still waiting on slaves " << mdr->more()->waiting_on_slave << dendl;
}
-void Server::_commit_slave_rmdir(MDRequestRef& mdr, int r)
+void Server::_commit_slave_rmdir(MDRequestRef& mdr, int r, CDentry *straydn)
{
dout(10) << "_commit_slave_rmdir " << *mdr << " r=" << r << dendl;
if (r == 0) {
+ if (mdr->more()->slave_update_journaled) {
+ CInode *strayin = straydn->get_projected_linkage()->get_inode();
+ if (strayin && !strayin->snaprealm)
+ mdcache->clear_dirty_bits_for_stray(strayin);
+ }
+
mdr->cleanup();
if (mdr->more()->slave_update_journaled) {
mdr->more()->is_ambiguous_auth = false;
}
+ if (straydn && mdr->more()->slave_update_journaled) {
+ CInode *strayin = straydn->get_projected_linkage()->get_inode();
+ if (strayin && !strayin->snaprealm)
+ mdcache->clear_dirty_bits_for_stray(strayin);
+ }
mds->queue_waiters(finished);
mdr->cleanup();
bool _rmdir_prepare_witness(MDRequestRef& mdr, mds_rank_t who, vector<CDentry*>& trace, CDentry *straydn);
void handle_slave_rmdir_prep(MDRequestRef& mdr);
void _logged_slave_rmdir(MDRequestRef& mdr, CDentry *srcdn, CDentry *straydn);
- void _commit_slave_rmdir(MDRequestRef& mdr, int r);
+ void _commit_slave_rmdir(MDRequestRef& mdr, int r, CDentry *straydn);
void handle_slave_rmdir_prep_ack(MDRequestRef& mdr, MMDSSlaveRequest *ack);
void do_rmdir_rollback(bufferlist &rbl, mds_rank_t master, MDRequestRef& mdr);
void _rmdir_rollback_finish(MDRequestRef& mdr, metareqid_t reqid, CDentry *dn, CDentry *straydn);
return false; // not until some snaps are deleted.
}
- if (in->has_dirfrags()) {
- list<CDir*> ls;
- in->get_nested_dirfrags(ls);
- for (list<CDir*>::iterator p = ls.begin(); p != ls.end(); ++p) {
- (*p)->try_remove_dentries_for_stray();
- }
- }
+ in->mdcache->clear_dirty_bits_for_stray(in);
if (!in->remote_parents.empty()) {
// unlink any stale remote snap dentry.