We make multiple iterations through populate_mydir(). Only pin each stray
once. Fixes #689 and crashes like
mds/CInode.h: In function 'virtual void CInode::bad_get(int)':
mds/CInode.h:1088: FAILED assert(ref_set.count(by) == 0)
ceph version 0.24 (
180a4176035521940390f4ce24ee3eb7aa290632)
1: (CInode::bad_put(int)+0) [0x827b090]
2: (MDSCacheObject::get(int)+0x153) [0x813e463]
3: (MDCache::populate_mydir()+0x8a) [0x81a7e5a]
4: (MDCache::_create_system_file_finish(Mutation*, CDentry*,
Context*)+0x181) [0x819f501]
5: (C_MDC_CreateSystemFile::finish(int)+0x29) [0x81d6c29]
6: (finish_contexts(std::list<Context*, std::allocator<Context*> >&,
int)+0x6b) [0x81d663b]
7: (Journaler::_finish_flush(int, long long, utime_t, bool)+0x983) [0x82f2f53]
8: (Journaler::C_Flush::finish(int)+0x3f) [0x82fb24f]
9: (Objecter::handle_osd_op_reply(MOSDOpReply*)+0x801) [0x82d8e31]
10: (MDS::_dispatch(Message*)+0x2ae5) [0x80eaa15]
11: (MDS::ms_dispatch(Message*)+0x62) [0x80eb142]
12: (SimpleMessenger::dispatch_entry()+0x899) [0x80b8649]
13: (SimpleMessenger::DispatchThread::entry()+0x22) [0x80b30f2]
Signed-off-by: Sage Weil <sage@newdream.net>
static const int STATE_PURGING = (1<<13);
static const int STATE_DIRTYPARENT = (1<<14);
static const int STATE_DIRTYRSTAT = (1<<15);
+ static const int STATE_STRAYPINNED = (1<<16);
// -- waiters --
static const uint64_t WAIT_DIR = (1<<0);
}
assert(straydn);
assert(strays[i]);
- strays[i]->get(CInode::PIN_STRAY);
+ // we make multiple passes through this method; make sure we only pin each stray once.
+ if (!strays[i]->state_test(CInode::STATE_STRAYPINNED)) {
+ strays[i]->get(CInode::PIN_STRAY);
+ strays[i]->state_set(CInode::STATE_STRAYPINNED);
+ }
dout(20) << " stray num " << i << " is " << *strays[i] << dendl;
}