From: Sage Weil Date: Mon, 2 Jun 2008 17:46:58 +0000 (-0700) Subject: mds: check/take versionlock along with wrlock in predirty_nested X-Git-Tag: v0.3~170^2~18 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4dac2778f815f001adcb8abc946b219bb27cd142;p=ceph.git mds: check/take versionlock along with wrlock in predirty_nested --- diff --git a/src/TODO b/src/TODO index 3c5c5f3d5a6..762fd5940d7 100644 --- a/src/TODO +++ b/src/TODO @@ -68,9 +68,13 @@ mds mustfix - fix rejoin vs updated dirfrag nested/dirlocks - not inode_full, now.. send the fnode. but for auth dirfrags, _to_ inode auth... which is sorta outside the subtree..? +- fix completed_request list on master, for disambiguating slaves. (sessionmap's complete list is trimmed based on client, not slave ops.) + - keep mdrequest open? is this useful for the srci export trimming? + - special list? needs master journal entry to finish commit, and extra message from slave->master after the commit. + /- locks (esp scatter) vs rejoin, scatter_writebehind - make sure locker avoids frozen inodes -- make sure predirty_nested stops if it can't wrlock versionlock (acquire_locks normally hides that detail for us) +/- make sure predirty_nested stops if it can't wrlock versionlock (acquire_locks normally hides that detail for us) - make sure stray inode is always opened on startup - make sure inode cache expire for frozen inode behaves diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 53152da7e98..9913fecae0f 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -1237,7 +1237,6 @@ void Locker::revoke_client_leases(SimpleLock *lock) * the scatterlock on a list if it isn't already wrlockable. this is * probably the best plan anyway, since we avoid too many * scatters/locks under normal usage. - * */ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob, CInode *in, CDir *parent, @@ -1344,15 +1343,18 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob, break; bool stop = false; - if (mut->wrlocks.count(&pin->dirlock) == 0 && - !scatter_wrlock_try(&pin->dirlock, mut, false)) { // ** do not initiate.. see above comment ** - dout(10) << "predirty_nested can't wrlock " << pin->dirlock << " on " << *pin << dendl; - stop = true; - } if (!pin->is_auth() || pin->is_ambiguous_auth()) { dout(10) << "predirty_nested !auth or ambig on " << *pin << dendl; stop = true; } + if (!stop && + mut->wrlocks.count(&pin->dirlock) == 0 && + (!pin->versionlock.can_wrlock() || // make sure we can take versionlock, too + !scatter_wrlock_try(&pin->dirlock, mut, false))) { // ** do not initiate.. see above comment ** + dout(10) << "predirty_nested can't wrlock one of " << pin->versionlock << " or " << pin->dirlock + << " on " << *pin << dendl; + stop = true; + } if (stop) { dout(10) << "predirty_nested stop. marking dirlock on " << *pin << dendl; pin->dirlock.set_updated(); @@ -1360,6 +1362,7 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob, mut->ls->dirty_dirfrag_dir.push_back(&pin->xlist_dirty_dirfrag_dir); break; } + local_wrlock_grab(&pin->versionlock, mut); // dirfrag -> diri mut->add_projected_inode(pin); @@ -2770,6 +2773,16 @@ void Locker::scatter_unscatter_autoscattered() // ========================================================================== // local lock +void Locker::local_wrlock_grab(LocalLock *lock, Mutation *mut) +{ + dout(7) << "local_wrlock_try on " << *lock + << " on " << *lock->get_parent() << dendl; + + assert(lock->can_wrlock()); + lock->get_wrlock(); + mut->wrlocks.insert(lock); + mut->locks.insert(lock); +} bool Locker::local_wrlock_start(LocalLock *lock, MDRequest *mut) { diff --git a/src/mds/Locker.h b/src/mds/Locker.h index a0c76b53c97..48d46959530 100644 --- a/src/mds/Locker.h +++ b/src/mds/Locker.h @@ -170,6 +170,7 @@ public: // local protected: + void local_wrlock_grab(LocalLock *lock, Mutation *mut); bool local_wrlock_start(LocalLock *lock, MDRequest *mut); void local_wrlock_finish(LocalLock *lock, Mutation *mut); bool local_xlock_start(LocalLock *lock, MDRequest *mut);