@@ -5643,41 +5643,25 @@ version_t Server::_rename_prepare_import(MDRequest *mdr, CDentry *srcdn, bufferl
return oldpv;
}
-void Server::_rename_prepare(MDRequest *mdr,
- EMetaBlob *metablob, bufferlist *client_map_bl,
- CDentry *srcdn, CDentry *destdn, CDentry *straydn)
+bool Server::_need_force_journal(CInode *diri, bool empty)
{
- dout(10) << "_rename_prepare " << *mdr << " " << *srcdn << " " << *destdn << dendl;
- if (straydn)
- dout(10) << " straydn " << *straydn << dendl;
-
- CDentry::linkage_t *srcdnl = srcdn->get_projected_linkage();
- CDentry::linkage_t *destdnl = destdn->get_projected_linkage();
- CInode *srci = srcdnl->get_inode();
- CInode *oldin = destdnl->get_inode();
-
- // primary+remote link merge?
- bool linkmerge = (srci == destdnl->get_inode() &&
- (srcdnl->is_primary() || destdnl->is_primary()));
- bool silent = srcdn->get_dir()->inode->is_stray();
+ list<CDir*> ls;
+ diri->get_dirfrags(ls);
- // we need to force journaling of this event if we (will) have any subtrees
- // nested beneath.
bool force_journal = false;
- while (srci->is_dir()) {
- // if we are auth for srci and exporting it, force journal because we need create
- // auth subtrees here during journal replay.
- if (srci->is_auth() && !destdn->is_auth()) {
- dout(10) << " we are exporting srci, will force journal" << dendl;
- force_journal = true;
- break;
+ if (empty) {
+ for (list<CDir*>::iterator p = ls.begin(); p != ls.end(); ++p) {
+ if ((*p)->is_subtree_root() && (*p)->get_dir_auth().first == mds->whoami) {
+ dout(10) << " frag " << (*p)->get_frag() << " is auth subtree dirfrag, will force journal" << dendl;
+ force_journal = true;
+ break;
+ } else
+ dout(20) << " frag " << (*p)->get_frag() << " is not auth subtree dirfrag" << dendl;
}
-
+ } else {
// see if any children of our frags are auth subtrees.
list<CDir*> subtrees;
mds->mdcache->list_subtrees(subtrees);
- list<CDir*> ls;
- srci->get_dirfrags(ls);
dout(10) << " subtrees " << subtrees << " frags " << ls << dendl;
for (list<CDir*>::iterator p = ls.begin(); p != ls.end(); ++p) {
CDir *dir = *p;
@@ -5693,8 +5677,40 @@ void Server::_rename_prepare(MDRequest *mdr,
} else
dout(20) << " frag " << (*p)->get_frag() << " does not contain " << **q << dendl;
}
+ if (force_journal)
+ break;
}
- break;
+ }
+ return force_journal;
+}
+
+void Server::_rename_prepare(MDRequest *mdr,
+ EMetaBlob *metablob, bufferlist *client_map_bl,
+ CDentry *srcdn, CDentry *destdn, CDentry *straydn)
+{
+ dout(10) << "_rename_prepare " << *mdr << " " << *srcdn << " " << *destdn << dendl;
+ if (straydn)
+ dout(10) << " straydn " << *straydn << dendl;
+
+ CDentry::linkage_t *srcdnl = srcdn->get_projected_linkage();
+ CDentry::linkage_t *destdnl = destdn->get_projected_linkage();
+ CInode *srci = srcdnl->get_inode();
+ CInode *oldin = destdnl->get_inode();
+
+ // primary+remote link merge?
+ bool linkmerge = (srci == destdnl->get_inode() &&
+ (srcdnl->is_primary() || destdnl->is_primary()));
+ bool silent = srcdn->get_dir()->inode->is_stray();
+
+ bool force_journal = false;
+ if (srci->is_dir() && !destdn->is_auth()) {
+ if (srci->is_auth()) {
+ // if we are auth for srci and exporting it, force journal because journal replay needs
+ // the source inode to create auth subtrees.
+ dout(10) << " we are exporting srci, will force journal" << dendl;
+ force_journal = true;
+ } else
+ force_journal = _need_force_journal(srci, false);
}
if (linkmerge)
@@ -217,6 +217,7 @@ public:
void _rename_prepare_witness(MDRequest *mdr, int who, set<int> &witnesse,
CDentry *srcdn, CDentry *destdn, CDentry *straydn);
version_t _rename_prepare_import(MDRequest *mdr, CDentry *srcdn, bufferlist *client_map_bl);
+ bool _need_force_journal(CInode *diri, bool empty);
void _rename_prepare(MDRequest *mdr,
EMetaBlob *metablob, bufferlist *client_map_bl,
CDentry *srcdn, CDentry *destdn, CDentry *straydn);