f->close_section();
}
+void BlueFS::dump_block_extents(ostream& out)
+{
+ for (unsigned i = 0; i < MAX_BDEV; ++i) {
+ if (!bdev[i]) {
+ continue;
+ }
+ out << i << " : size 0x" << std::hex << bdev[i]->get_size()
+ << " : own 0x" << block_all[i] << std::dec << "\n";
+ }
+}
void BlueFS::get_usage(vector<pair<uint64_t,uint64_t>> *usage)
{
assert(!new_log);
assert(!new_log_writer);
+ // create a new log [writer] so that we know compaction is in progress
+ // (see _should_compact_log)
+ new_log = new File;
+ new_log->fnode.ino = 0; // so that _flush_range won't try to log the fnode
+
+ // 0. wait for any racing flushes to complete. (We do not want to block
+ // in _flush_sync_log with jump_to set or else a racing thread might flush
+ // our entries and our jump_to update won't be correct.)
+ while (log_flushing) {
+ dout(10) << __func__ << " log is currently flushing, waiting" << dendl;
+ log_cond.wait(l);
+ }
+
// 1. allocate new log space and jump to it.
old_log_jump_to = log_file->fnode.get_allocated();
uint64_t need = old_log_jump_to + cct->_conf->bluefs_max_log_runway;
dout(10) << __func__ << " new_log_jump_to 0x" << std::hex << new_log_jump_to
<< std::dec << dendl;
- // create a new log [writer]
- new_log = new File;
- new_log->fnode.ino = 0; // so that _flush_range won't try to log the fnode
+ // allocate
int r = _allocate(BlueFS::BDEV_DB, new_log_jump_to,
&new_log->fnode.extents);
assert(r == 0);
while (log_flushing) {
dout(10) << __func__ << " want_seq " << want_seq
<< " log is currently flushing, waiting" << dendl;
+ assert(!jump_to);
log_cond.wait(l);
}
if (want_seq && want_seq <= log_seq_stable) {
dout(10) << __func__ << " want_seq " << want_seq << " <= log_seq_stable "
<< log_seq_stable << ", done" << dendl;
+ assert(!jump_to);
return 0;
}
if (log_t.empty() && dirty_files.empty()) {
dout(10) << __func__ << " want_seq " << want_seq
<< " " << log_t << " not dirty, dirty_files empty, no-op" << dendl;
+ assert(!jump_to);
return 0;
}
derr << __func__ << " allocated: 0x" << std::hex << allocated
<< " offset: 0x" << offset << " length: 0x" << length << std::dec
<< dendl;
+ assert(0 == "bluefs enospc");
return r;
}
h->file->fnode.recalc_allocated();
uint64_t left = ROUND_UP_TO(len, min_alloc_size);
int r = -ENOSPC;
+ int64_t alloc_len = 0;
+ AllocExtentVector extents;
+
if (alloc[id]) {
r = alloc[id]->reserve(left);
}
- if (r < 0) {
+
+ if (r == 0) {
+ uint64_t hint = 0;
+ if (!ev->empty()) {
+ hint = ev->back().end();
+ }
+ extents.reserve(4); // 4 should be (more than) enough for most allocations
+ alloc_len = alloc[id]->allocate(left, min_alloc_size, hint, &extents);
+ }
+ if (r < 0 || (alloc_len < (int64_t)left)) {
+ if (r == 0) {
+ alloc[id]->unreserve(left - alloc_len);
+ for (auto& p : extents) {
+ alloc[id]->release(p.offset, p.length);
+ }
+ }
if (id != BDEV_SLOW) {
if (bdev[id]) {
dout(1) << __func__ << " failed to allocate 0x" << std::hex << left
else
derr << __func__ << " failed to allocate 0x" << std::hex << left
<< " on bdev " << (int)id << ", dne" << std::dec << dendl;
- return r;
- }
-
- uint64_t hint = 0;
- if (!ev->empty()) {
- hint = ev->back().end();
- }
-
- AllocExtentVector extents;
- extents.reserve(4); // 4 should be (more than) enough for most allocations
- int64_t alloc_len = alloc[id]->allocate(left, min_alloc_size, hint,
- &extents);
- if (alloc_len < (int64_t)left) {
- derr << __func__ << " allocate failed on 0x" << std::hex << left
- << " min_alloc_size 0x" << min_alloc_size
- << " hint 0x" << hint << std::dec << dendl;
- alloc[id]->dump();
- assert(0 == "allocate failed... wtf");
+ if (alloc[id])
+ alloc[id]->dump();
return -ENOSPC;
}
_drop_link(file);
return 0;
}
+
+bool BlueFS::wal_is_rotational()
+{
+ if (!bdev[BDEV_WAL] || bdev[BDEV_WAL]->is_rotational())
+ return true;
+ return false;
+}