summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage.weil@dreamhost.com>2011-04-01 11:35:19 -0700
committerSage Weil <sage.weil@dreamhost.com>2011-04-01 11:35:19 -0700
commit0fb02b25daa04d590ad9d5bbc42525a1d5d35aed (patch)
tree8351f1f4443b81bf84dc1db72e6649b7d930ab33
parent1696388e7a74e83c3dd4f34e69b14f91573ab04b (diff)
parent06ed898ddd3bf3d34da0209c2c645c7efddd54dc (diff)
downloadceph-0fb02b25daa04d590ad9d5bbc42525a1d5d35aed.tar.gz
Merge branch 'mds_ino'
-rw-r--r--src/client/Client.cc18
-rw-r--r--src/client/Client.h1
-rw-r--r--src/client/SyntheticClient.cc20
-rw-r--r--src/client/SyntheticClient.h2
-rw-r--r--src/include/ceph_fs.h1
-rw-r--r--src/include/ceph_strings.cc1
-rw-r--r--src/mds/MDCache.cc11
-rw-r--r--src/mds/Server.cc145
-rw-r--r--src/mds/Server.h6
9 files changed, 180 insertions, 25 deletions
diff --git a/src/client/Client.cc b/src/client/Client.cc
index d09f2d56cb4..ca6fdc11db6 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -4528,9 +4528,9 @@ int Client::lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name)
filepath path(ino);
req->set_filepath(path);
- uint32_t h = ceph_str_hash(0, name, strlen(name));
+ uint32_t h = ceph_str_hash(CEPH_STR_HASH_RJENKINS, name, strlen(name));
char f[30];
- sprintf(f, "%d", h);
+ sprintf(f, "%u", h);
filepath path2(dirino);
path2.push_dentry(string(f));
req->set_filepath2(path2);
@@ -4540,6 +4540,20 @@ int Client::lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name)
return r;
}
+int Client::lookup_ino(inodeno_t ino)
+{
+ Mutex::Locker lock(client_lock);
+ dout(3) << "lookup_ino enter(" << ino << ") = " << dendl;
+
+ MetaRequest *req = new MetaRequest(CEPH_MDS_OP_LOOKUPINO);
+ filepath path(ino);
+ req->set_filepath(path);
+
+ int r = make_request(req, -1, -1, NULL, rand() % mdsmap->get_num_mds());
+ dout(3) << "lookup_ino exit(" << ino << ") = " << r << dendl;
+ return r;
+}
+
Fh *Client::_create_fh(Inode *in, int flags, int cmode)
{
// yay
diff --git a/src/client/Client.h b/src/client/Client.h
index 900d21cbc16..e31237e2e3e 100644
--- a/src/client/Client.h
+++ b/src/client/Client.h
@@ -1283,6 +1283,7 @@ public:
int mknod(const char *path, mode_t mode, dev_t rdev=0);
int open(const char *path, int flags, mode_t mode=0);
int lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name);
+ int lookup_ino(inodeno_t ino);
int close(int fd);
loff_t lseek(int fd, loff_t offset, int whence);
int read(int fd, char *buf, loff_t size, loff_t offset=-1);
diff --git a/src/client/SyntheticClient.cc b/src/client/SyntheticClient.cc
index e96560232ca..4cd14b41e0e 100644
--- a/src/client/SyntheticClient.cc
+++ b/src/client/SyntheticClient.cc
@@ -243,6 +243,9 @@ void parse_syn_options(vector<const char*>& args)
syn_sargs.push_back(args[++i]);
syn_sargs.push_back(args[++i]);
syn_sargs.push_back(args[++i]);
+ } else if (strcmp(args[i], "lookupino") == 0) {
+ syn_modes.push_back(SYNCLIENT_MODE_LOOKUPINO);
+ syn_sargs.push_back(args[++i]);
} else if (strcmp(args[i], "chunkfile") == 0) {
syn_modes.push_back(SYNCLIENT_MODE_CHUNK);
@@ -881,6 +884,16 @@ int SyntheticClient::run()
}
}
break;
+ case SYNCLIENT_MODE_LOOKUPINO:
+ {
+ inodeno_t ino;
+ string iname = get_sarg(0);
+ sscanf(iname.c_str(), "%llx", (long long unsigned*)&ino.val);
+ if (run_me()) {
+ lookup_ino(ino);
+ }
+ }
+ break;
case SYNCLIENT_MODE_MKSNAP:
{
@@ -3341,6 +3354,13 @@ int SyntheticClient::lookup_hash(inodeno_t ino, inodeno_t dirino, const char *na
return r;
}
+int SyntheticClient::lookup_ino(inodeno_t ino)
+{
+ int r = client->lookup_ino(ino);
+ dout(0) << "lookup_ino(" << ino << ") = " << r << dendl;
+ return r;
+}
+
int SyntheticClient::chunk_file(string &filename)
{
int fd = client->open(filename.c_str(), O_RDONLY);
diff --git a/src/client/SyntheticClient.h b/src/client/SyntheticClient.h
index 475ea7c43be..e3fcc136beb 100644
--- a/src/client/SyntheticClient.h
+++ b/src/client/SyntheticClient.h
@@ -74,6 +74,7 @@
#define SYNCLIENT_MODE_DUMP 63
#define SYNCLIENT_MODE_LOOKUPHASH 70
+#define SYNCLIENT_MODE_LOOKUPINO 71
#define SYNCLIENT_MODE_TRUNCATE 200
@@ -263,6 +264,7 @@ class SyntheticClient {
void import_find(const char *basedir, const char *find, bool writedata);
int lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name);
+ int lookup_ino(inodeno_t ino);
int chunk_file(string &filename);
diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h
index 68cb70aa0e5..3718bb421f1 100644
--- a/src/include/ceph_fs.h
+++ b/src/include/ceph_fs.h
@@ -321,6 +321,7 @@ enum {
CEPH_MDS_OP_GETATTR = 0x00101,
CEPH_MDS_OP_LOOKUPHASH = 0x00102,
CEPH_MDS_OP_LOOKUPPARENT = 0x00103,
+ CEPH_MDS_OP_LOOKUPINO = 0x00104,
CEPH_MDS_OP_SETXATTR = 0x01105,
CEPH_MDS_OP_RMXATTR = 0x01106,
diff --git a/src/include/ceph_strings.cc b/src/include/ceph_strings.cc
index f5fe1257b1e..ecc7ac03e8a 100644
--- a/src/include/ceph_strings.cc
+++ b/src/include/ceph_strings.cc
@@ -124,6 +124,7 @@ const char *ceph_mds_op_name(int op)
case CEPH_MDS_OP_LOOKUP: return "lookup";
case CEPH_MDS_OP_LOOKUPHASH: return "lookuphash";
case CEPH_MDS_OP_LOOKUPPARENT: return "lookupparent";
+ case CEPH_MDS_OP_LOOKUPINO: return "lookupino";
case CEPH_MDS_OP_GETATTR: return "getattr";
case CEPH_MDS_OP_SETXATTR: return "setxattr";
case CEPH_MDS_OP_SETATTR: return "setattr";
diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc
index 2d596768a07..0bae0eb8758 100644
--- a/src/mds/MDCache.cc
+++ b/src/mds/MDCache.cc
@@ -6884,6 +6884,7 @@ void MDCache::find_ino_peers(inodeno_t ino, Context *c, int hint)
fip.tid = tid;
fip.fin = c;
fip.hint = hint;
+ fip.checked.insert(mds->whoami);
_do_find_ino_peer(fip);
}
@@ -6904,7 +6905,8 @@ void MDCache::_do_find_ino_peer(find_ino_peer_info_t& fip)
fip.hint = -1;
} else {
for (set<int>::iterator p = active.begin(); p != active.end(); p++)
- if (fip.checked.count(*p) == 0) {
+ if (*p != mds->whoami &&
+ fip.checked.count(*p) == 0) {
m = *p;
break;
}
@@ -7036,7 +7038,10 @@ void MDCache::_find_ino_dir(inodeno_t ino, Context *fin, bufferlist& bl, int r)
filepath path(s.c_str());
vector<CDentry*> trace;
- Context *c = new C_MDS_FindInoDir(this, ino, fin);
+ dout(10) << "_find_ino_dir traversing to path " << path << dendl;
+
+ C_MDS_FindInoDir *c = new C_MDS_FindInoDir(this, ino, fin);
+ c->bl = bl;
r = path_traverse(NULL, NULL, c, path, &trace, NULL, MDS_TRAVERSE_DISCOVER);
if (r > 0)
return;
@@ -8099,7 +8104,7 @@ void MDCache::discover_path(CDir *base,
d.frag = base->get_frag();
d.snap = snap;
d.want_path = want_path;
- d.want_base_dir = true;
+ d.want_base_dir = false;
d.want_xlocked = want_xlocked;
_send_discover(d);
}
diff --git a/src/mds/Server.cc b/src/mds/Server.cc
index 58be7106f6f..9d042324de4 100644
--- a/src/mds/Server.cc
+++ b/src/mds/Server.cc
@@ -1125,6 +1125,10 @@ void Server::dispatch_client_request(MDRequest *mdr)
handle_client_lookup_hash(mdr);
break;
+ case CEPH_MDS_OP_LOOKUPINO:
+ handle_client_lookup_ino(mdr);
+ break;
+
// inodes ops.
case CEPH_MDS_OP_LOOKUP:
case CEPH_MDS_OP_LOOKUPSNAP:
@@ -2042,39 +2046,59 @@ void Server::handle_client_lookup_parent(MDRequest *mdr)
reply_request(mdr, 0, in, dn); // reply
}
-struct C_MDS_LookupHash : public Context {
+struct C_MDS_LookupHash2 : public Context {
Server *server;
MDRequest *mdr;
- C_MDS_LookupHash(Server *s, MDRequest *r) : server(s), mdr(r) {}
+ C_MDS_LookupHash2(Server *s, MDRequest *r) : server(s), mdr(r) {}
void finish(int r) {
- server->_lookup_hash(mdr, r);
+ server->_lookup_hash_2(mdr, r);
}
};
/* This function DOES clean up the mdr before returning*/
+/*
+ * filepath: ino
+ * filepath2: dirino/<hash as base-10 %d>
+ *
+ * This dirino+hash is optional.
+ */
void Server::handle_client_lookup_hash(MDRequest *mdr)
{
MClientRequest *req = mdr->client_request;
- CInode *in = mdcache->get_inode(req->get_filepath().get_ino());
- if (in && in->state_test(CInode::STATE_PURGING)) {
- reply_request(mdr, -ESTALE);
- return;
+ inodeno_t ino = req->get_filepath().get_ino();
+ inodeno_t dirino = req->get_filepath2().get_ino();
+
+ CInode *in = 0;
+
+ if (ino) {
+ in = mdcache->get_inode(ino);
+ if (in && in->state_test(CInode::STATE_PURGING)) {
+ reply_request(mdr, -ESTALE);
+ return;
+ }
+ if (!in && !dirino) {
+ dout(10) << " no dirino, looking up ino " << ino << " directly" << dendl;
+ _lookup_ino(mdr);
+ return;
+ }
}
if (!in) {
// try the directory
- CInode *diri = mdcache->get_inode(req->get_filepath2().get_ino());
+ CInode *diri = mdcache->get_inode(dirino);
if (!diri) {
- mdcache->find_ino_peers(req->get_filepath2().get_ino(),
- new C_MDS_LookupHash(this, mdr), -1);
+ mdcache->find_ino_peers(dirino,
+ new C_MDS_LookupHash2(this, mdr), -1);
return;
}
if (diri->state_test(CInode::STATE_PURGING)) {
reply_request(mdr, -ESTALE);
return;
}
+ dout(10) << " have diri " << *diri << dendl;
unsigned hash = atoi(req->get_filepath2()[0].c_str());
frag_t fg = diri->dirfragtree[hash];
+ dout(10) << " fg is " << fg << dendl;
CDir *dir = diri->get_dirfrag(fg);
if (!dir) {
if (!diri->is_auth()) {
@@ -2090,6 +2114,7 @@ void Server::handle_client_lookup_hash(MDRequest *mdr)
dir = diri->get_or_open_dirfrag(mdcache, fg);
}
assert(dir);
+ dout(10) << " have dir " << *dir << dendl;
if (!dir->is_auth()) {
if (dir->is_ambiguous_auth()) {
// wait
@@ -2101,7 +2126,7 @@ void Server::handle_client_lookup_hash(MDRequest *mdr)
return;
}
if (!dir->is_complete()) {
- dir->fetch(0, new C_MDS_RetryRequest(mdcache, mdr));
+ dir->fetch(new C_MDS_RetryRequest(mdcache, mdr));
return;
}
reply_request(mdr, -ESTALE);
@@ -2113,30 +2138,112 @@ void Server::handle_client_lookup_hash(MDRequest *mdr)
reply_request(mdr, reply, in, in->get_parent_dn());
}
-struct C_MDS_LookupHash2 : public Context {
+struct C_MDS_LookupHash3 : public Context {
Server *server;
MDRequest *mdr;
- C_MDS_LookupHash2(Server *s, MDRequest *r) : server(s), mdr(r) {}
+ C_MDS_LookupHash3(Server *s, MDRequest *r) : server(s), mdr(r) {}
void finish(int r) {
- server->_lookup_hash_2(mdr, r);
+ server->_lookup_hash_3(mdr, r);
}
};
-void Server::_lookup_hash(MDRequest *mdr, int r)
+void Server::_lookup_hash_2(MDRequest *mdr, int r)
{
- dout(10) << "_lookup_hash " << mdr << " r=" << r << dendl;
+ inodeno_t dirino = mdr->client_request->get_filepath2().get_ino();
+ dout(10) << "_lookup_hash_2 " << mdr << " checked peers for dirino " << dirino << " and got r=" << r << dendl;
if (r == 0) {
dispatch_client_request(mdr);
return;
}
// okay fine, try the dir object then!
- mdcache->find_ino_dir(mdr->client_request->get_filepath2().get_ino(), new C_MDS_LookupHash2(this, mdr));
+ mdcache->find_ino_dir(dirino, new C_MDS_LookupHash3(this, mdr));
}
-void Server::_lookup_hash_2(MDRequest *mdr, int r)
+void Server::_lookup_hash_3(MDRequest *mdr, int r)
+{
+ inodeno_t dirino = mdr->client_request->get_filepath2().get_ino();
+ dout(10) << "_lookup_hash_3 " << mdr << " checked dir object for dirino " << dirino
+ << " and got r=" << r << dendl;
+ if (r == 0) {
+ dispatch_client_request(mdr);
+ return;
+ }
+ dout(10) << "_lookup_hash_3 " << mdr << " trying the ino itself" << dendl;
+ _lookup_ino(mdr);
+}
+
+/***************/
+
+struct C_MDS_LookupIno2 : public Context {
+ Server *server;
+ MDRequest *mdr;
+ C_MDS_LookupIno2(Server *s, MDRequest *r) : server(s), mdr(r) {}
+ void finish(int r) {
+ server->_lookup_ino_2(mdr, r);
+ }
+};
+
+/* This function DOES clean up the mdr before returning*/
+/*
+ * filepath: ino
+ */
+void Server::handle_client_lookup_ino(MDRequest *mdr)
+{
+ MClientRequest *req = mdr->client_request;
+
+ inodeno_t ino = req->get_filepath().get_ino();
+ CInode *in = mdcache->get_inode(ino);
+ if (in && in->state_test(CInode::STATE_PURGING)) {
+ reply_request(mdr, -ESTALE);
+ return;
+ }
+ if (!in) {
+ _lookup_ino(mdr);
+ return;
+ }
+
+ dout(10) << "reply to lookup_ino " << *in << dendl;
+ MClientReply *reply = new MClientReply(req, 0);
+ reply_request(mdr, reply, in, in->get_parent_dn());
+}
+
+void Server::_lookup_ino(MDRequest *mdr)
+{
+ inodeno_t ino = mdr->client_request->get_filepath().get_ino();
+ dout(10) << "_lookup_ino " << mdr << " checking peers for ino " << ino << dendl;
+ mdcache->find_ino_peers(ino,
+ new C_MDS_LookupIno2(this, mdr), -1);
+}
+
+struct C_MDS_LookupIno3 : public Context {
+ Server *server;
+ MDRequest *mdr;
+ C_MDS_LookupIno3(Server *s, MDRequest *r) : server(s), mdr(r) {}
+ void finish(int r) {
+ server->_lookup_ino_3(mdr, r);
+ }
+};
+
+void Server::_lookup_ino_2(MDRequest *mdr, int r)
+{
+ inodeno_t ino = mdr->client_request->get_filepath().get_ino();
+ dout(10) << "_lookup_ino_2 " << mdr << " checked peers for ino " << ino
+ << " and got r=" << r << dendl;
+ if (r == 0) {
+ dispatch_client_request(mdr);
+ return;
+ }
+
+ // okay fine, maybe it's a directory though...
+ mdcache->find_ino_dir(ino, new C_MDS_LookupIno3(this, mdr));
+}
+
+void Server::_lookup_ino_3(MDRequest *mdr, int r)
{
- dout(10) << "_lookup_hash_2 " << mdr << " r=" << r << dendl;
+ inodeno_t ino = mdr->client_request->get_filepath().get_ino();
+ dout(10) << "_lookup_ino_3 " << mdr << " checked dir obj for ino " << ino
+ << " and got r=" << r << dendl;
if (r == 0) {
dispatch_client_request(mdr);
return;
diff --git a/src/mds/Server.h b/src/mds/Server.h
index d35813458d3..bbe8c05d0bb 100644
--- a/src/mds/Server.h
+++ b/src/mds/Server.h
@@ -137,8 +137,12 @@ public:
void handle_client_stat(MDRequest *mdr);
void handle_client_lookup_parent(MDRequest *mdr);
void handle_client_lookup_hash(MDRequest *mdr);
- void _lookup_hash(MDRequest *mdr, int r);
void _lookup_hash_2(MDRequest *mdr, int r);
+ void _lookup_hash_3(MDRequest *mdr, int r);
+ void handle_client_lookup_ino(MDRequest *mdr);
+ void _lookup_ino(MDRequest *mdr);
+ void _lookup_ino_2(MDRequest *mdr, int r);
+ void _lookup_ino_3(MDRequest *mdr, int r);
void handle_client_readdir(MDRequest *mdr);
void handle_client_file_setlock(MDRequest *mdr);
void handle_client_file_readlock(MDRequest *mdr);