From 880ffe9de56ae39d310f5a2063e63c0f8f0edcec Mon Sep 17 00:00:00 2001 From: John Spray Date: Thu, 6 Aug 2015 13:10:08 +0100 Subject: [PATCH] mds: fix setting whole layout in one vxattr Previously we were validating the layout after setting each field, so even when setting multiple fields in one go (to something valid) the intermediate states could be invalid and cause a bogus EINVAL. For example try setting object_size and stripe_unit both to 2M in one go. Signed-off-by: John Spray --- src/mds/Server.cc | 9 ++++++--- src/mds/Server.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 5fbb5969109..8f4ca72c8c6 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -3865,7 +3865,7 @@ struct keys_and_values }; int Server::parse_layout_vxattr(string name, string value, const OSDMap *osdmap, - ceph_file_layout *layout) + ceph_file_layout *layout, bool validate) { dout(20) << "parse_layout_vxattr name " << name << " value '" << value << "'" << dendl; try { @@ -3882,7 +3882,10 @@ int Server::parse_layout_vxattr(string name, string value, const OSDMap *osdmap, if (begin != end) return -EINVAL; for (map::iterator q = m.begin(); q != m.end(); ++q) { - int r = parse_layout_vxattr(string("layout.") + q->first, q->second, osdmap, layout); + // Skip validation on each attr, we do it once at the end (avoid + // rejecting intermediate states if the overall result is ok) + int r = parse_layout_vxattr(string("layout.") + q->first, q->second, + osdmap, layout, false); if (r < 0) return r; } @@ -3912,7 +3915,7 @@ int Server::parse_layout_vxattr(string name, string value, const OSDMap *osdmap, return -EINVAL; } - if (!ceph_file_layout_is_valid(layout)) { + if (validate && !ceph_file_layout_is_valid(layout)) { dout(10) << "bad layout" << dendl; return -EINVAL; } diff --git a/src/mds/Server.h b/src/mds/Server.h index 3b575ea2985..4cd73d5c508 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -176,7 +176,7 @@ public: void handle_client_setdirlayout(MDRequestRef& mdr); int parse_layout_vxattr(string name, string value, const OSDMap *osdmap, - ceph_file_layout *layout); + ceph_file_layout *layout, bool validate=true); int parse_quota_vxattr(string name, string value, quota_info_t *quota); void handle_set_vxattr(MDRequestRef& mdr, CInode *cur, ceph_file_layout *dir_layout, -- 2.47.3