#include "include/filepath.h"
#include "MDSCacheObject.h"
+#include "MDSContext.h"
#include "SimpleLock.h"
#include "LocalLock.h"
#include "ScrubHeader.h"
dn->dir = this;
}
-void CDir::prepare_old_fragment(map<string_snap_t, std::list<MDSInternalContextBase*> >& dentry_waiters, bool replay)
+void CDir::prepare_old_fragment(map<string_snap_t, MDSInternalContextBase::vec >& dentry_waiters, bool replay)
{
// auth_pin old fragment for duration so that any auth_pinning
// during the dentry migration doesn't trigger side effects
inode->add_dirfrag(this);
}
-void CDir::finish_old_fragment(list<MDSInternalContextBase*>& waiters, bool replay)
+void CDir::finish_old_fragment(MDSInternalContextBase::vec& waiters, bool replay)
{
// take waiters _before_ unfreeze...
if (!replay) {
get(PIN_SUBTREE);
}
-void CDir::split(int bits, list<CDir*>& subs, list<MDSInternalContextBase*>& waiters, bool replay)
+void CDir::split(int bits, list<CDir*>& subs, MDSInternalContextBase::vec& waiters, bool replay)
{
dout(10) << "split by " << bits << " bits on " << *this << dendl;
fragstatdiff.add_delta(fnode.accounted_fragstat, fnode.fragstat);
dout(10) << " rstatdiff " << rstatdiff << " fragstatdiff " << fragstatdiff << dendl;
- map<string_snap_t, std::list<MDSInternalContextBase*> > dentry_waiters;
+ map<string_snap_t, MDSInternalContextBase::vec > dentry_waiters;
prepare_old_fragment(dentry_waiters, replay);
// create subfrag dirs
finish_old_fragment(waiters, replay);
}
-void CDir::merge(list<CDir*>& subs, list<MDSInternalContextBase*>& waiters, bool replay)
+void CDir::merge(list<CDir*>& subs, MDSInternalContextBase::vec& waiters, bool replay)
{
dout(10) << "merge " << subs << dendl;
version_t rstat_version = inode->get_projected_inode()->rstat.version;
version_t dirstat_version = inode->get_projected_inode()->dirstat.version;
- map<string_snap_t, std::list<MDSInternalContextBase*> > dentry_waiters;
+ map<string_snap_t, MDSInternalContextBase::vec > dentry_waiters;
for (auto dir : subs) {
dout(10) << " subfrag " << dir->get_frag() << " " << *dir << dendl;
}
void CDir::take_dentry_waiting(std::string_view dname, snapid_t first, snapid_t last,
- list<MDSInternalContextBase*>& ls)
+ MDSInternalContextBase::vec& ls)
{
if (waiting_on_dentry.empty())
return;
put(PIN_DNWAITER);
}
-void CDir::take_sub_waiting(list<MDSInternalContextBase*>& ls)
+void CDir::take_sub_waiting(MDSInternalContextBase::vec& ls)
{
dout(10) << __func__ << dendl;
if (!waiting_on_dentry.empty()) {
/* NOTE: this checks dentry waiters too */
-void CDir::take_waiting(uint64_t mask, list<MDSInternalContextBase*>& ls)
+void CDir::take_waiting(uint64_t mask, MDSInternalContextBase::vec& ls)
{
if ((mask & WAIT_DENTRY) && !waiting_on_dentry.empty()) {
// take all dentry waiters
{
dout(11) << __func__ << " mask " << hex << mask << dec << " result " << result << " on " << *this << dendl;
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
take_waiting(mask, finished);
if (result < 0)
finish_contexts(g_ceph_context, finished, result);
ls->new_dirfrags.push_back(&item_new);
state_clear(STATE_CREATING);
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
take_waiting(CDir::WAIT_CREATED, waiters);
cache->mds->queue_waiters(waiters);
}
_commit(it->first, -1);
break;
}
- std::list<MDSInternalContextBase*> t;
+ MDSInternalContextBase::vec t;
for (const auto &waiter : it->second)
t.push_back(waiter);
cache->mds->queue_waiters(t);
// newly single auth?
if (was_ambiguous && dir_auth.second == CDIR_AUTH_UNKNOWN) {
- list<MDSInternalContextBase*> ls;
+ MDSInternalContextBase::vec ls;
take_waiting(WAIT_SINGLEAUTH, ls);
cache->mds->queue_waiters(ls);
}
#include "CInode.h"
#include "MDSCacheObject.h"
+#include "MDSContext.h"
class CDentry;
class MDCache;
public:
- void split(int bits, std::list<CDir*>& subs, list<MDSInternalContextBase*>& waiters, bool replay);
- void merge(std::list<CDir*>& subs, std::list<MDSInternalContextBase*>& waiters, bool replay);
+ void split(int bits, std::list<CDir*>& subs, MDSInternalContextBase::vec& waiters, bool replay);
+ void merge(std::list<CDir*>& subs, MDSInternalContextBase::vec& waiters, bool replay);
bool should_split() const {
return (int)get_frag_size() > g_conf()->mds_bal_split_size;
private:
void prepare_new_fragment(bool replay);
- void prepare_old_fragment(map<string_snap_t, std::list<MDSInternalContextBase*> >& dentry_waiters, bool replay);
+ void prepare_old_fragment(map<string_snap_t, MDSInternalContextBase::vec >& dentry_waiters, bool replay);
void steal_dentry(CDentry *dn); // from another dir. used by merge/split.
- void finish_old_fragment(std::list<MDSInternalContextBase*>& waiters, bool replay);
+ void finish_old_fragment(MDSInternalContextBase::vec& waiters, bool replay);
void init_fragment_pins();
bool complete, int r);
// -- commit --
- mempool::mds_co::compact_map<version_t, mempool::mds_co::list<MDSInternalContextBase*> > waiting_for_commit;
+ mempool::mds_co::compact_map<version_t, MDSInternalContextBase::vec_alloc<mempool::mds_co::pool_allocator> > waiting_for_commit;
void _commit(version_t want, int op_prio);
void _omap_commit(int op_prio);
void _encode_dentry(CDentry *dn, bufferlist& bl, const std::set<snapid_t> *snaps);
// -- waiters --
protected:
- mempool::mds_co::compact_map< string_snap_t, mempool::mds_co::list<MDSInternalContextBase*> > waiting_on_dentry; // FIXME string_snap_t not in mempool
+ mempool::mds_co::compact_map< string_snap_t, MDSInternalContextBase::vec_alloc<mempool::mds_co::pool_allocator> > waiting_on_dentry; // FIXME string_snap_t not in mempool
public:
bool is_waiting_for_dentry(std::string_view dname, snapid_t snap) {
return waiting_on_dentry.count(string_snap_t(dname, snap));
}
void add_dentry_waiter(std::string_view dentry, snapid_t snap, MDSInternalContextBase *c);
- void take_dentry_waiting(std::string_view dentry, snapid_t first, snapid_t last, std::list<MDSInternalContextBase*>& ls);
- void take_sub_waiting(std::list<MDSInternalContextBase*>& ls); // dentry or ino
+ void take_dentry_waiting(std::string_view dentry, snapid_t first, snapid_t last, MDSInternalContextBase::vec& ls);
+ void take_sub_waiting(MDSInternalContextBase::vec& ls); // dentry or ino
void add_waiter(uint64_t mask, MDSInternalContextBase *c) override;
- void take_waiting(uint64_t mask, std::list<MDSInternalContextBase*>& ls) override; // may include dentry waiters
+ void take_waiting(uint64_t mask, MDSInternalContextBase::vec& ls) override; // may include dentry waiters
void finish_waiting(uint64_t mask, int result = 0); // ditto
dout(10) << __func__ << " frag " << fg << " " << c << " on " << *this << dendl;
}
-void CInode::take_dir_waiting(frag_t fg, list<MDSInternalContextBase*>& ls)
+void CInode::take_dir_waiting(frag_t fg, MDSInternalContextBase::vec& ls)
{
if (waiting_on_dir.empty())
return;
auto it = waiting_on_dir.find(fg);
if (it != waiting_on_dir.end()) {
dout(10) << __func__ << " frag " << fg << " on " << *this << dendl;
- ls.splice(ls.end(), it->second);
+ auto& waiting = it->second;
+ ls.insert(ls.end(), waiting.begin(), waiting.end());
waiting_on_dir.erase(it);
if (waiting_on_dir.empty())
MDSCacheObject::add_waiter(tag, c);
}
-void CInode::take_waiting(uint64_t mask, list<MDSInternalContextBase*>& ls)
+void CInode::take_waiting(uint64_t mask, MDSInternalContextBase::vec& ls)
{
if ((mask & WAIT_DIR) && !waiting_on_dir.empty()) {
// take all dentry waiters
while (!waiting_on_dir.empty()) {
auto it = waiting_on_dir.begin();
dout(10) << __func__ << " dirfrag " << it->first << " on " << *this << dendl;
- ls.splice(ls.end(), it->second);
+ auto& waiting = it->second;
+ ls.insert(ls.end(), waiting.begin(), waiting.end());
waiting_on_dir.erase(it);
}
put(PIN_DIRWAITER);
return true;
}
-void CInode::unfreeze_inode(list<MDSInternalContextBase*>& finished)
+void CInode::unfreeze_inode(MDSInternalContextBase::vec& finished)
{
dout(10) << __func__ << dendl;
if (state_test(STATE_FREEZING)) {
void CInode::unfreeze_inode()
{
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
unfreeze_inode(finished);
mdcache->mds->queue_waiters(finished);
}
assert(state_test(CInode::STATE_FROZENAUTHPIN));
state_clear(CInode::STATE_FROZENAUTHPIN);
if (!state_test(STATE_FREEZING|STATE_FROZEN)) {
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
take_waiting(WAIT_UNFREEZE, finished);
mdcache->mds->queue_waiters(finished);
}
}
-void CInode::clear_ambiguous_auth(list<MDSInternalContextBase*>& finished)
+void CInode::clear_ambiguous_auth(MDSInternalContextBase::vec& finished)
{
assert(state_test(CInode::STATE_AMBIGUOUSAUTH));
state_clear(CInode::STATE_AMBIGUOUSAUTH);
void CInode::clear_ambiguous_auth()
{
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
clear_ambiguous_auth(finished);
mdcache->mds->queue_waiters(finished);
}
bool fcntl_removed = fcntl_locks ? fcntl_locks->remove_all_from(client) : false;
bool flock_removed = flock_locks ? flock_locks->remove_all_from(client) : false;
if (fcntl_removed || flock_removed) {
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
take_waiting(CInode::WAIT_FLOCK, waiters);
mdcache->mds->queue_waiters(waiters);
}
policylock.mark_need_recover();
}
}
-void CInode::_decode_locks_rejoin(bufferlist::const_iterator& p, list<MDSInternalContextBase*>& waiters,
+void CInode::_decode_locks_rejoin(bufferlist::const_iterator& p, MDSInternalContextBase::vec& waiters,
list<SimpleLock*>& eval_locks, bool survivor)
{
authlock.decode_state_rejoin(p, waiters, survivor);
#include "include/compact_set.h"
#include "MDSCacheObject.h"
+#include "MDSContext.h"
#include "flock.h"
#include "CDentry.h"
void set_ambiguous_auth() {
state_set(STATE_AMBIGUOUSAUTH);
}
- void clear_ambiguous_auth(std::list<MDSInternalContextBase*>& finished);
+ void clear_ambiguous_auth(MDSInternalContextBase::vec& finished);
void clear_ambiguous_auth();
inodeno_t ino() const { return inode.ino; }
// -- waiting --
protected:
- mempool::mds_co::compact_map<frag_t, std::list<MDSInternalContextBase*> > waiting_on_dir;
+ mempool::mds_co::compact_map<frag_t, MDSInternalContextBase::vec > waiting_on_dir;
public:
void add_dir_waiter(frag_t fg, MDSInternalContextBase *c);
- void take_dir_waiting(frag_t fg, std::list<MDSInternalContextBase*>& ls);
+ void take_dir_waiting(frag_t fg, MDSInternalContextBase::vec& ls);
bool is_waiting_for_dir(frag_t fg) {
return waiting_on_dir.count(fg);
}
void add_waiter(uint64_t tag, MDSInternalContextBase *c) override;
- void take_waiting(uint64_t tag, std::list<MDSInternalContextBase*>& ls) override;
+ void take_waiting(uint64_t tag, MDSInternalContextBase::vec& ls) override;
// -- encode/decode helpers --
void _encode_base(bufferlist& bl, uint64_t features);
void _encode_locks_state_for_replica(bufferlist& bl, bool need_recover);
void _encode_locks_state_for_rejoin(bufferlist& bl, int rep);
void _decode_locks_state(bufferlist::const_iterator& p, bool is_new);
- void _decode_locks_rejoin(bufferlist::const_iterator& p, std::list<MDSInternalContextBase*>& waiters,
+ void _decode_locks_rejoin(bufferlist::const_iterator& p, MDSInternalContextBase::vec& waiters,
std::list<SimpleLock*>& eval_locks, bool survivor);
// -- import/export --
/* Freeze the inode. auth_pin_allowance lets the caller account for any
* auth_pins it is itself holding/responsible for. */
bool freeze_inode(int auth_pin_allowance=0);
- void unfreeze_inode(std::list<MDSInternalContextBase*>& finished);
+ void unfreeze_inode(MDSInternalContextBase::vec& finished);
void unfreeze_inode();
void freeze_auth_pin();
// generics
-void Locker::eval_gather(SimpleLock *lock, bool first, bool *pneed_issue, list<MDSInternalContextBase*> *pfinishers)
+void Locker::eval_gather(SimpleLock *lock, bool first, bool *pneed_issue, MDSInternalContextBase::vec *pfinishers)
{
dout(10) << "eval_gather " << *lock << " on " << *lock->get_parent() << dendl;
assert(!lock->is_stable());
bool Locker::eval(CInode *in, int mask, bool caps_imported)
{
bool need_issue = caps_imported;
- list<MDSInternalContextBase*> finishers;
+ MDSInternalContextBase::vec finishers;
dout(10) << "eval " << mask << " " << *in << dendl;
void Locker::eval_cap_gather(CInode *in, set<CInode*> *issue_set)
{
bool need_issue = false;
- list<MDSInternalContextBase*> finishers;
+ MDSInternalContextBase::vec finishers;
// kick locks now
if (!in->filelock.is_stable())
void Locker::eval_scatter_gathers(CInode *in)
{
bool need_issue = false;
- list<MDSInternalContextBase*> finishers;
+ MDSInternalContextBase::vec finishers;
dout(10) << "eval_scatter_gathers " << *in << dendl;
#include "CInode.h"
#include "SimpleLock.h"
+#include "MDSContext.h"
#include "Mutation.h"
class Locker {
void drop_non_rdlocks(MutationImpl *mut, set<CInode*> *pneed_issue=0);
void drop_rdlocks_for_early_reply(MutationImpl *mut);
- void eval_gather(SimpleLock *lock, bool first=false, bool *need_issue=0, list<MDSInternalContextBase*> *pfinishers=0);
+ void eval_gather(SimpleLock *lock, bool first=false, bool *need_issue=0, MDSInternalContextBase::vec *pfinishers=0);
void eval(SimpleLock *lock, bool *need_issue);
- void eval_any(SimpleLock *lock, bool *need_issue, list<MDSInternalContextBase*> *pfinishers=0, bool first=false) {
+ void eval_any(SimpleLock *lock, bool *need_issue, MDSInternalContextBase::vec *pfinishers=0, bool first=false) {
if (!lock->is_stable())
eval_gather(lock, first, need_issue, pfinishers);
else if (lock->get_parent()->is_auth())
#include "include/elist.h"
#include "include/interval_set.h"
#include "include/Context.h"
+#include "MDSContext.h"
#include "mdstypes.h"
#include "CInode.h"
#include "CDentry.h"
#include "CDir.h"
-#include "MDSContext.h"
#include "include/unordered_set.h"
using ceph::unordered_set;
// try to expire
void try_to_expire(MDSRank *mds, MDSGatherBuilder &gather_bld, int op_prio);
- std::list<MDSInternalContextBase*> expiry_waiters;
+ MDSInternalContextBase::vec expiry_waiters;
void wait_for_expiry(MDSInternalContextBase *c)
{
static const uint64_t i_mask = CInode::WAIT_ANY_MASK & ~CInode::WAIT_DIR;
static const uint64_t d_mask = CDir::WAIT_ANY_MASK & ~CDir::WAIT_DENTRY;
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
// wake up any waiters in their subtrees
for (map<CDir*,set<CDir*> >::iterator p = subtrees.begin();
mds->heartbeat_reset();
}
- for (map<inodeno_t, list<MDSInternalContextBase*> >::iterator p = cap_reconnect_waiters.begin();
+ for (map<inodeno_t, MDSInternalContextBase::vec >::iterator p = cap_reconnect_waiters.begin();
p != cap_reconnect_waiters.end();
++p)
mds->queue_waiters(p->second);
dout(15) << " chose lock states on " << *in << dendl;
}
- map<inodeno_t, list<MDSInternalContextBase*> >::iterator it =
+ map<inodeno_t, MDSInternalContextBase::vec >::iterator it =
cap_reconnect_waiters.find(in->ino());
if (it != cap_reconnect_waiters.end()) {
mds->queue_waiters(it->second);
in->put(CInode::PIN_TRUNCATING);
in->auth_unpin(this);
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
in->take_waiting(CInode::WAIT_TRUNC, waiters);
mds->queue_waiters(waiters);
}
{
dout(10) << "open_ino_finish ino " << ino << " ret " << ret << dendl;
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
waiters.swap(info.waiters);
opening_inodes.erase(ino);
finish_contexts(g_ceph_context, waiters, ret);
base->add_waiter(CInode::WAIT_SINGLEAUTH, onfinish);
return;
} else if (from == mds->get_nodeid()) {
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
base->take_waiting(CInode::WAIT_DIR, finished);
mds->queue_waiters(finished);
return;
base->add_waiter(CDir::WAIT_SINGLEAUTH, onfinish);
return;
} else if (from == mds->get_nodeid()) {
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
base->take_sub_waiting(finished);
mds->queue_waiters(finished);
return;
if (m->is_flag_error_dn())
dout(7) << " flag error, dentry = " << m->get_error_dentry() << dendl;
- list<MDSInternalContextBase*> finished, error;
+ MDSInternalContextBase::vec finished, error;
mds_rank_t from = mds_rank_t(m->get_source().num());
// starting point
}
CDir *MDCache::add_replica_dir(bufferlist::const_iterator& p, CInode *diri, mds_rank_t from,
- list<MDSInternalContextBase*>& finished)
+ MDSInternalContextBase::vec& finished)
{
dirfrag_t df;
decode(df, p);
return dir;
}
-CDentry *MDCache::add_replica_dentry(bufferlist::const_iterator& p, CDir *dir, list<MDSInternalContextBase*>& finished)
+CDentry *MDCache::add_replica_dentry(bufferlist::const_iterator& p, CDir *dir, MDSInternalContextBase::vec& finished)
{
string name;
snapid_t last;
return dn;
}
-CInode *MDCache::add_replica_inode(bufferlist::const_iterator& p, CDentry *dn, list<MDSInternalContextBase*>& finished)
+CInode *MDCache::add_replica_inode(bufferlist::const_iterator& p, CDentry *dn, MDSInternalContextBase::vec& finished)
{
inodeno_t ino;
snapid_t last;
CDentry *MDCache::add_replica_stray(bufferlist &bl, mds_rank_t from)
{
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
auto p = bl.cbegin();
CInode *mdsin = add_replica_inode(p, NULL, finished);
}
auto p = m->bl.cbegin();
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
if (dn) {
if (m->get_is_primary()) {
// primary link.
*/
void MDCache::adjust_dir_fragments(CInode *diri, frag_t basefrag, int bits,
list<CDir*>& resultfrags,
- list<MDSInternalContextBase*>& waiters,
+ MDSInternalContextBase::vec& waiters,
bool replay)
{
dout(10) << "adjust_dir_fragments " << basefrag << " " << bits
dout(10) << "force_dir_fragment " << fg << " on " << *diri << dendl;
list<CDir*> src, result;
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
// split a parent?
frag_t parent = diri->dirfragtree.get_branch_or_leaf(fg);
list<CDir*>& srcfrags,
frag_t basefrag, int bits,
list<CDir*>& resultfrags,
- list<MDSInternalContextBase*>& waiters,
+ MDSInternalContextBase::vec& waiters,
bool replay)
{
dout(10) << "adjust_dir_fragments " << basefrag << " bits " << bits
}
// refragment
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
adjust_dir_fragments(diri, info.dirs, basedirfrag.frag, info.bits,
info.resultfrags, waiters, false);
if (g_conf()->mds_debug_frag)
*/
// refragment
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
list<CDir*> resultfrags;
adjust_dir_fragments(diri, base, bits, resultfrags, waiters, false);
if (g_conf()->mds_debug_frag)
list<CDir*> resultfrags;
if (uf.old_frags.empty()) {
// created by old format EFragment
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
adjust_dir_fragments(diri, p->first.frag, -uf.bits, resultfrags, waiters, true);
} else {
auto bp = uf.rollback.cbegin();
}
// waiters
- map<int, map<inodeno_t, list<MDSInternalContextBase*> > > waiting_for_base_ino;
+ map<int, map<inodeno_t, MDSInternalContextBase::vec > > waiting_for_base_ino;
void discover_base_ino(inodeno_t want_ino, MDSInternalContextBase *onfinish, mds_rank_t from=MDS_RANK_NONE);
void discover_dir_frag(CInode *base, frag_t approx_fg, MDSInternalContextBase *onfinish,
struct umaster {
set<mds_rank_t> slaves;
LogSegment *ls;
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
bool safe;
bool committing;
bool recovering;
map<inodeno_t,map<client_t,map<mds_rank_t,cap_reconnect_t> > > cap_imports; // ino -> client -> frommds -> capex
set<inodeno_t> cap_imports_missing;
- map<inodeno_t, list<MDSInternalContextBase*> > cap_reconnect_waiters;
+ map<inodeno_t, MDSInternalContextBase::vec > cap_reconnect_waiters;
int cap_imports_num_opening;
set<CInode*> rejoin_undef_inodes;
vector<CInode*> rejoin_recover_q, rejoin_check_q;
list<SimpleLock*> rejoin_eval_locks;
- list<MDSInternalContextBase*> rejoin_waiters;
+ MDSInternalContextBase::vec rejoin_waiters;
void rejoin_walk(CDir *dir, MMDSCacheRejoin *rejoin);
void handle_cache_rejoin(MMDSCacheRejoin *m);
private:
bool opening_root, open;
- list<MDSInternalContextBase*> waiting_for_open;
+ MDSInternalContextBase::vec waiting_for_open;
public:
void init_layouts();
version_t tid;
int64_t pool;
int last_err;
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
open_ino_info_t() : checking(MDS_RANK_NONE), auth_hint(MDS_RANK_NONE),
check_peers(true), fetch_backtrace(true), discover(false),
want_replica(false), want_xlocked(false), tid(0), pool(-1),
void replicate_inode(CInode *in, mds_rank_t to, bufferlist& bl,
uint64_t features);
- CDir* add_replica_dir(bufferlist::const_iterator& p, CInode *diri, mds_rank_t from, list<MDSInternalContextBase*>& finished);
- CDentry *add_replica_dentry(bufferlist::const_iterator& p, CDir *dir, list<MDSInternalContextBase*>& finished);
- CInode *add_replica_inode(bufferlist::const_iterator& p, CDentry *dn, list<MDSInternalContextBase*>& finished);
+ CDir* add_replica_dir(bufferlist::const_iterator& p, CInode *diri, mds_rank_t from, MDSInternalContextBase::vec& finished);
+ CDentry *add_replica_dentry(bufferlist::const_iterator& p, CDir *dir, MDSInternalContextBase::vec& finished);
+ CInode *add_replica_inode(bufferlist::const_iterator& p, CDentry *dn, MDSInternalContextBase::vec& finished);
void replicate_stray(CDentry *straydn, mds_rank_t who, bufferlist& bl);
CDentry *add_replica_stray(bufferlist &bl, mds_rank_t from);
int bits;
bool committed;
LogSegment *ls;
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
list<frag_t> old_frags;
bufferlist rollback;
ufragment() : bits(0), committed(false), ls(NULL) {}
map<dirfrag_t,fragment_info_t> fragments;
void adjust_dir_fragments(CInode *diri, frag_t basefrag, int bits,
- list<CDir*>& frags, list<MDSInternalContextBase*>& waiters, bool replay);
+ list<CDir*>& frags, MDSInternalContextBase::vec& waiters, bool replay);
void adjust_dir_fragments(CInode *diri,
list<CDir*>& srcfrags,
frag_t basefrag, int bits,
list<CDir*>& resultfrags,
- list<MDSInternalContextBase*>& waiters,
+ MDSInternalContextBase::vec& waiters,
bool replay);
CDir *force_dir_fragment(CInode *diri, frag_t fg, bool replay=true);
void get_force_dirfrag_bound_set(vector<dirfrag_t>& dfs, set<CDir*>& bounds);
expired_events += ls->num_events;
// Trigger all waiters
- for (std::list<MDSInternalContextBase*>::iterator i = ls->expiry_waiters.begin();
- i != ls->expiry_waiters.end(); ++i) {
- (*i)->complete(0);
- }
- ls->expiry_waiters.clear();
+ finish_contexts(g_ceph_context, ls->expiry_waiters);
logger->inc(l_mdl_evex, ls->num_events);
logger->inc(l_mdl_segex);
#include "include/types.h"
#include "include/Context.h"
+#include "MDSContext.h"
#include "common/Thread.h"
#include "common/Cond.h"
friend class ReplayThread;
friend class C_MDL_Replay;
- list<MDSInternalContextBase*> waitfor_replay;
+ MDSInternalContextBase::vec waitfor_replay;
void _replay(); // old way
void _replay_thread(); // new way
uint64_t MDSCacheObject::last_wait_seq = 0;
void MDSCacheObject::finish_waiting(uint64_t mask, int result) {
- std::list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
take_waiting(mask, finished);
finish_contexts(g_ceph_context, finished, result);
}
#include "include/xlist.h"
#include "mdstypes.h"
+#include "MDSContext.h"
#define MDS_REF_SET // define me for improved debug output, sanity checking
//#define MDS_AUTHPIN_SET // define me for debugging auth pin leaks
// << dendl;
}
- virtual void take_waiting(uint64_t mask, std::list<MDSInternalContextBase*>& ls) {
+ virtual void take_waiting(uint64_t mask, MDSInternalContextBase::vec& ls) {
if (waiting.empty()) return;
// process ordered waiters in the same order that they were added.
#include "common/Continuation.h"
#include "mds/Mutation.h"
#include "mds/Server.h"
+
+#include "MDSContext.h"
class MDSContinuation : public Continuation {
protected:
while (!finished_queue.empty()) {
dout(7) << "mds has " << finished_queue.size() << " queued contexts" << dendl;
dout(10) << finished_queue << dendl;
- list<MDSInternalContextBase*> ls;
+ decltype(finished_queue) ls;
ls.swap(finished_queue);
- while (!ls.empty()) {
- dout(10) << " finish " << ls.front() << dendl;
- ls.front()->complete(0);
- ls.pop_front();
-
+ for (auto& c : ls) {
+ dout(10) << " finish " << c << dendl;
+ c->complete(0);
heartbeat_reset();
}
}
return false;
}
queue_waiter(replay_queue.front());
- replay_queue.pop_front();
+ replay_queue.pop();
return true;
}
}
{
- map<epoch_t,list<MDSInternalContextBase*> >::iterator p = waiting_for_mdsmap.begin();
+ map<epoch_t,MDSInternalContextBase::vec >::iterator p = waiting_for_mdsmap.begin();
while (p != waiting_for_mdsmap.end() && p->first <= mdsmap->get_epoch()) {
- list<MDSInternalContextBase*> ls;
+ MDSInternalContextBase::vec ls;
ls.swap(p->second);
waiting_for_mdsmap.erase(p++);
finish_contexts(g_ceph_context, ls);
#include "SessionMap.h"
#include "MDCache.h"
#include "MDLog.h"
+#include "MDSContext.h"
#include "PurgeQueue.h"
#include "osdc/Journaler.h"
} progress_thread;
list<Message*> waiting_for_nolaggy;
- list<MDSInternalContextBase*> finished_queue;
+ MDSInternalContextBase::vec finished_queue;
// Dispatch, retry, queues
int dispatch_depth;
void inc_dispatch_depth() { ++dispatch_depth; }
ceph_tid_t last_tid; // for mds-initiated requests (e.g. stray rename)
- list<MDSInternalContextBase*> waiting_for_active, waiting_for_replay, waiting_for_reconnect, waiting_for_resolve;
- list<MDSInternalContextBase*> waiting_for_any_client_connection;
- list<MDSInternalContextBase*> replay_queue;
- map<mds_rank_t, list<MDSInternalContextBase*> > waiting_for_active_peer;
- map<epoch_t, list<MDSInternalContextBase*> > waiting_for_mdsmap;
+ MDSInternalContextBase::vec waiting_for_active, waiting_for_replay, waiting_for_reconnect, waiting_for_resolve;
+ MDSInternalContextBase::vec waiting_for_any_client_connection;
+ MDSInternalContextBase::que replay_queue;
+ map<mds_rank_t, MDSInternalContextBase::vec > waiting_for_active_peer;
+ map<epoch_t, MDSInternalContextBase::vec > waiting_for_mdsmap;
epoch_t osd_epoch_barrier;
finished_queue.push_back(c);
progress_thread.signal();
}
- void queue_waiters(std::list<MDSInternalContextBase*>& ls) {
- finished_queue.splice( finished_queue.end(), ls );
+ void queue_waiters(MDSInternalContextBase::vec& ls) {
+ MDSInternalContextBase::vec v;
+ v.swap(ls);
+ finished_queue.insert(finished_queue.end(), v.begin(), v.end());
progress_thread.signal();
}
waiting_for_mdsmap[e].push_back(c);
}
void enqueue_replay(MDSInternalContextBase *c) {
- replay_queue.push_back(c);
+ replay_queue.push(c);
}
bool queue_one_replay();
dout(10) << "save_2 v " << v << dendl;
committed_version = v;
- list<MDSInternalContextBase*> ls;
+ MDSInternalContextBase::vec ls;
while (!waitfor_save.empty()) {
- if (waitfor_save.begin()->first > v) break;
- ls.splice(ls.end(), waitfor_save.begin()->second);
- waitfor_save.erase(waitfor_save.begin());
+ auto it = waitfor_save.begin();
+ if (it->first > v) break;
+ auto& v = it->second;
+ ls.insert(ls.end(), v.begin(), v.end());
+ waitfor_save.erase(it);
}
- finish_contexts(g_ceph_context, ls,0);
+ finish_contexts(g_ceph_context, ls, 0);
}
#include "mds_table_types.h"
#include "include/buffer_fwd.h"
+#include "MDSContext.h"
+
class MDSRank;
-class Context;
-class MDSInternalContextBase;
class MDSTable {
public:
version_t version, committing_version, committed_version, projected_version;
- map<version_t, list<MDSInternalContextBase*> > waitfor_save;
+ map<version_t, MDSInternalContextBase::vec > waitfor_save;
public:
MDSTable(MDSRank *m, const char *n, bool is_per_mds) :
// pending commits
map<version_t, LogSegment*> pending_commit;
- map<version_t, list<MDSInternalContextBase*> > ack_waiters;
+ map<version_t, MDSInternalContextBase::vec > ack_waiters;
void handle_reply(class MMDSTableQuery *m);
void _logged_ack(version_t tid);
#define CEPH_MDSTABLESERVER_H
#include "MDSTable.h"
+#include "MDSContext.h"
class MMDSTableRequest;
void Migrator::finish_export_inode(CInode *in, mds_rank_t peer,
map<client_t,Capability::Import>& peer_imported,
- list<MDSInternalContextBase*>& finished)
+ MDSInternalContextBase::vec& finished)
{
dout(12) << "finish_export_inode " << *in << dendl;
void Migrator::finish_export_dir(CDir *dir, mds_rank_t peer,
map<inodeno_t,map<client_t,Capability::Import> >& peer_imported,
- list<MDSInternalContextBase*>& finished, int *num_dentries)
+ MDSInternalContextBase::vec& finished, int *num_dentries)
{
dout(10) << "finish_export_dir " << *dir << dendl;
// finish export (adjust local cache state)
int num_dentries = 0;
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
finish_export_dir(dir, it->second.peer,
it->second.peer_imported, finished, &num_dentries);
CDir *dir;
CInode *diri;
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
// assimilate root dir.
map<dirfrag_t,import_state_t>::iterator it = import_state.find(m->get_dirfrag());
cache->adjust_subtree_auth(dir, stat.peer);
- C_ContextsBase<MDSInternalContextBase, MDSInternalContextGather> *fin = new C_ContextsBase<MDSInternalContextBase, MDSInternalContextGather>(g_ceph_context);
+ auto fin = new C_ContextsBase<MDSInternalContextBase, MDSInternalContextGather, MDSInternalContextBase::vec>(g_ceph_context);
if (!dir->get_inode()->is_auth() &&
!dir->get_inode()->has_subtree_root_dirfrag(mds->get_nodeid())) {
dir->get_inode()->clear_scatter_dirty();
// take all waiters on this dir
// NOTE: a pass of imported data is guaranteed to get all of my waiters because
// a replica's presense in my cache implies/forces it's presense in authority's.
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
dir->take_waiting(CDir::WAIT_ANY_MASK, waiters);
- for (list<MDSInternalContextBase*>::iterator it = waiters.begin();
+ for (MDSInternalContextBase::vec::iterator it = waiters.begin();
it != waiters.end();
++it)
import_root->add_waiter(CDir::WAIT_UNFREEZE, *it); // UNFREEZE will get kicked both on success or failure
#include "include/types.h"
+#include "MDSContext.h"
+
#include <map>
#include <list>
#include <set>
map<client_t,client_metadata_t>& exported_client_metadata_map);
void finish_export_inode(CInode *in, mds_rank_t target,
map<client_t,Capability::Import>& peer_imported,
- list<MDSInternalContextBase*>& finished);
+ MDSInternalContextBase::vec& finished);
void finish_export_inode_caps(CInode *in, mds_rank_t target,
map<client_t,Capability::Import>& peer_imported);
map<client_t,client_metadata_t>& exported_client_metadata_map);
void finish_export_dir(CDir *dir, mds_rank_t target,
map<inodeno_t,map<client_t,Capability::Import> >& peer_imported,
- list<MDSInternalContextBase*>& finished, int *num_dentries);
+ MDSInternalContextBase::vec& finished, int *num_dentries);
void clear_export_proxy_pins(CDir *dir);
#include "include/filepath.h"
#include "MDSCacheObject.h"
+#include "MDSContext.h"
#include "SimpleLock.h"
#include "Capability.h"
Context *slave_commit;
bufferlist rollback_bl;
- list<MDSInternalContextBase*> waiting_for_finish;
+ MDSInternalContextBase::vec waiting_for_finish;
// export & fragment
CDir* export_dir;
#include "mdstypes.h"
#include "Anchor.h"
+#include "MDSContext.h"
+
class CDir;
class CInode;
class MDSRank;
-class MDSInternalContextBase;
class OpenFileTable
{
std::vector<std::map<std::string, bufferlist> > loaded_journals;
map<inodeno_t, RecoveredAnchor> loaded_anchor_map;
set<dirfrag_t> loaded_dirfrags;
- list<MDSInternalContextBase*> waiting_for_load;
+ MDSInternalContextBase::vec waiting_for_load;
bool load_done = false;
void _reset_states() {
};
unsigned prefetch_state = 0;
unsigned num_opening_inodes = 0;
- list<MDSInternalContextBase*> waiting_for_prefetch;
+ MDSInternalContextBase::vec waiting_for_prefetch;
void _open_ino_finish(inodeno_t ino, int r);
void _prefetch_inodes();
void _prefetch_dirfrags();
#include "SimpleLock.h"
+#include "MDSContext.h"
+
class ScatterLock : public SimpleLock {
struct more_bits_t {
encode(s, bl);
}
- void decode_state_rejoin(bufferlist::const_iterator& p, list<MDSInternalContextBase*>& waiters, bool survivor) {
+ void decode_state_rejoin(bufferlist::const_iterator& p, MDSInternalContextBase::vec& waiters, bool survivor) {
SimpleLock::decode_state_rejoin(p, waiters, survivor);
if (is_flushing()) {
set_dirty();
void Server::finish_flush_session(Session *session, version_t seq)
{
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
session->finish_flush(seq, finished);
mds->queue_waiters(finished);
}
dout(10) << " state prior to lock change: " << *lock_state << dendl;
if (CEPH_LOCK_UNLOCK == set_lock.type) {
list<ceph_filelock> activated_locks;
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
if (lock_state->is_waiting(set_lock)) {
dout(10) << " unlock removing waiting lock " << set_lock << dendl;
lock_state->remove_waiting(set_lock);
CDentry::linkage_t *destdnl = destdn->get_linkage();
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
if (r == 0) {
// unfreeze+singleauth inode
// hmm, do i really need to delay this?
}
if (mdr) {
- list<MDSInternalContextBase*> finished;
+ MDSInternalContextBase::vec finished;
if (mdr->more()->is_ambiguous_auth) {
if (srcdn->is_auth())
mdr->more()->rename_inode->unfreeze_inode(finished);
#include "MDSRank.h"
#include "Mutation.h"
+#include "MDSContext.h"
class OSDMap;
class PerfCounters;
#include "CInode.h"
#include "Capability.h"
+#include "MDSContext.h"
#include "msg/Message.h"
enum {
// -- caps --
private:
version_t cap_push_seq; // cap push seq #
- map<version_t, list<MDSInternalContextBase*> > waitfor_flush; // flush session messages
+ map<version_t, MDSInternalContextBase::vec > waitfor_flush; // flush session messages
public:
xlist<Capability*> caps; // inodes with caps; front=most recently used
waitfor_flush[get_push_seq()].push_back(c);
return get_push_seq();
}
- void finish_flush(version_t seq, list<MDSInternalContextBase*>& ls) {
+ void finish_flush(version_t seq, MDSInternalContextBase::vec& ls) {
while (!waitfor_flush.empty()) {
- if (waitfor_flush.begin()->first > seq)
+ auto it = waitfor_flush.begin();
+ if (it->first > seq)
break;
- ls.splice(ls.end(), waitfor_flush.begin()->second);
- waitfor_flush.erase(waitfor_flush.begin());
+ auto& v = it->second;
+ ls.insert(ls.end(), v.begin(), v.end());
+ waitfor_flush.erase(it);
}
}
public:
map<int,xlist<Session*>* > by_state;
uint64_t set_state(Session *session, int state);
- map<version_t, list<MDSInternalContextBase*> > commit_waiters;
+ map<version_t, MDSInternalContextBase::vec > commit_waiters;
explicit SessionMap(MDSRank *m) : mds(m),
projected(0), committing(0), committed(0),
// -- loading, saving --
inodeno_t ino;
- list<MDSInternalContextBase*> waiting_for_load;
+ MDSInternalContextBase::vec waiting_for_load;
object_t get_object_name() const;
void finish_waiters(uint64_t mask, int r=0) {
parent->finish_waiting(mask << get_wait_shift(), r);
}
- void take_waiting(uint64_t mask, list<MDSInternalContextBase*>& ls) {
+ void take_waiting(uint64_t mask, MDSInternalContextBase::vec& ls) {
parent->take_waiting(mask << get_wait_shift(), ls);
}
void add_waiter(uint64_t mask, MDSInternalContextBase *c) {
//assert(!is_stable() || gather_set.size() == 0); // gather should be empty in stable states.
return s;
}
- void set_state_rejoin(int s, list<MDSInternalContextBase*>& waiters, bool survivor) {
+ void set_state_rejoin(int s, MDSInternalContextBase::vec& waiters, bool survivor) {
assert(!get_parent()->is_auth());
// If lock in the replica object was not in SYNC state when auth mds of the object failed.
if (is_new)
state = s;
}
- void decode_state_rejoin(bufferlist::const_iterator& p, list<MDSInternalContextBase*>& waiters, bool survivor) {
+ void decode_state_rejoin(bufferlist::const_iterator& p, MDSInternalContextBase::vec& waiters, bool survivor) {
__s16 s;
using ceph::decode;
decode(s, p);
synced = true;
if (synced && !waiting_for_version.empty()) {
- std::list<MDSInternalContextBase*> finished;
- for (auto p = waiting_for_version.begin();
- p != waiting_for_version.end(); ) {
- if (p->first > cached_version)
+ MDSInternalContextBase::vec finished;
+ while (!waiting_for_version.empty()) {
+ auto it = waiting_for_version.begin();
+ if (it->first > cached_version)
break;
- finished.splice(finished.end(), p->second);
- waiting_for_version.erase(p++);
+ auto& v = it->second;
+ finished.insert(finished.end(), v.begin(), v.end());
+ waiting_for_version.erase(it);
}
if (!finished.empty())
mds->queue_waiters(finished);
#include "MDSTableClient.h"
#include "snap.h"
+#include "MDSContext.h"
-class MDSInternalContextBase;
class MDSRank;
class LogSegment;
set<version_t> committing_tids;
- map<version_t, std::list<MDSInternalContextBase*> > waiting_for_version;
+ map<version_t, MDSInternalContextBase::vec > waiting_for_version;
uint64_t sync_reqid;
bool synced;
#include "include/xlist.h"
#include "include/elist.h"
#include "common/snap_types.h"
-
-class MDSInternalContextBase;
+#include "MDSContext.h"
struct SnapRealm {
protected:
dout(10) << "EFragment.replay " << op_name(op) << " " << ino << " " << basefrag << " by " << bits << dendl;
list<CDir*> resultfrags;
- list<MDSInternalContextBase*> waiters;
+ MDSInternalContextBase::vec waiters;
list<frag_t> old_frags;
// in may be NULL if it wasn't in our cache yet. if it's a prepare