summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Lang <sam.lang@inktank.com>2013-02-12 16:33:58 -0600
committerSage Weil <sage@inktank.com>2013-02-12 14:44:24 -0800
commit78ff229afae8eecd69bfab40e20925b00888894a (patch)
tree2228c2e1bb64a5b4762a7e7d4954d0bc6465bc13
parentd8c6b08e8e85f10069f379362b0afc2238e4c650 (diff)
downloadceph-78ff229afae8eecd69bfab40e20925b00888894a.tar.gz
mds: Setting pool on a file requires latest osdmap
If we create a file, then create a pool, then try to set the pool on the file with the vxattr, no mds operation triggers a request for the latest osdmap, so we get back EINVAL. So if we fail to find the pool initially, fall back to requesting a new osdmap and trying the vxattr again. We don't wait for a new map if we don't get anything newer than what we already have. Signed-off-by: Sam Lang <sam.lang@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/mds/MDS.cc4
-rw-r--r--src/mds/MDS.h2
-rw-r--r--src/mds/Mutation.h6
-rw-r--r--src/mds/Server.cc24
4 files changed, 35 insertions, 1 deletions
diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc
index 0a3480ebced..e59f5955916 100644
--- a/src/mds/MDS.cc
+++ b/src/mds/MDS.cc
@@ -690,6 +690,10 @@ void MDS::handle_mds_beacon(MMDSBeacon *m)
m->put();
}
+void MDS::request_osdmap(Context *c) {
+ objecter->wait_for_new_map(c, osdmap->get_epoch());
+}
+
/* This function DOES put the passed message before returning*/
void MDS::handle_command(MMonCommand *m)
{
diff --git a/src/mds/MDS.h b/src/mds/MDS.h
index f61ad8ddac5..50555e831d9 100644
--- a/src/mds/MDS.h
+++ b/src/mds/MDS.h
@@ -394,6 +394,8 @@ class MDS : public Dispatcher {
void beacon_send();
void handle_mds_beacon(MMDSBeacon *m);
+ void request_osdmap(Context *c);
+
// messages
bool _dispatch(Message *m);
diff --git a/src/mds/Mutation.h b/src/mds/Mutation.h
index 8866f6850c6..313edef30d8 100644
--- a/src/mds/Mutation.h
+++ b/src/mds/Mutation.h
@@ -191,6 +191,9 @@ struct MDRequest : public Mutation {
// indicates how may retries of request have been made
int retry;
+ // indicator for vxattr osdmap update
+ bool waited_for_osdmap;
+
// break rarely-used fields into a separately allocated structure
// to save memory for most ops
struct More {
@@ -245,6 +248,7 @@ struct MDRequest : public Mutation {
slave_request(0),
internal_op(-1),
retry(0),
+ waited_for_osdmap(false),
_more(0) {
in[0] = in[1] = 0;
}
@@ -257,6 +261,7 @@ struct MDRequest : public Mutation {
slave_request(0),
internal_op(-1),
retry(0),
+ waited_for_osdmap(false),
_more(0) {
in[0] = in[1] = 0;
}
@@ -269,6 +274,7 @@ struct MDRequest : public Mutation {
slave_request(0),
internal_op(-1),
retry(0),
+ waited_for_osdmap(false),
_more(0) {
in[0] = in[1] = 0;
}
diff --git a/src/mds/Server.cc b/src/mds/Server.cc
index 92f5bf64268..54585128eda 100644
--- a/src/mds/Server.cc
+++ b/src/mds/Server.cc
@@ -3523,7 +3523,7 @@ int Server::parse_layout_vxattr(string name, string value, ceph_file_layout *lay
int64_t pool = mds->osdmap->lookup_pg_pool_name(value);
if (pool < 0) {
dout(10) << " unknown pool " << value << dendl;
- return -EINVAL;
+ return -ENOENT;
}
layout->fl_pg_pool = pool;
}
@@ -3581,6 +3581,17 @@ void Server::handle_set_vxattr(MDRequest *mdr, CInode *cur,
rest = name.substr(name.find("layout"));
int r = parse_layout_vxattr(rest, value, &dlayout->layout);
if (r < 0) {
+ if (r == -ENOENT) {
+ if (!mdr->waited_for_osdmap) {
+ // send request to get latest map, but don't wait if
+ // we don't get anything newer than what we have
+ mdr->waited_for_osdmap = true;
+ mds->request_osdmap(
+ new C_MDS_RetryRequest(mdcache, mdr));
+ return;
+ }
+ r = -EINVAL;
+ }
reply_request(mdr, r);
return;
}
@@ -3600,6 +3611,17 @@ void Server::handle_set_vxattr(MDRequest *mdr, CInode *cur,
rest = name.substr(name.find("layout"));
int r = parse_layout_vxattr(rest, value, &layout);
if (r < 0) {
+ if (r == -ENOENT) {
+ if (!mdr->waited_for_osdmap) {
+ // send request to get latest map, but don't wait if
+ // we don't get anything newer than what we have
+ mdr->waited_for_osdmap = true;
+ mds->request_osdmap(
+ new C_MDS_RetryRequest(mdcache, mdr));
+ return;
+ }
+ r = -EINVAL;
+ }
reply_request(mdr, r);
return;
}