mirror of
https://github.com/ceph/ceph
synced 2025-04-01 00:26:47 +00:00
Merge pull request #12125 from ukernel/wip-17990
mds: properly commit new dirfrag before splitting it Reviewed-by: Greg Farnum <gfarnum@redhat.com>
This commit is contained in:
commit
6c5958c1f5
@ -1223,6 +1223,11 @@ void CDir::add_waiter(uint64_t tag, MDSInternalContextBase *c)
|
||||
}
|
||||
}
|
||||
|
||||
if (tag & WAIT_CREATED) {
|
||||
assert(state_test(STATE_CREATING));
|
||||
assert(state_test(STATE_FRAGMENTING));
|
||||
}
|
||||
|
||||
MDSCacheObject::add_waiter(tag, c);
|
||||
}
|
||||
|
||||
@ -1334,6 +1339,13 @@ void CDir::_mark_dirty(LogSegment *ls)
|
||||
void CDir::mark_new(LogSegment *ls)
|
||||
{
|
||||
ls->new_dirfrags.push_back(&item_new);
|
||||
state_clear(STATE_CREATING);
|
||||
|
||||
if (state_test(CDir::STATE_FRAGMENTING)) {
|
||||
list<MDSInternalContextBase*> ls;
|
||||
take_waiting(CDir::WAIT_CREATED, ls);
|
||||
cache->mds->queue_waiters(ls);
|
||||
}
|
||||
}
|
||||
|
||||
void CDir::mark_clean()
|
||||
|
@ -99,6 +99,7 @@ public:
|
||||
static const unsigned STATE_FREEZINGDIR = (1<< 5);
|
||||
static const unsigned STATE_COMMITTING = (1<< 6); // mid-commit
|
||||
static const unsigned STATE_FETCHING = (1<< 7); // currenting fetching
|
||||
static const unsigned STATE_CREATING = (1<< 8);
|
||||
static const unsigned STATE_IMPORTBOUND = (1<<10);
|
||||
static const unsigned STATE_EXPORTBOUND = (1<<11);
|
||||
static const unsigned STATE_EXPORTING = (1<<12);
|
||||
@ -149,6 +150,7 @@ public:
|
||||
static const uint64_t WAIT_DENTRY = (1<<0); // wait for item to be in cache
|
||||
static const uint64_t WAIT_COMPLETE = (1<<1); // wait for complete dir contents
|
||||
static const uint64_t WAIT_FROZEN = (1<<2); // auth pins removed
|
||||
static const uint64_t WAIT_CREATED = (1<<3); // new dirfrag is logged
|
||||
|
||||
static const int WAIT_DNLOCK_OFFSET = 4;
|
||||
|
||||
|
@ -10840,15 +10840,20 @@ void MDCache::fragment_mark_and_complete(MDRequestRef& mdr)
|
||||
dout(15) << " fetching incomplete " << *dir << dendl;
|
||||
dir->fetch(gather.new_sub(), true); // ignore authpinnability
|
||||
ready = false;
|
||||
}
|
||||
if (dir->get_frag() == frag_t() && dir->is_new()) {
|
||||
} else if (dir->get_frag() == frag_t()) {
|
||||
// The COMPLETE flag gets lost if we fragment a new dirfrag, then rollback
|
||||
// the operation. To avoid CDir::fetch() complaining about missing object,
|
||||
// we commit new dirfrag first.
|
||||
dout(15) << " committing new " << *dir << dendl;
|
||||
assert(dir->is_dirty());
|
||||
dir->commit(0, gather.new_sub(), true);
|
||||
ready = false;
|
||||
if (dir->state_test(CDir::STATE_CREATING)) {
|
||||
dout(15) << " waiting until new dir gets journaled " << *dir << dendl;
|
||||
dir->add_waiter(CDir::WAIT_CREATED, gather.new_sub());
|
||||
ready = false;
|
||||
} else if (dir->is_new()) {
|
||||
dout(15) << " committing new " << *dir << dendl;
|
||||
assert(dir->is_dirty());
|
||||
dir->commit(0, gather.new_sub(), true);
|
||||
ready = false;
|
||||
}
|
||||
}
|
||||
if (!ready)
|
||||
continue;
|
||||
|
@ -4789,6 +4789,7 @@ void Server::handle_client_mkdir(MDRequestRef& mdr)
|
||||
|
||||
// ...and that new dir is empty.
|
||||
CDir *newdir = newi->get_or_open_dirfrag(mdcache, frag_t());
|
||||
newdir->state_set(CDir::STATE_CREATING);
|
||||
newdir->mark_complete();
|
||||
newdir->fnode.version = newdir->pre_dirty();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user