X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fmds%2FInoTable.cc;fp=src%2Fceph%2Fsrc%2Fmds%2FInoTable.cc;h=fc1faa876427cd430c4cb3212327d4ef25ae7e56;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/mds/InoTable.cc b/src/ceph/src/mds/InoTable.cc new file mode 100644 index 0000000..fc1faa8 --- /dev/null +++ b/src/ceph/src/mds/InoTable.cc @@ -0,0 +1,227 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "InoTable.h" +#include "MDSRank.h" + +#include "include/types.h" + +#include "common/config.h" + +#define dout_context g_ceph_context +#define dout_subsys ceph_subsys_mds +#undef dout_prefix +#define dout_prefix *_dout << "mds." << rank << "." << table_name << ": " + +void InoTable::reset_state() +{ + // use generic range. FIXME THIS IS CRAP + free.clear(); + //#ifdef __LP64__ + uint64_t start = (uint64_t)(rank+1) << 40; + uint64_t len = (uint64_t)1 << 40; + //#else + //# warning this looks like a 32-bit system, using small inode numbers. + // uint64_t start = (uint64_t)(mds->get_nodeid()+1) << 25; + // uint64_t end = ((uint64_t)(mds->get_nodeid()+2) << 25) - 1; + //#endif + free.insert(start, len); + + projected_free = free; +} + +inodeno_t InoTable::project_alloc_id(inodeno_t id) +{ + dout(10) << "project_alloc_id " << id << " to " << projected_free << "/" << free << dendl; + assert(is_active()); + if (!id) + id = projected_free.range_start(); + projected_free.erase(id); + ++projected_version; + return id; +} +void InoTable::apply_alloc_id(inodeno_t id) +{ + dout(10) << "apply_alloc_id " << id << " to " << projected_free << "/" << free << dendl; + free.erase(id); + ++version; +} + +void InoTable::project_alloc_ids(interval_set& ids, int want) +{ + assert(is_active()); + while (want > 0) { + inodeno_t start = projected_free.range_start(); + inodeno_t end = projected_free.end_after(start); + inodeno_t num = end - start; + if (num > (inodeno_t)want) + num = want; + projected_free.erase(start, num); + ids.insert(start, num); + want -= num; + } + dout(10) << "project_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl; + ++projected_version; +} +void InoTable::apply_alloc_ids(interval_set& ids) +{ + dout(10) << "apply_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl; + free.subtract(ids); + ++version; +} + + +void InoTable::project_release_ids(interval_set& ids) +{ + dout(10) << "project_release_ids " << ids << " to " << projected_free << "/" << free << dendl; + projected_free.insert(ids); + ++projected_version; +} +void InoTable::apply_release_ids(interval_set& ids) +{ + dout(10) << "apply_release_ids " << ids << " to " << projected_free << "/" << free << dendl; + free.insert(ids); + ++version; +} + + +// + +void InoTable::replay_alloc_id(inodeno_t id) +{ + assert(mds); // Only usable in online mode + + dout(10) << "replay_alloc_id " << id << dendl; + if (free.contains(id)) { + free.erase(id); + projected_free.erase(id); + } else { + mds->clog->error() << "journal replay alloc " << id + << " not in free " << free; + } + projected_version = ++version; +} +void InoTable::replay_alloc_ids(interval_set& ids) +{ + assert(mds); // Only usable in online mode + + dout(10) << "replay_alloc_ids " << ids << dendl; + interval_set is; + is.intersection_of(free, ids); + if (is == ids) { + free.subtract(ids); + projected_free.subtract(ids); + } else { + mds->clog->error() << "journal replay alloc " << ids << ", only " + << is << " is in free " << free; + free.subtract(is); + projected_free.subtract(is); + } + projected_version = ++version; +} +void InoTable::replay_release_ids(interval_set& ids) +{ + dout(10) << "replay_release_ids " << ids << dendl; + free.insert(ids); + projected_free.insert(ids); + projected_version = ++version; +} + + +void InoTable::replay_reset() +{ + dout(10) << "replay_reset " << free << dendl; + skip_inos(inodeno_t(10000000)); // a lot! + projected_free = free; + projected_version = ++version; +} + + +void InoTable::skip_inos(inodeno_t i) +{ + dout(10) << "skip_inos was " << free << dendl; + inodeno_t first = free.range_start(); + interval_set s; + s.insert(first, i); + s.intersection_of(free); + free.subtract(s); + projected_free = free; + projected_version = ++version; + dout(10) << "skip_inos now " << free << dendl; +} + +void InoTable::dump(Formatter *f) const +{ + f->open_object_section("inotable"); + + f->open_array_section("projected_free"); + for (interval_set::const_iterator i = projected_free.begin(); i != projected_free.end(); ++i) { + f->open_object_section("range"); + f->dump_int("start", (*i).first); + f->dump_int("len", (*i).second); + f->close_section(); + } + f->close_section(); + + f->open_array_section("free"); + for (interval_set::const_iterator i = free.begin(); i != free.end(); ++i) { + f->open_object_section("range"); + f->dump_int("start", (*i).first); + f->dump_int("len", (*i).second); + f->close_section(); + } + f->close_section(); + + f->close_section(); +} + + +void InoTable::generate_test_instances(list& ls) +{ + ls.push_back(new InoTable()); +} + + +bool InoTable::is_marked_free(inodeno_t id) const +{ + return free.contains(id) || projected_free.contains(id); +} + +bool InoTable::intersects_free( + const interval_set &other, + interval_set *intersection) +{ + interval_set i; + i.intersection_of(free, other); + if (intersection != nullptr) { + *intersection = i; + } + return !(i.empty()); +} + +bool InoTable::repair(inodeno_t id) +{ + if (projected_version != version) { + // Can't do the repair while other things are in flight + return false; + } + + assert(is_marked_free(id)); + dout(10) << "repair: before status. ino = 0x" << std::hex << id << " pver =" << projected_version << " ver= " << version << dendl; + free.erase(id); + projected_free.erase(id); + projected_version = ++version; + dout(10) << "repair: after status. ino = 0x" << std::hex <