void InoTable::project_alloc_ids(interval_set<inodeno_t>& ids, int want)
{
- dout(10) << "project_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl;
assert(is_active());
while (want > 0) {
inodeno_t start = projected_free.start();
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<inodeno_t>& ids)
void InoTable::replay_alloc_id(inodeno_t id)
{
dout(10) << "replay_alloc_id " << id << dendl;
- free.erase(id);
- projected_free.erase(id);
+ if (free.contains(id)) {
+ free.erase(id);
+ projected_free.erase(id);
+ } else {
+ stringstream ss;
+ ss << "journal replay alloc " << id << " not in free " << free;
+ mds->logclient.log(LOG_ERROR, ss);
+ }
projected_version = ++version;
}
void InoTable::replay_alloc_ids(interval_set<inodeno_t>& ids)
{
dout(10) << "replay_alloc_ids " << ids << dendl;
- free.subtract(ids);
- projected_free.subtract(ids);
+ interval_set<inodeno_t> is;
+ is.intersection_of(free, ids);
+ if (is == ids) {
+ free.subtract(ids);
+ projected_free.subtract(ids);
+ } else {
+ stringstream ss;
+ ss << "journal replay alloc " << ids << ", only " << is << " is in free " << free;
+ mds->logclient.log(LOG_ERROR, ss);
+ free.subtract(is);
+ projected_free.subtract(is);
+ }
projected_version = ++version;
}
void InoTable::replay_release_ids(interval_set<inodeno_t>& ids)
version_t get_committing_version() { return committing_version; }
version_t get_projected_version() { return projected_version; }
+ void force_replay_version(version_t v) {
+ version = projected_version = v;
+ }
+
//version_t project_version() { return ++projected_version; }
//version_t inc_version() { return ++version; }
cmapv(v),
inotablev(0) {
}
- ESession(entity_inst_t inst, bool o, version_t v, interval_set<inodeno_t>& i, version_t iv) :
+ ESession(entity_inst_t inst, bool o, version_t v,
+ const interval_set<inodeno_t>& i, version_t iv) :
LogEvent(EVENT_SESSION),
client_inst(inst),
open(o),
mds->inotable->replay_alloc_id(allocated_ino);
if (preallocated_inos.size())
mds->inotable->replay_alloc_ids(preallocated_inos);
+
+ // [repair bad inotable updates]
+ if (inotablev > mds->inotable->get_version()) {
+ stringstream ss;
+ ss << "journal replay inotablev mismatch " << mds->inotable->get_version() << " -> " << inotablev;
+ mds->logclient.log(LOG_ERROR, ss);
+ mds->inotable->force_replay_version(inotablev);
+ }
+
assert(inotablev == mds->inotable->get_version());
}
}