From cb201ffcdebe7f5c9a50c90ed158a6f4d946bde5 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 15 Jul 2008 14:41:49 -0700 Subject: [PATCH] mds: server cleanup. link/unlink. --- src/mds/MDCache.cc | 62 +++++++++++++++++++++++++++------------------- src/mds/MDCache.h | 1 + src/mds/Server.cc | 36 ++++++++++++++++----------- 3 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 588488718c245..5d90e4c001d3b 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -981,27 +981,24 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t first, snapid_t last) 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; @@ -1009,23 +1006,38 @@ void MDCache::journal_cow_inode(EMetaBlob *metablob, CInode *in, snapid_t follow 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); diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 41f53e311cbb3..a6fbe843328b4 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -469,6 +469,7 @@ public: // journal helpers CInode *pick_inode_snap(CInode *in, snapid_t follows); CInode *cow_inode(CInode *in, snapid_t first, snapid_t last); + void journal_cow_dentry(EMetaBlob *metablob, CDentry *dn, snapid_t follows=CEPH_NOSNAP); void journal_cow_inode(EMetaBlob *metablob, CInode *in, snapid_t follows=CEPH_NOSNAP); void journal_dirty_inode(EMetaBlob *metablob, CInode *in, snapid_t follows=CEPH_NOSNAP); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 84b4ea0ec85a1..05b2b76c88416 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -2090,7 +2090,7 @@ void Server::handle_client_mknod(MDRequest *mdr) 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)); @@ -2138,8 +2138,7 @@ void Server::handle_client_mkdir(MDRequest *mdr) 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 @@ -2180,7 +2179,7 @@ void Server::handle_client_symlink(MDRequest *mdr) 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)); @@ -2317,14 +2316,16 @@ void Server::_link_local(MDRequest *mdr, CDentry *dn, CInode *targeti) 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)); } @@ -2412,7 +2413,9 @@ void Server::_link_remote(MDRequest *mdr, bool inc, CDentry *dn, CInode *targeti 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(), @@ -2420,6 +2423,7 @@ void Server::_link_remote(MDRequest *mdr, bool inc, CDentry *dn, CInode *targeti } 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); } @@ -2561,7 +2565,8 @@ void Server::handle_slave_link_prep(MDRequest *mdr) // 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)); } @@ -2912,24 +2917,25 @@ void Server::_unlink_local(MDRequest *mdr, CDentry *dn, CDentry *straydn) 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); @@ -4709,7 +4715,7 @@ void Server::handle_client_openc(MDRequest *mdr) 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); -- 2.39.5