Merge PR #22289 into master

* refs/pull/22289/head:
	mds: put Capability in map container

Reviewed-by: Patrick Donnelly <pdonnell@redhat.com>
This commit is contained in:
Patrick Donnelly 2018-06-15 07:01:57 -07:00
commit c7951d8f36
No known key found for this signature in database
GPG Key ID: 3A2A7E25BEA8AADB
6 changed files with 101 additions and 123 deletions

View File

@ -210,16 +210,16 @@ ostream& operator<<(ostream& out, const CInode& in)
if (!in.get_client_caps().empty()) {
out << " caps={";
for (map<client_t,Capability*>::const_iterator it = in.get_client_caps().begin();
it != in.get_client_caps().end();
++it) {
if (it != in.get_client_caps().begin()) out << ",";
out << it->first << "="
<< ccap_string(it->second->pending());
if (it->second->issued() != it->second->pending())
out << "/" << ccap_string(it->second->issued());
out << "/" << ccap_string(it->second->wanted())
<< "@" << it->second->get_last_sent();
bool first = true;
for (const auto &p : in.get_client_caps()) {
if (!first) out << ",";
out << p.first << "="
<< ccap_string(p.second.pending());
if (p.second.issued() != p.second.pending())
out << "/" << ccap_string(p.second.issued());
out << "/" << ccap_string(p.second.wanted())
<< "@" << p.second.get_last_sent();
first = false;
}
out << "}";
if (in.get_loner() >= 0 || in.get_wanted_loner() >= 0) {
@ -2836,17 +2836,16 @@ client_t CInode::calc_ideal_loner()
int n = 0;
client_t loner = -1;
for (map<client_t,Capability*>::iterator it = client_caps.begin();
it != client_caps.end();
++it)
if (!it->second->is_stale() &&
((it->second->wanted() & (CEPH_CAP_ANY_WR|CEPH_CAP_FILE_WR|CEPH_CAP_FILE_RD)) ||
for (const auto &p : client_caps) {
if (!p.second.is_stale() &&
((p.second.wanted() & (CEPH_CAP_ANY_WR|CEPH_CAP_FILE_WR|CEPH_CAP_FILE_RD)) ||
(inode.is_dir() && !has_subtree_root_dirfrag()))) {
if (n)
return -1;
n++;
loner = it->first;
loner = p.first;
}
}
return loner;
}
@ -2998,26 +2997,27 @@ Capability *CInode::add_client_cap(client_t client, Session *session, SnapRealm
if (parent)
parent->dir->adjust_num_inodes_with_caps(1);
}
Capability *cap = new Capability(this, ++mdcache->last_cap_id, client);
assert(client_caps.count(client) == 0);
client_caps[client] = cap;
uint64_t cap_id = ++mdcache->last_cap_id;
auto ret = client_caps.emplace(std::piecewise_construct, std::forward_as_tuple(client),
std::forward_as_tuple(this, cap_id, client));
assert(ret.second == true);
Capability *cap = &ret.first->second;
session->add_cap(cap);
if (session->is_stale())
cap->mark_stale();
cap->client_follows = first-1;
containing_realm->add_cap(client, cap);
return cap;
}
void CInode::remove_client_cap(client_t client)
{
assert(client_caps.count(client) == 1);
Capability *cap = client_caps[client];
auto it = client_caps.find(client);
assert(it != client_caps.end());
Capability *cap = &it->second;
cap->item_session_caps.remove_myself();
cap->item_revoking_caps.remove_myself();
@ -3030,8 +3030,7 @@ void CInode::remove_client_cap(client_t client)
if (cap->wanted())
adjust_num_caps_wanted(-1);
delete cap;
client_caps.erase(client);
client_caps.erase(it);
if (client_caps.empty()) {
dout(10) << __func__ << " last cap, leaving realm " << *containing_realm << dendl;
put(PIN_CAPS);
@ -3056,11 +3055,9 @@ void CInode::move_to_realm(SnapRealm *realm)
{
dout(10) << __func__ << " joining realm " << *realm
<< ", leaving realm " << *containing_realm << dendl;
for (map<client_t,Capability*>::iterator q = client_caps.begin();
q != client_caps.end();
++q) {
containing_realm->remove_cap(q->first, q->second);
realm->add_cap(q->first, q->second);
for (auto& p : client_caps) {
containing_realm->remove_cap(p.first, &p.second);
realm->add_cap(p.first, &p.second);
}
item_caps.remove_myself();
realm->inodes_with_caps.push_back(&item_caps);
@ -3098,10 +3095,8 @@ void CInode::clear_client_caps_after_export()
void CInode::export_client_caps(map<client_t,Capability::Export>& cl)
{
for (map<client_t,Capability*>::iterator it = client_caps.begin();
it != client_caps.end();
++it) {
cl[it->first] = it->second->make_export();
for (const auto &p : client_caps) {
cl[p.first] = p.second.make_export();
}
}
@ -3190,16 +3185,14 @@ int CInode::get_caps_issued(int *ploner, int *pother, int *pxlocker,
loner_cap = -1;
}
for (map<client_t,Capability*>::const_iterator it = client_caps.begin();
it != client_caps.end();
++it) {
int i = it->second->issued();
for (const auto &p : client_caps) {
int i = p.second.issued();
c |= i;
if (it->first == loner_cap)
if (p.first == loner_cap)
loner |= i;
else
other |= i;
xlocker |= get_xlocker_mask(it->first) & i;
xlocker |= get_xlocker_mask(p.first) & i;
}
if (ploner) *ploner = (loner >> shift) & mask;
if (pother) *pother = (other >> shift) & mask;
@ -3209,11 +3202,10 @@ int CInode::get_caps_issued(int *ploner, int *pother, int *pxlocker,
bool CInode::is_any_caps_wanted() const
{
for (map<client_t,Capability*>::const_iterator it = client_caps.begin();
it != client_caps.end();
++it)
if (it->second->wanted())
for (const auto &p : client_caps) {
if (p.second.wanted())
return true;
}
return false;
}
@ -3221,13 +3213,11 @@ int CInode::get_caps_wanted(int *ploner, int *pother, int shift, int mask) const
{
int w = 0;
int loner = 0, other = 0;
for (map<client_t,Capability*>::const_iterator it = client_caps.begin();
it != client_caps.end();
++it) {
if (!it->second->is_stale()) {
int t = it->second->wanted();
for (const auto &p : client_caps) {
if (!p.second.is_stale()) {
int t = p.second.wanted();
w |= t;
if (it->first == loner_cap)
if (p.first == loner_cap)
loner |= t;
else
other |= t;
@ -4511,7 +4501,7 @@ void CInode::dump(Formatter *f, int flags) const
f->open_array_section("client_caps");
for (const auto &p : client_caps) {
auto &client = p.first;
auto &cap = p.second;
auto cap = &p.second;
f->open_object_section("client_cap");
f->dump_int("client_id", client.v);
f->dump_string("pending", ccap_string(cap->pending()));

View File

@ -581,8 +581,8 @@ public:
// -- distributed state --
protected:
// file capabilities
using cap_map = mempool::mds_co::map<client_t, Capability*>;
cap_map client_caps; // client -> caps
using mempool_cap_map = mempool::mds_co::map<client_t, Capability>;
mempool_cap_map client_caps; // client -> caps
mempool::mds_co::compact_map<int32_t, int32_t> mds_caps_wanted; // [auth] mds -> caps wanted
int replica_caps_wanted = 0; // [replica] what i've requested from auth
int num_caps_wanted = 0;
@ -975,7 +975,7 @@ public:
int count_nonstale_caps() {
int n = 0;
for (const auto &p : client_caps) {
if (!p.second->is_stale())
if (!p.second.is_stale())
n++;
}
return n;
@ -983,7 +983,7 @@ public:
bool multiple_nonstale_caps() {
int n = 0;
for (const auto &p : client_caps) {
if (!p.second->is_stale()) {
if (!p.second.is_stale()) {
if (n)
return true;
n++;
@ -999,17 +999,17 @@ public:
void set_mds_caps_wanted(mempool::mds_co::compact_map<int32_t,int32_t>& m);
void set_mds_caps_wanted(mds_rank_t mds, int32_t wanted);
const cap_map& get_client_caps() const { return client_caps; }
const mempool_cap_map& get_client_caps() const { return client_caps; }
Capability *get_client_cap(client_t client) {
auto client_caps_entry = client_caps.find(client);
if (client_caps_entry != client_caps.end())
return client_caps_entry->second;
return &client_caps_entry->second;
return 0;
}
int get_client_cap_pending(client_t client) const {
auto client_caps_entry = client_caps.find(client);
if (client_caps_entry != client_caps.end()) {
return client_caps_entry->second->pending();
return client_caps_entry->second.pending();
} else {
return 0;
}

View File

@ -135,9 +135,9 @@ public:
const Capability& operator=(const Capability& other) = delete;
int pending() { return _pending; }
int issued() { return _issued; }
bool is_null() { return !_pending && _revokes.empty(); }
int pending() const { return _pending; }
int issued() const { return _issued; }
bool is_null() const { return !_pending && _revokes.empty(); }
ceph_seq_t issue(unsigned c) {
if (_pending & ~c) {
@ -216,52 +216,52 @@ public:
}
}
}
ceph_seq_t get_mseq() { return mseq; }
ceph_seq_t get_mseq() const { return mseq; }
void inc_mseq() { mseq++; }
ceph_seq_t get_last_sent() { return last_sent; }
utime_t get_last_issue_stamp() { return last_issue_stamp; }
utime_t get_last_revoke_stamp() { return last_revoke_stamp; }
ceph_seq_t get_last_sent() const { return last_sent; }
utime_t get_last_issue_stamp() const { return last_issue_stamp; }
utime_t get_last_revoke_stamp() const { return last_revoke_stamp; }
void set_last_issue() { last_issue = last_sent; }
void set_last_issue_stamp(utime_t t) { last_issue_stamp = t; }
void set_last_revoke_stamp(utime_t t) { last_revoke_stamp = t; }
void reset_num_revoke_warnings() { num_revoke_warnings = 0; }
void inc_num_revoke_warnings() { ++num_revoke_warnings; }
unsigned get_num_revoke_warnings() { return num_revoke_warnings; }
unsigned get_num_revoke_warnings() const { return num_revoke_warnings; }
void set_cap_id(uint64_t i) { cap_id = i; }
uint64_t get_cap_id() { return cap_id; }
uint64_t get_cap_id() const { return cap_id; }
//ceph_seq_t get_last_issue() { return last_issue; }
bool is_suppress() { return suppress > 0; }
bool is_suppress() const { return suppress > 0; }
void inc_suppress() { suppress++; }
void dec_suppress() { suppress--; }
bool is_stale() { return state & STATE_STALE; }
bool is_stale() const { return state & STATE_STALE; }
void mark_stale() { state |= STATE_STALE; }
void clear_stale() { state &= ~STATE_STALE; }
bool is_new() { return state & STATE_NEW; }
bool is_new() const { return state & STATE_NEW; }
void mark_new() { state |= STATE_NEW; }
void clear_new() { state &= ~STATE_NEW; }
bool is_importing() { return state & STATE_IMPORTING; }
bool is_importing() const { return state & STATE_IMPORTING; }
void mark_importing() { state |= STATE_IMPORTING; }
void clear_importing() { state &= ~STATE_IMPORTING; }
bool need_snapflush() { return state & STATE_NEEDSNAPFLUSH; }
bool need_snapflush() const { return state & STATE_NEEDSNAPFLUSH; }
void mark_needsnapflush() { state |= STATE_NEEDSNAPFLUSH; }
void clear_needsnapflush() { state &= ~STATE_NEEDSNAPFLUSH; }
CInode *get_inode() { return inode; }
CInode *get_inode() const { return inode; }
client_t get_client() const { return client; }
// caps this client wants to hold
int wanted() { return _wanted; }
int wanted() const { return _wanted; }
void set_wanted(int w);
void inc_last_seq() { last_sent++; }
ceph_seq_t get_last_seq() { return last_sent; }
ceph_seq_t get_last_issue() { return last_issue; }
ceph_seq_t get_last_seq() const { return last_sent; }
ceph_seq_t get_last_issue() const { return last_issue; }
void reset_seq() {
last_sent = 0;
@ -269,7 +269,7 @@ public:
}
// -- exports --
Export make_export() {
Export make_export() const {
return Export(cap_id, _wanted, issued(), pending(), client_follows, last_sent, mseq+1, last_issue_stamp);
}
void merge(const Export& other, bool auth_cap) {

View File

@ -2005,13 +2005,13 @@ bool Locker::issue_caps(CInode *in, Capability *only_cap)
int nissued = 0;
// client caps
map<client_t, Capability*>::iterator it;
map<client_t, Capability>::iterator it;
if (only_cap)
it = in->client_caps.find(only_cap->get_client());
else
it = in->client_caps.begin();
for (; it != in->client_caps.end(); ++it) {
Capability *cap = it->second;
Capability *cap = &it->second;
if (cap->is_stale())
continue;
@ -2110,10 +2110,8 @@ void Locker::issue_truncate(CInode *in)
{
dout(7) << "issue_truncate on " << *in << dendl;
for (map<client_t, Capability*>::iterator it = in->client_caps.begin();
it != in->client_caps.end();
++it) {
Capability *cap = it->second;
for (auto &p : in->client_caps) {
Capability *cap = &p.second;
MClientCaps *m = new MClientCaps(CEPH_CAP_OP_TRUNC,
in->ino(),
in->find_snaprealm()->inode->ino(),
@ -2122,7 +2120,7 @@ void Locker::issue_truncate(CInode *in)
cap->get_mseq(),
mds->get_osd_epoch_barrier());
in->encode_cap_message(m, cap);
mds->send_message_client_counted(m, it->first);
mds->send_message_client_counted(m, p.first);
}
// should we increase max_size?
@ -2328,14 +2326,12 @@ void Locker::calc_new_client_ranges(CInode *in, uint64_t size,
// increase ranges as appropriate.
// shrink to 0 if no WR|BUFFER caps issued.
for (map<client_t,Capability*>::iterator p = in->client_caps.begin();
p != in->client_caps.end();
++p) {
if ((p->second->issued() | p->second->wanted()) & (CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER)) {
client_writeable_range_t& nr = (*new_ranges)[p->first];
for (const auto &p : in->get_client_caps()) {
if ((p.second.issued() | p.second.wanted()) & (CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER)) {
client_writeable_range_t& nr = (*new_ranges)[p.first];
nr.range.first = 0;
if (latest->client_ranges.count(p->first)) {
client_writeable_range_t& oldr = latest->client_ranges[p->first];
if (latest->client_ranges.count(p.first)) {
client_writeable_range_t& oldr = latest->client_ranges[p.first];
if (ms > oldr.range.last)
*max_increased = true;
nr.range.last = std::max(ms, oldr.range.last);
@ -2481,14 +2477,14 @@ void Locker::share_inode_max_size(CInode *in, Capability *only_cap)
* the cap later.
*/
dout(10) << "share_inode_max_size on " << *in << dendl;
map<client_t, Capability*>::iterator it;
map<client_t, Capability>::iterator it;
if (only_cap)
it = in->client_caps.find(only_cap->get_client());
else
it = in->client_caps.begin();
for (; it != in->client_caps.end(); ++it) {
const client_t client = it->first;
Capability *cap = it->second;
Capability *cap = &it->second;
if (cap->is_suppress())
continue;
if (cap->pending() & (CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER)) {

View File

@ -1559,7 +1559,7 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t last)
// clone caps?
for (auto &p : in->client_caps) {
client_t client = p.first;
Capability *cap = p.second;
Capability *cap = &p.second;
int issued = cap->need_snapflush() ? CEPH_CAP_ANY_WR : cap->issued();
if ((issued & CEPH_CAP_ANY_WR) &&
cap->client_follows < last) {
@ -2017,17 +2017,15 @@ void MDCache::broadcast_quota_to_client(CInode *in, client_t exclude_ct)
if (!in->get_projected_srnode())
mds->server->create_quota_realm(in);
for (map<client_t,Capability*>::iterator it = in->client_caps.begin();
it != in->client_caps.end();
++it) {
Session *session = mds->get_session(it->first);
for (auto &p : in->client_caps) {
Session *session = mds->get_session(p.first);
if (!session || !session->connection ||
!session->connection->has_feature(CEPH_FEATURE_MDS_QUOTA))
continue;
Capability *cap = it->second;
Capability *cap = &p.second;
if (exclude_ct >= 0 && exclude_ct != it->first)
if (exclude_ct >= 0 && exclude_ct != p.first)
goto update;
if (cap->last_rbytes == i->rstat.rbytes &&

View File

@ -1256,11 +1256,9 @@ void Migrator::check_export_size(CDir *dir, export_state_t& stat, set<client_t>&
}
}
}
for (map<client_t, Capability*>::iterator q = in->client_caps.begin();
q != in->client_caps.end();
++q) {
for (const auto &q : in->get_client_caps()) {
approx_size += cap_size;
client_set.insert(q->first);
client_set.insert(q.first);
}
}
@ -1288,10 +1286,9 @@ void Migrator::check_export_size(CDir *dir, export_state_t& stat, set<client_t>&
void Migrator::get_export_client_set(CInode *in, set<client_t>& client_set)
{
for (map<client_t, Capability*>::iterator q = in->client_caps.begin();
q != in->client_caps.end();
++q)
client_set.insert(q->first);
for (const auto &p : in->get_client_caps()) {
client_set.insert(p.first);
}
}
/* This function DOES put the passed message before returning*/
@ -1494,10 +1491,9 @@ void Migrator::encode_export_inode_caps(CInode *in, bool auth_cap, bufferlist& b
}
// make note of clients named by exported capabilities
for (map<client_t, Capability*>::iterator it = in->client_caps.begin();
it != in->client_caps.end();
++it)
exported_client_map[it->first] = mds->sessionmap.get_inst(entity_name_t::CLIENT(it->first.v));
for (const auto &p : in->get_client_caps()) {
exported_client_map[p.first] = mds->sessionmap.get_inst(entity_name_t::CLIENT(p.first.v));
}
}
void Migrator::finish_export_inode_caps(CInode *in, mds_rank_t peer,
@ -1509,20 +1505,18 @@ void Migrator::finish_export_inode_caps(CInode *in, mds_rank_t peer,
in->put(CInode::PIN_EXPORTINGCAPS);
// tell (all) clients about migrating caps..
for (map<client_t, Capability*>::iterator it = in->client_caps.begin();
it != in->client_caps.end();
++it) {
Capability *cap = it->second;
dout(7) << "finish_export_inode_caps telling client." << it->first
for (const auto &p : in->get_client_caps()) {
const Capability *cap = &p.second;
dout(7) << "finish_export_inode_caps telling client." << p.first
<< " exported caps on " << *in << dendl;
MClientCaps *m = new MClientCaps(CEPH_CAP_OP_EXPORT, in->ino(), 0,
cap->get_cap_id(), cap->get_mseq(), mds->get_osd_epoch_barrier());
map<client_t,Capability::Import>::iterator q = peer_imported.find(it->first);
map<client_t,Capability::Import>::iterator q = peer_imported.find(p.first);
assert(q != peer_imported.end());
m->set_cap_peer(q->second.cap_id, q->second.issue_seq, q->second.mseq,
(q->second.cap_id > 0 ? peer : -1), 0);
mds->send_message_client_counted(m, it->first);
mds->send_message_client_counted(m, p.first);
}
in->clear_client_caps_after_export();
mds->locker->eval(in, CEPH_CAP_LOCKS);
@ -1871,8 +1865,8 @@ void Migrator::export_reverse(CDir *dir, export_state_t& stat)
// revoke/resume stale caps
for (auto in : to_eval) {
bool need_issue = false;
for (auto& p : in->get_client_caps()) {
Capability *cap = p.second;
for (auto &p : in->client_caps) {
Capability *cap = &p.second;
if (cap->is_stale()) {
mds->locker->revoke_stale_caps(cap);
} else {