*
*/
-class InodeStat {
- public:
+struct DirStat {
+ // mds distribution hints
+ frag_t frag;
+ int auth;
+ set<int> dist;
+ bool is_rep;
+
+ DirStat() {}
+ DirStat(bufferlist::iterator& p) {
+ _decode(p);
+ }
+
+ void _decode(bufferlist::iterator& p) {
+ ::_decode_simple(frag, p);
+ ::_decode_simple(auth, p);
+ ::_decode_simple(dist, p);
+ ::_decode_simple(is_rep, p);
+ }
+
+ static void _encode(bufferlist& bl, CDir *dir, int whoami) {
+ frag_t frag = dir->get_frag();
+ int auth;
+ set<int> dist;
+ bool is_rep;
+
+ auth = dir->get_dir_auth().first;
+ if (dir->is_auth())
+ dir->get_dist_spec(dist, whoami);
+ is_rep = dir->is_rep();
+
+ ::_encode_simple(frag, bl);
+ ::_encode_simple(auth, bl);
+ ::_encode_simple(dist, bl);
+ ::_encode_simple(is_rep, bl);
+ }
+};
+
+struct InodeStat {
inode_t inode;
string symlink; // symlink content (if symlink)
fragtree_t dirfragtree;
uint32_t mask;
- // mds distribution hints
- map<frag_t,int> dirfrag_auth;
- map<frag_t,set<int> > dirfrag_dist;
- set<frag_t> dirfrag_rep;
-
public:
InodeStat() {}
InodeStat(bufferlist::iterator& p) {
void _decode(bufferlist::iterator &p) {
::_decode_simple(mask, p);
::_decode_simple(inode, p);
- ::_decode_simple(dirfrag_auth, p);
- ::_decode_simple(dirfrag_dist, p);
- ::_decode_simple(dirfrag_rep, p);
::_decode_simple(symlink, p);
dirfragtree._decode(p);
}
- static void _encode(bufferlist &bl, CInode *in, int whoami) {
+ static void _encode(bufferlist &bl, CInode *in) {
int mask = STAT_MASK_INO|STAT_MASK_TYPE|STAT_MASK_BASE;
// mask
::_encode_simple(mask, bl);
::_encode_simple(in->inode, bl);
-
- // dirfrag info
- map<frag_t,int> dirfrag_auth;
- map<frag_t,set<int> > dirfrag_dist;
- set<frag_t> dirfrag_rep;
-
- list<CDir*> ls;
- in->get_dirfrags(ls);
- for (list<CDir*>::iterator p = ls.begin();
- p != ls.end();
- ++p) {
- CDir *dir = *p;
- dirfrag_auth[dir->dirfrag().frag] = dir->get_dir_auth().first;
- if (dir->is_auth())
- dir->get_dist_spec(dirfrag_dist[dir->dirfrag().frag], whoami);
- if (dir->is_rep())
- dirfrag_rep.insert(dir->dirfrag().frag);
- }
-
- ::_encode_simple(dirfrag_auth, bl);
- ::_encode_simple(dirfrag_dist, bl);
- ::_encode_simple(dirfrag_rep, bl);
-
::_encode_simple(in->symlink, bl);
in->dirfragtree._encode(bl);
}
string path;
list<InodeStat*> trace_in;
+ list<DirStat*> trace_dir;
list<string> trace_dn;
bufferlist trace_bl;
+ DirStat *dir_dir;
list<InodeStat*> dir_in;
list<string> dir_dn;
bufferlist dir_bl;
void set_file_caps_seq(long s) { st.file_caps_seq = s; }
void set_file_data_version(uint64_t v) { st.file_data_version = v; }
- MClientReply() {};
+ MClientReply() : dir_dir(0) {};
MClientReply(MClientRequest *req, int result = 0) :
- Message(MSG_CLIENT_REPLY) {
+ Message(MSG_CLIENT_REPLY), dir_dir(0) {
memset(&st, 0, sizeof(st));
this->st.tid = req->get_tid();
this->st.op = req->get_op();
}
void _decode_dir() {
bufferlist::iterator p = dir_bl.begin();
+ dir_dir = new DirStat(p);
while (!p.end()) {
string dn;
::_decode_simple(dn, p);
if (dir_in.empty() && dir_bl.length()) _decode_dir();
return dir_in;
}
- const list<string>& get_dir_dn() {
+ const list<string>& get_dir_dn() {
if (dir_dn.empty() && dir_bl.length()) _decode_dir();
return dir_dn;
}
+ const DirStat* get_dir_dir() {
+ return dir_dir;
+ }
// trace
void set_trace_dist(CInode *in, int whoami) {
- // inode, dentry, ..., inode
+ // inode, dentry, dir, ..., inode
while (in) {
- InodeStat::_encode(trace_bl, in, whoami);
- if (in->get_parent_dn())
- ::_encode_simple(in->get_parent_dn()->get_name(), trace_bl);
- in = in->get_parent_inode();
+ InodeStat::_encode(trace_bl, in);
+ CDentry *dn = in->get_parent_dn();
+ if (!dn) break;
+ ::_encode_simple(in->get_parent_dn()->get_name(), trace_bl);
+ DirStat::_encode(trace_bl, dn->get_dir(), whoami);
+ in = dn->get_dir()->get_inode();
}
}
void _decode_trace() {
bufferlist::iterator p = trace_bl.begin();
while (!p.end()) {
+ // inode
trace_in.push_front(new InodeStat(p));
if (!p.end()) {
+ // dentry
string ref_dn;
::_decode_simple(ref_dn, p);
trace_dn.push_front(ref_dn);
+
+ // dir
+ trace_dir.push_front(new DirStat(p));
}
}
}
if (trace_in.empty() && trace_bl.length()) _decode_trace();
return trace_in;
}
- const list<string>& get_trace_dn() {
+ const list<DirStat*>& get_trace_dir() {
+ if (trace_in.empty() && trace_bl.length()) _decode_trace();
+ return trace_dir;
+ }
+ const list<string>& get_trace_dn() {
if (trace_in.empty() && trace_bl.length()) _decode_trace();
return trace_dn;
}