]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: take nestlock wrlock when projecting rstat into dirfrag
authorSage Weil <sage@newdream.net>
Fri, 15 Oct 2010 14:59:29 +0000 (07:59 -0700)
committerSage Weil <sage@newdream.net>
Fri, 15 Oct 2010 20:41:03 +0000 (13:41 -0700)
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 <sage@newdream.net>
src/mds/MDCache.cc

index 2bb884240e7da23eddf4876dc50de6a2806b114f..e9d8036452918ae9b5f8f86ee4af62018d58aff4 100644 (file)
@@ -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;