} else {
splits[client] = snap = new MClientSnap(CEPH_SNAP_OP_SPLIT);
snap->head.split = realm->inode->ino();
- realm->build_snap_trace(snap->bl);
+ snap->bl = realm->get_snap_trace();
for (const auto& child : realm->open_children)
snap->split_realms.push_back(child->inode->ino());
vector<inodeno_t> split_inos;
vector<inodeno_t> split_realms;
- bufferlist snapbl;
for (elist<CInode*>::iterator p = realm->inodes_with_caps.begin(member_offset(CInode, item_caps));
!p.end();
p != realm->open_children.end();
++p)
split_realms.push_back((*p)->inode->ino());
- parent_realm->build_snap_trace(snapbl);
for (auto p : realm->client_caps) {
assert(!p.second->empty());
update->head.split = parent_realm->inode->ino();
update->split_inos = split_inos;
update->split_realms = split_realms;
- update->bl = snapbl;
+ update->bl = parent_realm->get_snap_trace();
}
}
}
cap->pending(), cap->wanted(), 0,
cap->get_mseq(), mds->get_osd_epoch_barrier());
in->encode_cap_message(reap, cap);
- realm->build_snap_trace(reap->snapbl);
+ reap->snapbl = realm->get_snap_trace();
reap->set_cap_peer(p_cap_id, p_seq, p_mseq, peer, p_flags);
mds->send_message_client_counted(reap, session);
} else {
dout(10) << "finish_snaprealm_reconnect client." << client << " has old seq " << seq << " < "
<< realm->get_newest_seq() << " on " << *realm << dendl;
MClientSnap *snap = new MClientSnap(CEPH_SNAP_OP_UPDATE);
- realm->build_snap_trace(snap->bl);
+ snap->bl = realm->get_snap_trace();
for (const auto& child : realm->open_children)
snap->split_realms.push_back(child->inode->ino());
} else {
vector<inodeno_t> split_inos;
vector<inodeno_t> split_realms;
- bufferlist snapbl;
if (notify_clients) {
assert(in->snaprealm->have_past_parents_open());
++p)
split_realms.push_back((*p)->inode->ino());
}
- in->snaprealm->build_snap_trace(snapbl);
}
set<SnapRealm*> past_children;
update->head.split = in->ino();
update->split_inos = split_inos;
update->split_realms = split_realms;
- update->bl = snapbl;
+ update->bl = in->snaprealm->get_snap_trace();
updates[p->first] = update;
}
}
* get list of snaps for this realm. we must include parents' snaps
* for the intervals during which they were our parent.
*/
-void SnapRealm::build_snap_set(set<snapid_t> &s,
- snapid_t& max_seq, snapid_t& max_last_created, snapid_t& max_last_destroyed,
- snapid_t first, snapid_t last) const
+void SnapRealm::build_snap_set() const
{
- dout(10) << "build_snap_set [" << first << "," << last << "] on " << *this << dendl;
+ dout(10) << "build_snap_set on " << *this << dendl;
- if (srnode.seq > max_seq)
- max_seq = srnode.seq;
- if (srnode.last_created > max_last_created)
- max_last_created = srnode.last_created;
+ cached_seq = srnode.seq;
+ cached_last_created = srnode.last_created;
+ cached_snaps.clear();
- // include my snaps within interval [first,last]
- for (auto p = srnode.snaps.lower_bound(first); // first element >= first
- p != srnode.snaps.end() && p->first <= last;
- ++p)
- s.insert(p->first);
+ // include my snaps
+ for (const auto& p : srnode.snaps)
+ cached_snaps.insert(p.first);
if (!srnode.past_parent_snaps.empty()) {
- set<snapid_t> snaps;
- for (auto p = srnode.past_parent_snaps.lower_bound(first); // first element >= first
- p != srnode.past_parent_snaps.end() && *p <= last;
- ++p) {
- snaps.insert(*p);
+ set<snapid_t> snaps = mdcache->mds->snapclient->filter(srnode.past_parent_snaps);
+ if (!snaps.empty()) {
+ snapid_t last = *snaps.rbegin();
+ cached_seq = std::max(cached_seq, last);
+ cached_last_created = std::max(cached_last_created, last);
}
- snaps = mdcache->mds->snapclient->filter(snaps);
- s.insert(snaps.begin(), snaps.end());
+ cached_snaps.insert(snaps.begin(), snaps.end());
} else {
- // include snaps for parents during intervals that intersect [first,last]
- for (map<snapid_t, snaplink_t>::const_iterator p = srnode.past_parents.lower_bound(first);
- p != srnode.past_parents.end() && p->first >= first && p->second.first <= last;
- ++p) {
- const CInode *oldparent = mdcache->get_inode(p->second.ino);
+ // include snaps for parents
+ for (const auto& p : srnode.past_parents) {
+ const CInode *oldparent = mdcache->get_inode(p.second.ino);
assert(oldparent); // call open_parents first!
assert(oldparent->snaprealm);
- oldparent->snaprealm->build_snap_set(s, max_seq, max_last_created, max_last_destroyed,
- std::max(first, p->second.first),
- std::min(last, p->first));
+
+ const set<snapid_t>& snaps = oldparent->snaprealm->get_snaps();
+ snapid_t last = 0;
+ for (auto q = snaps.lower_bound(p.second.first);
+ q != snaps.end() && *q <= p.first;
+ q++) {
+ cached_snaps.insert(*q);
+ last = *q;
+ }
+ cached_seq = std::max(cached_seq, last);
+ cached_last_created = std::max(cached_last_created, last);
}
}
- if (srnode.current_parent_since <= last && parent)
- parent->build_snap_set(s, max_seq, max_last_created, max_last_destroyed,
- std::max(first, srnode.current_parent_since), last);
+ snapid_t parent_seq = parent ? parent->get_newest_seq() : snapid_t(0);
+ if (parent_seq >= srnode.current_parent_since) {
+ auto& snaps = parent->get_snaps();
+ auto p = snaps.lower_bound(srnode.current_parent_since);
+ cached_snaps.insert(p, snaps.end());
+ cached_seq = std::max(cached_seq, parent_seq);
+ cached_last_created = std::max(cached_last_created, parent->get_last_created());
+ }
}
-
void SnapRealm::check_cache() const
{
assert(have_past_parents_open());
cached_last_destroyed == last_destroyed)
return;
- cached_snaps.clear();
cached_snap_context.clear();
- cached_last_created = srnode.last_created;
- cached_seq = srnode.seq;
cached_last_destroyed = last_destroyed;
- build_snap_set(cached_snaps, cached_seq, cached_last_created, cached_last_destroyed,
- 0, CEPH_NOSNAP);
+ build_snap_set();
- cached_snap_trace.clear();
- build_snap_trace(cached_snap_trace);
+ build_snap_trace();
dout(10) << "check_cache rebuilt " << cached_snaps
<< " seq " << srnode.seq
inode->close_snaprealm();
}
-const bufferlist& SnapRealm::get_snap_trace()
+const bufferlist& SnapRealm::get_snap_trace() const
{
check_cache();
return cached_snap_trace;
}
-void SnapRealm::build_snap_trace(bufferlist& snapbl) const
+void SnapRealm::build_snap_trace() const
{
- SnapRealmInfo info(inode->ino(), srnode.created, srnode.seq, srnode.current_parent_since);
+ cached_snap_trace.clear();
+ SnapRealmInfo info(inode->ino(), srnode.created, srnode.seq, srnode.current_parent_since);
if (parent) {
info.h.parent = parent->inode->ino();
if (!srnode.past_parent_snaps.empty()) {
past = mdcache->mds->snapclient->filter(srnode.past_parent_snaps);
} else if (!srnode.past_parents.empty()) {
- snapid_t last = srnode.past_parents.rbegin()->first;
- snapid_t max_seq, max_last_created, max_last_destroyed;
- build_snap_set(past, max_seq, max_last_created, max_last_destroyed, 0, last);
+ const set<snapid_t>& snaps = get_snaps();
+ for (const auto& p : srnode.past_parents) {
+ for (auto q = snaps.lower_bound(p.second.first);
+ q != snaps.end() && *q <= p.first;
+ q++) {
+ if (srnode.snaps.count(*q))
+ continue;
+ past.insert(*q);
+ }
+ }
}
if (!past.empty()) {
info.my_snaps.push_back(p->first);
dout(10) << "build_snap_trace my_snaps " << info.my_snaps << dendl;
- encode(info, snapbl);
+ encode(info, cached_snap_trace);
if (parent)
- parent->build_snap_trace(snapbl);
+ cached_snap_trace.append(parent->get_snap_trace());
}
void SnapRealm::prune_past_parents()