if (silent)
dout(10) << " reintegrating stray; will avoid changing nlink or dir mtime" << dendl;
+ if (srci->is_dir() &&
+ (srcdn->is_auth() || destdn->is_auth())) {
+ dout(10) << " noting renamed dir ino " << srci->ino() << " in metablob" << dendl;
+ metablob->renamed_dirino = srci->ino();
+ }
+
// prepare
inode_t *pi = 0, *ji = 0; // renamed inode
inode_t *tpi = 0, *tji = 0; // target/overwritten inode
list<pair<__u8,version_t> > table_tids; // tableclient transactions
inodeno_t opened_ino;
+public:
+ inodeno_t renamed_dirino;
+private:
// ino (pre)allocation. may involve both inotable AND session state.
version_t inotablev, sessionmapv;
public:
void encode(bufferlist& bl) const {
- __u8 struct_v = 2;
+ __u8 struct_v = 3;
::encode(struct_v, bl);
::encode(lump_order, bl);
::encode(lump_map, bl);
::encode(truncate_finish, bl);
::encode(destroyed_inodes, bl);
::encode(client_reqs, bl);
+ ::encode(renamed_dirino, bl);
}
void decode(bufferlist::iterator &bl) {
__u8 struct_v;
::decode(truncate_start, bl);
::decode(truncate_finish, bl);
::decode(destroyed_inodes, bl);
- if (struct_v >= 2)
+ if (struct_v >= 2) {
::decode(client_reqs, bl);
- else {
+ } else {
list<metareqid_t> r;
::decode(r, bl);
while (!r.empty()) {
r.pop_front();
}
}
+ if (struct_v >= 3)
+ ::decode(renamed_dirino, bl);
}
// EMetaBlob
EMetaBlob::EMetaBlob(MDLog *mdlog) : root(NULL),
- opened_ino(0),
+ opened_ino(0), renamed_dirino(0),
inotablev(0), sessionmapv(0),
allocated_ino(0),
last_subtree_map(mdlog ? mdlog->get_last_segment_offset() : 0),
dout(10) << "EMetaBlob.replay " << (isnew ? " added root ":" updated root ") << *in << dendl;
}
+ CInode *renamed_diri = 0;
+ CDir *olddir = 0;
+ if (renamed_dirino) {
+ renamed_diri = mds->mdcache->get_inode(renamed_dirino);
+ if (renamed_diri)
+ dout(10) << "EMetaBlob.replay renamed inode is " << *renamed_diri << dendl;
+ else
+ dout(10) << "EMetaBlob.replay don't have renamed ino " << renamed_dirino << dendl;
+ }
+
// walk through my dirs (in order!)
for (list<dirfrag_t>::iterator lp = lump_order.begin();
lp != lump_order.end();
dn->first = p->dnfirst;
if (!dn->get_linkage()->is_null()) {
dout(10) << "EMetaBlob.replay unlinking " << *dn << dendl;
+ if (dn->get_linkage()->is_primary() &&
+ dn->get_linkage()->get_inode() == renamed_diri)
+ olddir = dir;
dir->unlink_inode(dn);
}
dn->set_version(p->dnv);
}
}
+ if (renamed_dirino) {
+ if (olddir) {
+ assert(renamed_diri);
+ mds->mdcache->adjust_subtree_after_rename(renamed_diri, olddir, false);
+ } else {
+ if (!renamed_diri) {
+ renamed_diri = mds->mdcache->get_inode(renamed_dirino);
+ assert(renamed_diri);
+ }
+ // FIXME.
+ }
+ }
+
// table client transactions
for (list<pair<__u8,version_t> >::iterator p = table_tids.begin();
p != table_tids.end();