pass dir auth etc info to client separately from inode

git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1893 29311d96-e01e-0410-9327-a35deaab8ce9
This commit is contained in:
sageweil 2007-10-08 23:44:11 +00:00
parent ad05ba39e3
commit 7386f0e9c7
2 changed files with 68 additions and 44 deletions

View File

@ -1558,6 +1558,8 @@ void Server::handle_client_readdir(MDRequest *mdr)
// build dir contents
bufferlist dirbl;
DirStat::_encode(dirbl, dir, mds->get_nodeid());
int numfiles = 0;
for (CDir::map_t::iterator it = dir->begin();
it != dir->end();
@ -1596,7 +1598,7 @@ void Server::handle_client_readdir(MDRequest *mdr)
// add this dentry + inodeinfo
::_encode(it->first, dirbl);
InodeStat::_encode(dirbl, in, mds->get_nodeid());
InodeStat::_encode(dirbl, in);
// touch it
mdcache->lru.lru_touch(dn);

View File

@ -50,18 +50,49 @@ class CInode;
*
*/
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) {
@ -71,14 +102,11 @@ class InodeStat {
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
@ -88,29 +116,6 @@ class InodeStat {
::_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);
}
@ -132,9 +137,11 @@ class MClientReply : public Message {
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;
@ -158,9 +165,9 @@ class MClientReply : public Message {
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();
@ -208,6 +215,7 @@ class MClientReply : public Message {
}
void _decode_dir() {
bufferlist::iterator p = dir_bl.begin();
dir_dir = new DirStat(p);
while (!p.end()) {
string dn;
::_decode_simple(dn, p);
@ -220,30 +228,40 @@ class MClientReply : public Message {
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));
}
}
}
@ -252,7 +270,11 @@ class MClientReply : public Message {
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;
}