From: Sage Weil Date: Wed, 27 Apr 2011 22:09:35 +0000 (-0700) Subject: mds: freeze fragments during split/merge X-Git-Tag: v0.28~139^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d6917cd731c25917dd1f5489ba7b06e333700d3b;p=ceph.git mds: freeze fragments during split/merge Freeze the target fragment(s) before unfreezing the old fragment(s) to avoid any weird events going off when the unfreeze unauth_pins the dir inode (in certain cases). This makes the whole process cleaner and more symmetrical. Signed-off-by: Sage Weil --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 8821d00aa1536..2c921c0acc15e 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -659,7 +659,7 @@ void CDir::purge_stale_snap_data(const set& snaps) /** * steal_dentry -- semi-violently move a dentry from one CDir to another * (*) violently, in that nitems, most pins, etc. are not correctly maintained - * on the old CDir corpse; must call purge_stolen() when finished. + * on the old CDir corpse; must call finish_old_fragment() when finished. */ void CDir::steal_dentry(CDentry *dn) { @@ -722,7 +722,13 @@ void CDir::steal_dentry(CDentry *dn) dn->dir = this; } -void CDir::purge_stolen(list& waiters, bool replay) +void CDir::prepare_new_fragment(bool replay) +{ + if (!replay && is_auth()) + _freeze_dir(); +} + +void CDir::finish_old_fragment(list& waiters, bool replay) { // take waiters _before_ unfreeze... if (!replay) { @@ -818,6 +824,8 @@ void CDir::split(int bits, list& subs, list& waiters, bool repl subfrags[n++] = f; subs.push_back(f); inode->add_dirfrag(f); + + f->prepare_new_fragment(replay); } // repartition dentries @@ -854,13 +862,15 @@ void CDir::split(int bits, list& subs, list& waiters, bool repl subfrags[0]->fnode.accounted_rstat.add_delta(zero, olddiff); dout(10) << " " << subfrags[0]->fnode.accounted_fragstat << dendl; - purge_stolen(waiters, replay); + finish_old_fragment(waiters, replay); } void CDir::merge(list& subs, list& waiters, bool replay) { dout(10) << "merge " << subs << dendl; + prepare_new_fragment(replay); + // see if _any_ of the source frags have stale fragstat or rstat int stale_rstat = 0; int stale_fragstat = 0; @@ -906,7 +916,7 @@ void CDir::merge(list& subs, list& waiters, bool replay) state_set(dir->get_state() & MASK_STATE_FRAGMENT_KEPT); dir_auth = dir->dir_auth; - dir->purge_stolen(waiters, replay); + dir->finish_old_fragment(waiters, replay); inode->close_dirfrag(dir->get_frag()); } diff --git a/src/mds/CDir.h b/src/mds/CDir.h index 2060e98473e66..80c68c5d097b8 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -370,8 +370,9 @@ public: } private: + void prepare_new_fragment(bool replay); void steal_dentry(CDentry *dn); // from another dir. used by merge/split. - void purge_stolen(list& waiters, bool replay); + void finish_old_fragment(list& waiters, bool replay); void init_fragment_pins(); diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index a5cf7ef6af385..b6e3d19f6e74a 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -4607,7 +4607,7 @@ void MDCache::open_snap_parents() q++) for (set::iterator r = q->second.begin(); r != q->second.end(); - r++) + r++) prepare_realm_split(in->snaprealm, q->first, *r, splits); missing_snap_parents.erase(p++); @@ -9617,7 +9617,6 @@ void MDCache::fragment_frozen(list& dirs, frag_t basefrag, int bits) // freeze and store them too dir->state_set(CDir::STATE_FRAGMENTING); dir->commit(0, gather->new_sub(), true); // ignore authpinnability - dir->_freeze_dir(); } mds->mdlog->submit_entry(le, gather->new_sub());