From a8913af2d4f4a56d053905ef9b7ad0ebb5f0a7f9 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 24 May 2008 21:02:43 -0700 Subject: [PATCH] mds: unlink_local fixed up, still need to do remote --- src/mds/Locker.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++-- src/mds/Locker.h | 2 ++ src/mds/Server.cc | 53 +++++++++++++++--------------------- src/mds/Server.h | 2 +- 4 files changed, 91 insertions(+), 34 deletions(-) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 83ec9f9b3cdf8..3351ebee40d84 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -419,7 +419,7 @@ bool Locker::xlock_start(SimpleLock *lock, MDRequest *mut) case CEPH_LOCK_IDFT: case CEPH_LOCK_IDIR: case CEPH_LOCK_INESTED: - assert(0); + return scatter_xlock_start((ScatterLock*)lock, mut); default: return simple_xlock_start(lock, mut); } @@ -435,7 +435,7 @@ void Locker::xlock_finish(SimpleLock *lock, Mutation *mut) case CEPH_LOCK_IDFT: case CEPH_LOCK_IDIR: case CEPH_LOCK_INESTED: - assert(0); + return scatter_xlock_finish((ScatterLock*)lock, mut); default: return simple_xlock_finish(lock, mut); } @@ -2021,6 +2021,70 @@ void Locker::scatter_wrlock_finish(ScatterLock *lock, Mutation *mut) } +bool Locker::scatter_xlock_start(ScatterLock *lock, MDRequest *mut) +{ + dout(7) << "file_xlock_start on " << *lock << " on " << *lock->get_parent() << dendl; + + assert(lock->get_parent()->is_auth()); // remote scatter xlock not implemented + + // already xlocked by me? + if (lock->get_xlocked_by() == mut) + return true; + + // can't write? + if (!lock->can_xlock(mut)) { + + // auth + if (!lock->can_xlock_soon()) { + if (!lock->is_stable()) { + dout(7) << "scatter_xlock_start on auth, waiting for stable on " << *lock << " on " << *lock->get_parent() << dendl; + lock->add_waiter(SimpleLock::WAIT_STABLE, new C_MDS_RetryRequest(mdcache, mut)); + return false; + } + + // initiate lock + scatter_lock(lock); + + // fall-thru to below. + } + } + + // check again + if (lock->can_xlock(mut)) { + assert(lock->get_parent()->is_auth()); + lock->get_xlock(mut); + mut->locks.insert(lock); + mut->xlocks.insert(lock); + return true; + } else { + dout(7) << "scatter_xlock_start on auth, waiting for write on " << *lock << " on " << *lock->get_parent() << dendl; + lock->add_waiter(SimpleLock::WAIT_WR, new C_MDS_RetryRequest(mdcache, mut)); + return false; + } +} + +void Locker::scatter_xlock_finish(ScatterLock *lock, Mutation *mut) +{ + dout(7) << "scatter_xlock_finish on " << *lock << " on " << *lock->get_parent() << dendl; + + // drop ref + assert(lock->can_xlock(mut)); + lock->put_xlock(); + mut->locks.erase(lock); + mut->xlocks.erase(lock); + + assert(lock->get_parent()->is_auth()); // or implement remote xlocks + + // others waiting? + lock->finish_waiters(SimpleLock::WAIT_STABLE | + SimpleLock::WAIT_WR | + SimpleLock::WAIT_RD, 0); + + if (lock->get_parent()->is_auth()) + scatter_eval(lock); +} + + class C_Locker_ScatterEval : public Context { Locker *locker; ScatterLock *lock; diff --git a/src/mds/Locker.h b/src/mds/Locker.h index 06db3050b37f6..2d22d4ef8f7a9 100644 --- a/src/mds/Locker.h +++ b/src/mds/Locker.h @@ -141,6 +141,8 @@ protected: bool scatter_wrlock_try(ScatterLock *lock, Mutation *mut); bool scatter_wrlock_start(ScatterLock *lock, MDRequest *mut); void scatter_wrlock_finish(ScatterLock *lock, Mutation *mut); + bool scatter_xlock_start(ScatterLock *lock, MDRequest *mut); + void scatter_xlock_finish(ScatterLock *lock, Mutation *mut); void scatter_writebehind(ScatterLock *lock); class C_Locker_ScatterWB : public Context { diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 2fd8b258b3086..79c6fdab0e07d 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -2338,15 +2338,13 @@ class C_MDS_link_remote_finish : public Context { CDentry *dn; CInode *targeti; version_t dpv; - version_t dirpv; public: - C_MDS_link_remote_finish(MDS *m, MDRequest *r, CDentry *d, CInode *ti, version_t dirpv_) : + C_MDS_link_remote_finish(MDS *m, MDRequest *r, CDentry *d, CInode *ti) : mds(m), mdr(r), dn(d), targeti(ti), - dpv(d->get_projected_version()), - dirpv(dirpv_) { } + dpv(d->get_projected_version()) {} void finish(int r) { assert(r == 0); - mds->server->_link_remote_finish(mdr, dn, targeti, dpv, dirpv); + mds->server->_link_remote_finish(mdr, dn, targeti, dpv); } }; @@ -2378,8 +2376,7 @@ void Server::_link_remote(MDRequest *mdr, CDentry *dn, CInode *targeti) mdr->ls = mdlog->get_current_segment(); EUpdate *le = new EUpdate(mdlog, "link_remote"); le->metablob.add_client_req(mdr->reqid); - version_t dirpv = predirty_dn_diri(mdr, dn, &le->metablob); // dir inode's mtime - le->metablob.add_dir_context(dn->get_dir()); + mds->locker->predirty_nested(mdr, &le->metablob, targeti, dn->dir, false, true, 1); le->metablob.add_remote_dentry(dn, true, targeti->ino(), MODE_TO_DT(targeti->inode.mode)); // new remote @@ -2387,11 +2384,11 @@ void Server::_link_remote(MDRequest *mdr, CDentry *dn, CInode *targeti) mdr->committing = true; // log + wait - mdlog->submit_entry(le, new C_MDS_link_remote_finish(mds, mdr, dn, targeti, dirpv)); + mdlog->submit_entry(le, new C_MDS_link_remote_finish(mds, mdr, dn, targeti)); } void Server::_link_remote_finish(MDRequest *mdr, CDentry *dn, CInode *targeti, - version_t dpv, version_t dirpv) + version_t dpv) { dout(10) << "_link_remote_finish " << *dn << " to " << *targeti << dendl; @@ -2399,8 +2396,7 @@ void Server::_link_remote_finish(MDRequest *mdr, CDentry *dn, CInode *targeti, dn->dir->link_remote_inode(dn, targeti); dn->mark_dirty(dpv, mdr->ls); - // dir inode's mtime - dirty_dn_diri(mdr, dn, dirpv); + mdr->apply(); // bump target popularity mds->balancer->hit_inode(mdr->now, targeti, META_POP_IWR); @@ -2736,33 +2732,31 @@ void Server::_unlink_local(MDRequest *mdr, CDentry *dn, CDentry *straydn) EUpdate *le = new EUpdate(mdlog, "unlink_local"); le->metablob.add_client_req(mdr->reqid); - version_t ipv = 0; // dirty inode version - inode_t *ji = 0; // journaled projected inode + if (dn->is_primary()) + dn->inode->projected_parent = straydn; + + inode_t *pi = dn->inode->project_inode(); + mdr->add_projected_inode(dn->inode); + pi->version = dn->inode->pre_dirty(); + pi->nlink--; + pi->ctime = mdr->now; + + mds->locker->predirty_nested(mdr, &le->metablob, dn->inode, dn->dir, + dn->is_primary(), true, -1); + if (dn->is_primary()) { // primary link. add stray dentry. assert(straydn); - dn->inode->projected_parent = straydn; - ipv = dn->inode->pre_dirty(); le->metablob.add_dir_context(straydn->dir); - ji = le->metablob.add_primary_dentry(straydn, true, dn->inode); + le->metablob.add_primary_dentry(straydn, true, dn->inode, pi); } else { // remote link. update remote inode. - ipv = dn->inode->pre_dirty(); le->metablob.add_dir_context(dn->inode->get_parent_dir()); - ji = le->metablob.add_primary_dentry(dn->inode->parent, true, dn->inode); + le->metablob.add_primary_dentry(dn->inode->parent, true, dn->inode); } - - // update journaled target inode - inode_t *pi = dn->inode->project_inode(); - pi->nlink--; - pi->ctime = mdr->now; - pi->version = ipv; - *ji = *pi; // copy into journal // the unlinked dentry dn->pre_dirty(); - mds->locker->predirty_nested(mdr, &le->metablob, dn->inode, dn->dir, - dn->is_primary(), true, -1); le->metablob.add_null_dentry(dn, true); if (mdr->more()->dst_reanchor_atid) @@ -2788,11 +2782,8 @@ void Server::_unlink_local_finish(MDRequest *mdr, straydn->dir->link_primary_inode(straydn, in); } - // nlink--, dirty old dentry - in->pop_and_dirty_projected_inode(mdr->ls); - dn->mark_dirty(dnpv, mdr->ls); - mdr->apply(); + dn->mark_dirty(dnpv, mdr->ls); // share unlink news with replicas for (map::iterator it = dn->replicas_begin(); diff --git a/src/mds/Server.h b/src/mds/Server.h index 266de1b568596..a24304a54d4e8 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -137,7 +137,7 @@ public: void _link_remote(MDRequest *mdr, CDentry *dn, CInode *targeti); void _link_remote_finish(MDRequest *mdr, CDentry *dn, CInode *targeti, - version_t, version_t); + version_t); void handle_slave_link_prep(MDRequest *mdr); void _logged_slave_link(MDRequest *mdr, CInode *targeti, utime_t old_ctime, bool inc); -- 2.39.5