From d8ee92a6423cd6b766f1b85799c96eb1521be078 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 15 Oct 2010 07:59:29 -0700 Subject: [PATCH] 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 --- src/mds/MDCache.cc | 9 +++++++++ 1 file changed, 9 insertions(+) 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; -- 2.39.5