SnapRealmInfo info;
::decode(info, p);
if (first_realm == 0)
- first_realm = info.ino;
- SnapRealm *realm = get_snap_realm(info.ino);
+ first_realm = info.ino();
+ SnapRealm *realm = get_snap_realm(info.ino());
- if (info.seq > realm->seq) {
- dout(10) << "update_snap_trace " << *realm << " seq " << info.seq << " > " << realm->seq
+ if (info.seq() > realm->seq) {
+ dout(10) << "update_snap_trace " << *realm << " seq " << info.seq() << " > " << realm->seq
<< dendl;
if (flush) {
}
// _always_ verify parent
- bool invalidate = adjust_realm_parent(realm, info.parent);
+ bool invalidate = adjust_realm_parent(realm, info.parent());
- if (info.seq > realm->seq) {
+ if (info.seq() > realm->seq) {
// update
- realm->created = info.created;
- realm->parent = info.parent;
- realm->parent_since = info.parent_since;
+ realm->created = info.created();
+ realm->parent = info.parent();
+ realm->parent_since = info.parent_since();
realm->prior_parent_snaps = info.prior_parent_snaps;
realm->my_snaps = info.my_snaps;
- realm->seq = info.seq;
+ realm->seq = info.seq();
invalidate = true;
}
if (invalidate) {
dout(15) << "update_snap_trace " << *realm << " self|parent updated" << dendl;
dout(15) << " snapc " << realm->get_snap_context() << dendl;
} else {
- dout(10) << "update_snap_trace " << *realm << " seq " << info.seq
+ dout(10) << "update_snap_trace " << *realm << " seq " << info.seq()
<< " <= " << realm->seq << " and same parent, SKIPPING" << dendl;
}
list<Inode*> to_move;
SnapRealm *realm = 0;
- if (m->op == CEPH_SNAP_OP_SPLIT) {
- assert(m->split);
+ if (m->head.op == CEPH_SNAP_OP_SPLIT) {
+ assert(m->head.split);
SnapRealmInfo info;
bufferlist::iterator p = m->bl.begin();
::decode(info, p);
- assert(info.ino == m->split);
+ assert(info.ino() == m->head.split);
// flush, then move, ino's.
- realm = get_snap_realm(info.ino);
+ realm = get_snap_realm(info.ino());
dout(10) << " splitting off " << *realm << dendl;
for (vector<inodeno_t>::iterator p = m->split_inos.begin();
p != m->split_inos.end();
Inode *in = inode_map[vino];
if (!in->snaprealm || in->snaprealm == realm)
continue;
- if (in->snaprealm->created > info.created) {
+ if (in->snaprealm->created > info.created()) {
dout(10) << " NOT moving " << *in << " from _newer_ realm "
<< *in->snaprealm << dendl;
continue;
}
}
- update_snap_trace(m->bl, m->op != CEPH_SNAP_OP_DESTROY);
+ update_snap_trace(m->bl, m->head.op != CEPH_SNAP_OP_DESTROY);
if (realm) {
for (list<Inode*>::iterator p = to_move.begin(); p != to_move.end(); p++) {
} __attribute__ ((packed));
/* followed by a __le32+string for dname */
+
/* client reconnect */
struct ceph_mds_cap_reconnect {
__le32 wanted;
}
}
-
-struct ceph_mds_snap {
- /* ... */
+struct ceph_mds_snap_head {
+ __le32 op;
+ __le64 split;
+ __le32 num_split_inos;
+ __le32 num_split_realms;
+ __le32 trace_len;
};
+/* followed by split inos, then split realms, then the trace blob */
+/*
+ * encode info about a snaprealm, as viewed by a client
+ */
+struct ceph_mds_snap_realm {
+ __le64 ino; /* ino */
+ __le64 created; /* snap: when created */
+ __le64 parent; /* ino: parent realm */
+ __le64 parent_since; /* snap: same parent since */
+ __le64 seq; /* snap: version */
+ __le32 num_snaps;
+ __le32 num_prior_parent_snaps;
+};
+/* followed by my snaps, then prior parent snaps */
/*
* osd map
decode(v[i], p);
}
+template<class T>
+inline void encode_nohead(const std::vector<T>& v, bufferlist& bl)
+{
+ for (typename std::vector<T>::const_iterator p = v.begin(); p != v.end(); ++p)
+ encode(*p, bl);
+}
+template<class T>
+inline void decode_nohead(int len, std::vector<T>& v, bufferlist::iterator& p)
+{
+ v.resize(len);
+ for (__u32 i=0; i<v.size(); i++)
+ decode(v[i], p);
+}
+
// map (pointers)
template<class T, class U>
inline void encode(const std::map<T,U*>& m, bufferlist& bl)
p.copy(len, s);
}
+inline void encode_nohead(const bufferlist& s, bufferlist& bl)
+{
+ bl.append(s);
+}
+inline void decode_nohead(int len, bufferlist& s, bufferlist::iterator& p)
+{
+ s.clear();
+ p.copy(len, s);
+}
+
#endif
WRITE_RAW_ENCODER(ceph_mds_request_head)
WRITE_RAW_ENCODER(ceph_mds_caps)
WRITE_RAW_ENCODER(ceph_mds_lease)
+WRITE_RAW_ENCODER(ceph_mds_snap_head)
+WRITE_RAW_ENCODER(ceph_mds_snap_realm)
WRITE_RAW_ENCODER(ceph_mds_reply_head)
WRITE_RAW_ENCODER(ceph_mds_reply_inode)
WRITE_RAW_ENCODER(ceph_mds_cap_reconnect)
WRITE_RAW_ENCODER(ceph_mds_snaprealm_reconnect)
WRITE_RAW_ENCODER(ceph_frag_tree_split)
WRITE_RAW_ENCODER(ceph_inopath_item)
-
WRITE_RAW_ENCODER(ceph_osd_request_head)
WRITE_RAW_ENCODER(ceph_osd_reply_head)
return out << s.val;
}
-#define MAXSNAP CEPH_MAXSNAP
-#define NOSNAP CEPH_NOSNAP
struct SnapRealmInfo {
- inodeno_t ino, parent;
- snapid_t created;
- snapid_t parent_since;
- vector<snapid_t> prior_parent_snaps; // before parent_since
+ mutable ceph_mds_snap_realm h;
vector<snapid_t> my_snaps;
- snapid_t seq;
+ vector<snapid_t> prior_parent_snaps; // before parent_since
+
+ SnapRealmInfo() {
+ memset(&h, 0, sizeof(h));
+ }
+ SnapRealmInfo(inodeno_t ino, snapid_t created, snapid_t seq, snapid_t current_parent_since) {
+ memset(&h, 0, sizeof(h));
+ h.ino = ino;
+ h.created = created;
+ h.seq = seq;
+ h.parent_since = current_parent_since;
+ }
+
+ inodeno_t ino() { return inodeno_t(h.ino); }
+ inodeno_t parent() { return inodeno_t(h.parent); }
+ snapid_t seq() { return snapid_t(h.seq); }
+ snapid_t parent_since() { return snapid_t(h.parent_since); }
+ snapid_t created() { return snapid_t(h.created); }
void encode(bufferlist& bl) const {
- ::encode(ino, bl);
- ::encode(parent, bl);
- ::encode(parent_since, bl);
- ::encode(prior_parent_snaps, bl);
- ::encode(my_snaps, bl);
- ::encode(seq, bl);
- };
+ h.num_snaps = my_snaps.size();
+ h.num_prior_parent_snaps = prior_parent_snaps.size();
+ ::encode(h, bl);
+ ::encode_nohead(my_snaps, bl);
+ ::encode_nohead(prior_parent_snaps, bl);
+ }
void decode(bufferlist::iterator& bl) {
- ::decode(ino, bl);
- ::decode(parent, bl);
- ::decode(parent_since, bl);
- ::decode(prior_parent_snaps, bl);
- ::decode(my_snaps, bl);
- ::decode(seq, bl);
+ ::decode(h, bl);
+ ::decode_nohead(h.num_snaps, my_snaps, bl);
+ ::decode_nohead(h.num_prior_parent_snaps, prior_parent_snaps, bl);
}
};
WRITE_CLASS_ENCODER(SnapRealmInfo)
MClientSnap *snap;
if (splits.count(client) == 0) {
splits[client] = snap = new MClientSnap(CEPH_SNAP_OP_SPLIT);
- snap->split = realm->inode->ino();
+ snap->head.split = realm->inode->ino();
realm->build_snap_trace(snap->bl);
for (set<SnapRealm*>::iterator p = realm->open_children.begin();
Session *session = mds->sessionmap.get_session(entity_name_t::CLIENT(p->first));
if (session) {
dout(10) << " client" << p->first
- << " split " << p->second->split
+ << " split " << p->second->head.split
<< " inos " << p->second->split_inos
<< dendl;
mds->send_message_client(p->second, session->inst);
p++) {
assert(!p->second.empty());
MClientSnap *update = updates[p->first] = new MClientSnap(CEPH_SNAP_OP_SPLIT);
- update->split = in->ino();
+ update->head.split = in->ino();
update->split_inos = split_inos;
update->split_realms = split_realms;
update->bl = snapbl;
void SnapRealm::build_snap_trace(bufferlist& snapbl)
{
- SnapRealmInfo info;
- info.ino = inode->ino();
- info.seq = seq;
- info.parent_since = current_parent_since;
+ SnapRealmInfo info(inode->ino(), created, seq, current_parent_since);
if (parent) {
- info.parent = parent->inode->ino();
+ info.h.parent = parent->inode->ino();
if (!past_parents.empty()) {
snapid_t last = past_parents.rbegin()->first;
set<snapid_t> past;
<< info.prior_parent_snaps << dendl;
}
} else
- info.parent = 0;
+ info.h.parent = 0;
info.my_snaps.reserve(snaps.size());
for (map<snapid_t,SnapInfo>::reverse_iterator p = snaps.rbegin();
#include "msg/Message.h"
struct MClientSnap : public Message {
- __u32 op;
+ ceph_mds_snap_head head;
bufferlist bl;
-
+
// (for split only)
- inodeno_t split;
vector<inodeno_t> split_inos;
vector<inodeno_t> split_realms;
-
+
MClientSnap(int o=0) :
- Message(CEPH_MSG_CLIENT_SNAP),
- op(o), split(0) {}
+ Message(CEPH_MSG_CLIENT_SNAP) {
+ memset(&head, 0, sizeof(head));
+ head.op = o;
+ }
const char *get_type_name() { return "client_snap"; }
void print(ostream& out) {
- out << "client_snap(" << ceph_snap_op_name(op);
- if (split)
- out << " split=" << split;
+ out << "client_snap(" << ceph_snap_op_name(head.op);
+ if (head.split)
+ out << " split=" << head.split;
out << ")";
}
void encode_payload() {
- ::encode(op, payload);
- ::encode(bl, payload);
- ::encode(split, payload);
- ::encode(split_inos, payload);
- ::encode(split_realms, payload);
+ head.num_split_inos = split_inos.size();
+ head.num_split_realms = split_realms.size();
+ head.trace_len = bl.length();
+ ::encode(head, payload);
+ ::encode_nohead(split_inos, payload);
+ ::encode_nohead(split_realms, payload);
+ ::encode_nohead(bl, payload);
}
void decode_payload() {
bufferlist::iterator p = payload.begin();
- ::decode(op, p);
- ::decode(bl, p);
- ::decode(split, p);
- ::decode(split_inos, p);
- ::decode(split_realms, p);
+ ::decode(head, p);
+ ::decode_nohead(head.num_split_inos, split_inos, p);
+ ::decode_nohead(head.num_split_realms, split_realms, p);
+ ::decode_nohead(head.trace_len, bl, p);
assert(p.end());
}