bool seen_recs = false;
boost::dynamic_bitset<uint64_t> used_blocks[MAX_BDEV];
+ boost::dynamic_bitset<uint64_t> owned_blocks[MAX_BDEV];
+
if (cct->_conf->bluefs_log_replay_check_allocations) {
for (size_t i = 0; i < MAX_BDEV; ++i) {
if (alloc_size[i] != 0 && bdev[i] != nullptr) {
used_blocks[i].resize(bdev[i]->get_size() / alloc_size[i]);
+ owned_blocks[i].resize(bdev[i]->get_size() / alloc_size[i]);
}
}
}
if (cct->_conf->bluefs_log_replay_check_allocations) {
bool fail = false;
+ apply(offset, length, alloc_size[id], owned_blocks[id],
+ [&](uint64_t pos, boost::dynamic_bitset<uint64_t> &bs) {
+ ceph_assert(pos < bs.size());
+ if (bs.test(pos)) {
+ fail = true;
+ } else {
+ bs.set(pos);
+ }
+ }
+ );
+ if (fail) {
+ derr << __func__ << " invalid extent " << (int)id
+ << ": 0x" << std::hex << offset << "~" << length
+ << std::dec << ": already given" << dendl;
+ return -EFAULT;
+ }
apply(offset, length, alloc_size[id], used_blocks[id],
[&](uint64_t pos, boost::dynamic_bitset<uint64_t> &bs) {
ceph_assert(pos < bs.size());
}
);
if (fail) {
- derr << __func__ << " invalid extent " << id << ": 0x" << std::hex << offset << "~" << length
+ derr << __func__ << " invalid extent " << int(id)
+ << ": 0x" << std::hex << offset << "~" << length
<< std::dec << ": already in use" << dendl;
return -EFAULT;
}
alloc[id]->init_rm_free(offset, length);
if (cct->_conf->bluefs_log_replay_check_allocations) {
bool fail = false;
+ apply(offset, length, alloc_size[id], owned_blocks[id],
+ [&](uint64_t pos, boost::dynamic_bitset<uint64_t> &bs) {
+ ceph_assert(pos < bs.size());
+ if (!bs.test(pos)) {
+ fail = true;
+ } else {
+ bs.reset(pos);
+ }
+ }
+ );
+ if (fail) {
+ derr << __func__ << " invalid extent " << int(id)
+ << ": 0x" << std::hex << offset << "~" << length
+ << std::dec << ": wasn't given" << dendl;
+ return -EFAULT;
+ }
+
apply(offset, length, alloc_size[id], used_blocks[id],
[&](uint64_t pos, boost::dynamic_bitset<uint64_t> &bs) {
ceph_assert(pos < bs.size());
}
);
if (fail) {
- derr << __func__ << " invalid extent " << id << ": 0x" << std::hex << offset << "~" << length
+ derr << __func__ << " invalid extent " << (int)id
+ << ": 0x" << std::hex << offset << "~" << length
<< std::dec << ": still in use" << dendl;
return -EFAULT;
}
for (auto e : fnode_extents) {
auto id = e.bdev;
bool fail = false;
+ apply(e.offset, e.length, alloc_size[id], owned_blocks[id],
+ [&](uint64_t pos, boost::dynamic_bitset<uint64_t> &bs) {
+ ceph_assert(pos < bs.size());
+ if (!bs.test(pos)) {
+ fail = true;
+ }
+ }
+ );
+ if (fail) {
+ derr << __func__ << " invalid extent " << int(id)
+ << ": 0x" << std::hex << e.offset << "~" << e.length
+ << std::dec
+ << ": wasn't given but allocated for ino " << fnode.ino
+ << dendl;
+ return -EFAULT;
+ }
+
apply(e.offset, e.length, alloc_size[id], used_blocks[id],
[&](uint64_t pos, boost::dynamic_bitset<uint64_t> &bs) {
ceph_assert(pos < bs.size());
}
);
if (fail) {
- derr << __func__ << " invalid extent " << e.bdev << ": 0x" << std::hex << e.offset << "~" << e.length
- << std::dec << ": duplicate reference, ino " << fnode.ino << dendl;
+ derr << __func__ << " invalid extent " << int(e.bdev)
+ << ": 0x" << std::hex << e.offset << "~" << e.length
+ << std::dec << ": duplicate reference, ino " << fnode.ino
+ << dendl;
return -EFAULT;
}
}
for (auto e : fnode_extents) {
auto id = e.bdev;
bool fail = false;
+ apply(e.offset, e.length, alloc_size[id], owned_blocks[id],
+ [&](uint64_t pos, boost::dynamic_bitset<uint64_t> &bs) {
+ ceph_assert(pos < bs.size());
+ if (!bs.test(pos)) {
+ fail = true;
+ }
+ }
+ );
+ if (fail) {
+ derr << __func__ << " invalid extent " << int(id)
+ << ": 0x" << std::hex << e.offset << "~" << e.length
+ << std::dec
+ << ": wasn't given but allocated for removed ino " << ino
+ << dendl;
+ return -EFAULT;
+ }
+
apply(e.offset, e.length, alloc_size[id], used_blocks[id],
[&](uint64_t pos, boost::dynamic_bitset<uint64_t> &bs) {
ceph_assert(pos < bs.size());
}
);
if (fail) {
- derr << __func__ << " invalid extent " << e.bdev << ": 0x" << std::hex << e.offset << "~" << e.length
- << std::dec << ": not in use while releasing for ino " << ino << dendl;
+ derr << __func__ << " invalid extent " << int(id)
+ << ": 0x" << std::hex << e.offset << "~" << e.length
+ << std::dec
+ << ": not in use but allocated for removed ino " << ino
+ << dendl;
return -EFAULT;
}
}