From dc399ed231d9f3e048f514fcc72a1c74c8c0ea1a Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 25 May 2018 10:47:12 +0800 Subject: [PATCH] mds: add magic to header of open file table Fixes: http://tracker.ceph.com/issues/24240 Signed-off-by: "Yan, Zheng" (cherry picked from commit c60d55d19276c5c65c18bebbfd5939bb8c53f57c) Conflicts: src/mds/OpenFileTable.cc: Resolved in _load_finish --- src/mds/OpenFileTable.cc | 46 ++++++++++++++++++++++++++++++++++------ src/mds/OpenFileTable.h | 3 +++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/mds/OpenFileTable.cc b/src/mds/OpenFileTable.cc index 0e30e975cf5e0..2e3e2faa590c5 100644 --- a/src/mds/OpenFileTable.cc +++ b/src/mds/OpenFileTable.cc @@ -195,9 +195,13 @@ object_t OpenFileTable::get_object_name(unsigned idx) const void OpenFileTable::_encode_header(bufferlist &bl, int j_state) { + std::string_view magic = CEPH_FS_ONDISK_MAGIC; + encode(magic, bl); + ENCODE_START(1, 1, bl); encode(omap_version, bl); encode(omap_num_objs, bl); encode((__u8)j_state, bl); + ENCODE_FINISH(bl); } class C_IO_OFT_Save : public MDSIOContextBase { @@ -292,7 +296,6 @@ void OpenFileTable::commit(MDSInternalContextBase *c, uint64_t log_seq, int op_p SnapContext snapc; object_locator_t oloc(mds->mdsmap->get_metadata_pool()); - const unsigned max_items_per_obj = 1024 * 1024; const unsigned max_write_size = mds->mdcache->max_dir_commit_size; struct omap_update_ctl { @@ -456,11 +459,12 @@ void OpenFileTable::commit(MDSInternalContextBase *c, uint64_t log_seq, int op_p assert(it.second == DIRTY_NEW); // find omap object to store the key for (unsigned i = first_free_idx; i < omap_num_objs; i++) { - if (omap_num_items[i] < max_items_per_obj) + if (omap_num_items[i] < MAX_ITEMS_PER_OBJ) omap_idx = i; } if (omap_idx < 0) { ++omap_num_objs; + assert(omap_num_objs <= MAX_OBJECTS); omap_num_items.resize(omap_num_objs); omap_updates.resize(omap_num_objs); omap_updates.back().clear = true; @@ -476,7 +480,7 @@ void OpenFileTable::commit(MDSInternalContextBase *c, uint64_t log_seq, int op_p unsigned& count = omap_num_items.at(omap_idx); assert(count > 0); --count; - if ((unsigned)omap_idx < first_free_idx && count < max_items_per_obj) + if ((unsigned)omap_idx < first_free_idx && count < MAX_ITEMS_PER_OBJ) first_free_idx = omap_idx; } auto& ctl = omap_updates.at(omap_idx); @@ -713,12 +717,42 @@ void OpenFileTable::_load_finish(int op_r, int header_r, int values_r, try { if (first) { bufferlist::iterator p = header_bl.begin(); + + string magic; version_t version; unsigned num_objs; __u8 jstate; - decode(version, p); - decode(num_objs, p); - decode(jstate, p); + + if (header_bl.length() == 13) { + // obsolete format. + decode(version, p); + decode(num_objs, p); + decode(jstate, p); + } else { + decode(magic, p); + if (magic != CEPH_FS_ONDISK_MAGIC) { + std::ostringstream oss; + oss << "invalid magic '" << magic << "'"; + throw buffer::malformed_input(oss.str()); + } + + DECODE_START(1, p); + decode(version, p); + decode(num_objs, p); + decode(jstate, p); + DECODE_FINISH(p); + } + + if (num_objs > MAX_OBJECTS) { + std::ostringstream oss; + oss << "invalid object count '" << num_objs << "'"; + throw buffer::malformed_input(oss.str()); + } + if (jstate > JOURNAL_FINISH) { + std::ostringstream oss; + oss << "invalid journal state '" << jstate << "'"; + throw buffer::malformed_input(oss.str()); + } if (version > omap_version) { omap_version = version; diff --git a/src/mds/OpenFileTable.h b/src/mds/OpenFileTable.h index db949d9f8882d..b9e7cfe86c0fb 100644 --- a/src/mds/OpenFileTable.h +++ b/src/mds/OpenFileTable.h @@ -67,6 +67,9 @@ protected: MDSRank *mds; version_t omap_version = 0; + + static const unsigned MAX_ITEMS_PER_OBJ = 1024 * 1024; + static const unsigned MAX_OBJECTS = 1024; // billion items at most unsigned omap_num_objs = 0; std::vector omap_num_items; -- 2.39.5