return oldin;
}
-void MDCache::journal_cow_inode(EMetaBlob *metablob, CInode *in, snapid_t follows)
+
+void MDCache::journal_cow_dentry(EMetaBlob *metablob, CDentry *dn, snapid_t follows)
{
- dout(10) << "journal_cow_inode follows " << follows << " on " << *in << dendl;
- CDentry *dn = in->get_projected_parent_dn();
- dout(10) << " orig dn " << *dn << dendl;
+ dout(10) << "journal_cow_dentry follows " << follows << " on " << *dn << dendl;
- if (follows == CEPH_NOSNAP)
- follows = in->find_snaprealm()->get_latest_snap();
-
- // are we within the current snap?
- if (follows < in->first)
- return;
+ // nothing to cow on a null dentry
+ assert(!dn->is_null());
- if (in->is_multiversion()) {
+ if (dn->is_primary() && dn->inode->is_multiversion()) {
// multiversion inode.
+ CInode *in = dn->inode;
+
+ if (follows == CEPH_NOSNAP)
+ follows = in->find_snaprealm()->get_latest_snap();
+
old_inode_t &old = in->old_inodes[follows];
old.first = in->first;
- if (in->is_projected())
- old.inode = *in->get_previous_projected_inode();
- else
- old.inode = in->inode; // mkdir/mknod/symlink don't bother to project new inodes
+ old.inode = *in->get_previous_projected_inode();
old.xattrs = in->xattrs;
in->first = follows+1;
dout(10) << " duped to old_inode [" << old.first << "," << follows << "] "
<< *in << dendl;
} else {
+ if (follows == CEPH_NOSNAP)
+ follows = dn->dir->inode->find_snaprealm()->get_latest_snap();
+
snapid_t oldfirst = dn->first;
+
+ // update dn.first before adding old dentry to cdir's map
dn->first = follows+1;
dout(10) << " dn " << *dn << dendl;
- CInode *oldin = cow_inode(in, in->first, follows);
- CDentry *olddn = dn->dir->add_primary_dentry(dn->name, oldin, oldfirst, follows);
- dout(10) << " olddn " << *olddn << dendl;
-
- metablob->add_primary_dentry(olddn, true);
- inode_t *pi;
- if (in->is_projected())
- pi = in->get_previous_projected_inode();
- else
- pi = &in->inode; // mkdir/mknod/symlink don't bother to project new inodes
+ if (dn->is_primary()) {
+ CInode *oldin = cow_inode(dn->inode, dn->inode->first, follows);
+ CDentry *olddn = dn->dir->add_primary_dentry(dn->name, oldin, oldfirst, follows);
+ dout(10) << " olddn " << *olddn << dendl;
+ metablob->add_primary_dentry(olddn, true);
+ } else {
+ assert(dn->is_remote());
+ CDentry *olddn = dn->dir->add_remote_dentry(dn->name, dn->remote_ino, dn->remote_d_type,
+ oldfirst, follows);
+ dout(10) << " olddn " << *olddn << dendl;
+ metablob->add_remote_dentry(olddn, true);
+ }
}
}
+
+void MDCache::journal_cow_inode(EMetaBlob *metablob, CInode *in, snapid_t follows)
+{
+ dout(10) << "journal_cow_inode follows " << follows << " on " << *in << dendl;
+ CDentry *dn = in->get_projected_parent_dn();
+ journal_cow_dentry(metablob, dn, follows);
+}
+
void MDCache::journal_dirty_inode(EMetaBlob *metablob, CInode *in, snapid_t follows)
{
journal_cow_inode(metablob, in, follows);
le->metablob.add_allocated_ino(newi->ino(), mds->idalloc->get_version());
mds->locker->predirty_nested(mdr, &le->metablob, newi, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1);
- mdcache->journal_dirty_inode(&le->metablob, newi, follows);
+ le->metablob.add_primary_dentry(dn, true, newi);
// log + wait
mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi, follows));
le->metablob.add_client_req(req->get_reqid());
le->metablob.add_allocated_ino(newi->ino(), mds->idalloc->get_version());
mds->locker->predirty_nested(mdr, &le->metablob, newi, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1);
- //le->metablob.add_primary_dentry(dn, true, newi, &newi->inode);
- mdcache->journal_dirty_inode(&le->metablob, newi, follows);
+ le->metablob.add_primary_dentry(dn, true, newi, &newi->inode);
le->metablob.add_dir(newdir, true, true); // dirty AND complete
// log + wait
le->metablob.add_client_req(req->get_reqid());
le->metablob.add_allocated_ino(newi->ino(), mds->idalloc->get_version());
mds->locker->predirty_nested(mdr, &le->metablob, newi, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1);
- mdcache->journal_dirty_inode(&le->metablob, newi, follows);
+ le->metablob.add_primary_dentry(dn, true, newi);
// log + wait
mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi, follows));
pi->ctime = mdr->now;
pi->version = tipv;
+ snapid_t follows = dn->dir->inode->find_snaprealm()->get_latest_snap();
+ dn->first = follows+1;
+
// log + wait
EUpdate *le = new EUpdate(mdlog, "link_local");
le->metablob.add_client_req(mdr->reqid);
mds->locker->predirty_nested(mdr, &le->metablob, targeti, dn->dir, PREDIRTY_DIR, 1); // new dn
mds->locker->predirty_nested(mdr, &le->metablob, targeti, 0, PREDIRTY_PRIMARY); // targeti
- le->metablob.add_remote_dentry(dn, true, targeti->ino(),
- MODE_TO_DT(targeti->inode.mode)); // new remote
- le->metablob.add_primary_dentry(targeti->parent, true, targeti, pi); // update old primary
+ le->metablob.add_remote_dentry(dn, true, targeti->ino(), MODE_TO_DT(targeti->inode.mode)); // new remote
+ mdcache->journal_dirty_inode(&le->metablob, targeti);
mdlog->submit_entry(le, new C_MDS_link_local_finish(mds, mdr, dn, targeti, dnpv, tipv));
}
mds->mdcache->add_uncommitted_master(mdr->reqid, mdr->ls, mdr->more()->slaves);
}
+ snapid_t dnfollows = dn->dir->inode->find_snaprealm()->get_latest_snap();
if (inc) {
+ dn->first = dnfollows + 1;
dn->pre_dirty();
mds->locker->predirty_nested(mdr, &le->metablob, targeti, dn->dir, PREDIRTY_DIR, 1);
le->metablob.add_remote_dentry(dn, true, targeti->ino(),
} else {
dn->pre_dirty();
mds->locker->predirty_nested(mdr, &le->metablob, targeti, dn->dir, PREDIRTY_DIR, -1);
+ mdcache->journal_cow_dentry(&le->metablob, dn, dnfollows);
le->metablob.add_null_dentry(dn, true);
}
// commit case
mds->locker->predirty_nested(mdr, &le->commit, dn->inode, 0, PREDIRTY_SHALLOW|PREDIRTY_PRIMARY, 0);
- le->commit.add_primary_dentry(dn, true, targeti, pi); // update old primary
+ //le->commit.add_primary_dentry(dn, true, targeti, pi); // update old primary
+ mdcache->journal_dirty_inode(&le->commit, targeti);
mdlog->submit_entry(le, new C_MDS_SlaveLinkPrep(this, mdr, targeti));
}
pi->nlink--;
pi->ctime = mdr->now;
+ // the unlinked dentry
+ dn->pre_dirty();
+ mdcache->journal_cow_dentry(&le->metablob, dn);
+ le->metablob.add_null_dentry(dn, true);
+
if (dn->is_primary()) {
// primary link. add stray dentry.
assert(straydn);
mds->locker->predirty_nested(mdr, &le->metablob, dn->inode, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, -1);
mds->locker->predirty_nested(mdr, &le->metablob, dn->inode, straydn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1);
- //le->metablob.add_dir_context(straydn->dir);
le->metablob.add_primary_dentry(straydn, true, dn->inode, pi);
} else {
// remote link. update remote inode.
mds->locker->predirty_nested(mdr, &le->metablob, dn->inode, dn->dir, PREDIRTY_DIR, -1);
mds->locker->predirty_nested(mdr, &le->metablob, dn->inode, 0, PREDIRTY_PRIMARY);
- le->metablob.add_primary_dentry(dn->inode->parent, true, dn->inode, pi);
+ //le->metablob.add_primary_dentry(dn->inode->parent, true, dn->inode, pi);
+ mdcache->journal_dirty_inode(&le->metablob, dn->inode);
}
- // the unlinked dentry
- dn->pre_dirty();
- le->metablob.add_null_dentry(dn, true);
-
if (mdr->more()->dst_reanchor_atid)
le->metablob.add_anchor_transaction(mdr->more()->dst_reanchor_atid);
le->metablob.add_client_req(req->get_reqid());
le->metablob.add_allocated_ino(in->ino(), mds->idalloc->get_version());
mds->locker->predirty_nested(mdr, &le->metablob, in, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1);
- mdcache->journal_dirty_inode(&le->metablob, in, follows);
+ le->metablob.add_primary_dentry(dn, true, in);
// log + wait
C_MDS_openc_finish *fin = new C_MDS_openc_finish(mds, mdr, dn, in, follows);