From: Sage Weil Date: Fri, 15 Oct 2010 14:59:29 +0000 (-0700) Subject: mds: take nestlock wrlock when projecting rstat into dirfrag X-Git-Tag: v0.22~5 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=d8ee92a6423cd6b766f1b85799c96eb1521be078;p=ceph.git mds: take nestlock wrlock when projecting rstat into dirfrag We were already checking that we _can_ wrlock before doing the rstat projection (if we can't, we mark_dirty_rstat() on the inode), but we weren't actually taking the wrlock to prevent lock state changes while that happened. This bug eventually manifested itself as a failed assertion at the now familiar mds/CInode.cc: In function 'virtual void CInode::decode_lock_state(int, ceph::bufferlist&)': mds/CInode.cc:1364: FAILED assert(pf->rstat == rstat) Signed-off-by: Sage Weil --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 2bb884240e7da..e9d8036452918 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -1764,6 +1764,15 @@ void MDCache::predirty_journal_parents(Mutation *mut, EMetaBlob *blob, << ", marking dirty rstat on " << *cur << dendl; cur->mark_dirty_rstat(); } else { + // if we don't hold a wrlock reference on this nestlock, take one, + // because we are about to write into the dirfrag fnode and that needs + // to commit before the lock can cycle. + if (mut->wrlocks.count(&parent->inode->nestlock) == 0) { + dout(10) << " taking wrlock on " << parent->inode->nestlock << " on " << *parent->inode << dendl; + mds->locker->wrlock_force(&parent->inode->nestlock, mut); + } + + // now we can project the inode rstat diff the dirfrag SnapRealm *prealm = parent->inode->find_snaprealm(); snapid_t follows = cfollows;