diff options
author | Sam Lang <sam.lang@inktank.com> | 2013-02-12 16:33:58 -0600 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-02-12 14:44:24 -0800 |
commit | 78ff229afae8eecd69bfab40e20925b00888894a (patch) | |
tree | 2228c2e1bb64a5b4762a7e7d4954d0bc6465bc13 | |
parent | d8c6b08e8e85f10069f379362b0afc2238e4c650 (diff) | |
download | ceph-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.cc | 4 | ||||
-rw-r--r-- | src/mds/MDS.h | 2 | ||||
-rw-r--r-- | src/mds/Mutation.h | 6 | ||||
-rw-r--r-- | src/mds/Server.cc | 24 |
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; } |