mds: fix fast create + rm failure

The inode projected_version() needs to be accurate or we run into
problems later.  So, change the way the inode creation version is
initialized by moving the hack to right before mark_dirty() is
called (to keep the v < pv assertion in place).
This commit is contained in:
Sage Weil 2009-01-16 11:57:39 -08:00
parent 7eeca0bbdf
commit 461cb1a643
2 changed files with 13 additions and 10 deletions

View File

@ -79,6 +79,8 @@ ostream& operator<<(ostream& out, CInode& in)
out << " " << in.dirfragtree;
out << " v" << in.get_version();
if (in.get_projected_version() > in.get_version())
out << " pv" << in.get_projected_version();
if (in.is_auth_pinned()) {
out << " ap=" << in.get_num_auth_pins();
@ -493,11 +495,7 @@ void CInode::name_stray_dentry(string& dname)
version_t CInode::pre_dirty()
{
assert(parent || projected_parent.size());
version_t pv;
if (projected_parent.size())
pv = projected_parent.front()->pre_dirty(get_projected_version());
else
pv = parent->pre_dirty();
version_t pv = get_projected_parent_dn()->pre_dirty(get_projected_version());
dout(10) << "pre_dirty " << pv << " (current v " << inode.version << ")" << dendl;
return pv;
}

View File

@ -2303,7 +2303,10 @@ public:
// link the inode
dn->pop_projected_linkage();
// dirty inode, dn, dir
// be a bit hacky with the inode version, here.. we decrement it
// just to keep mark_dirty() happen. (we didn't bother projecting
// a new version of hte inode since it's just been created)
newi->inode.version--;
newi->mark_dirty(newi->inode.version + 1, mdr->ls);
// mkdir?
@ -2347,7 +2350,7 @@ void Server::handle_client_mknod(MDRequest *mdr)
newi->inode.mode = req->head.args.mknod.mode;
if ((newi->inode.mode & S_IFMT) == 0)
newi->inode.mode |= S_IFREG;
newi->inode.version = dn->pre_dirty() - 1;
newi->inode.version = dn->pre_dirty();
newi->inode.rstat.rfiles = 1;
dn->first = newi->first = follows+1;
@ -2398,7 +2401,7 @@ void Server::handle_client_mkdir(MDRequest *mdr)
newi->inode.mode &= ~S_IFMT;
newi->inode.mode |= S_IFDIR;
newi->inode.layout = g_default_mds_dir_layout;
newi->inode.version = dn->pre_dirty() - 1;
newi->inode.version = dn->pre_dirty();
newi->inode.rstat.rsubdirs = 1;
dn->first = newi->first = follows+1;
@ -2467,7 +2470,7 @@ void Server::handle_client_symlink(MDRequest *mdr)
newi->inode.size = newi->symlink.length();
newi->inode.rstat.rbytes = newi->inode.size;
newi->inode.rstat.rfiles = 1;
newi->inode.version = dn->pre_dirty() - 1;
newi->inode.version = dn->pre_dirty();
dn->first = newi->first = follows+1;
@ -3233,8 +3236,10 @@ void Server::_unlink_local(MDRequest *mdr, CDentry *dn, CDentry *straydn)
EUpdate *le = new EUpdate(mdlog, "unlink_local");
le->metablob.add_client_req(mdr->reqid);
if (dnl->is_primary())
if (straydn) {
assert(dnl->is_primary());
straydn->push_projected_linkage(dnl->get_inode());
}
// the unlinked dentry
dn->pre_dirty();