From: Sage Weil Date: Sat, 1 Feb 2020 18:11:19 +0000 (-0600) Subject: os/bluestore/BlueFS: reclaim unused too-granular extents first X-Git-Tag: v15.1.1~469^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=d1e67344b778dbd9a17b59d8b751ed9c5ff5ba9b;p=ceph-ci.git os/bluestore/BlueFS: reclaim unused too-granular extents first If we have extents that were too granular (below our allocator alloc_size), return those first. Signed-off-by: Sage Weil --- diff --git a/src/os/bluestore/BlueFS.cc b/src/os/bluestore/BlueFS.cc index 81b2cc5cfe3..03c1270859a 100644 --- a/src/os/bluestore/BlueFS.cc +++ b/src/os/bluestore/BlueFS.cc @@ -336,24 +336,44 @@ int BlueFS::reclaim_blocks(unsigned id, uint64_t want, << " want 0x" << std::hex << want << std::dec << dendl; ceph_assert(id < alloc.size()); ceph_assert(alloc[id]); - - int64_t got = alloc[id]->allocate(want, alloc_size[id], 0, extents); - ceph_assert(got != 0); - if (got < 0) { - derr << __func__ << " failed to allocate space to return to bluestore" - << dendl; - alloc[id]->dump(); - return got; + int64_t got = 0; + + interval_set granular; + while (want > 0 && !block_unused_too_granular[id].empty()) { + auto p = block_unused_too_granular[id].begin(); + dout(20) << __func__ << " unused " << (int)id << ":" + << std::hex << p.get_start() << "~" << p.get_len() << dendl; + extents->push_back({p.get_start(), p.get_len()}); + granular.insert(p.get_start(), p.get_len()); + if (want >= p.get_len()) { + want -= p.get_len(); + } else { + want = 0; + } + got += p.get_len(); + block_unused_too_granular[id].erase(p); } - for (auto& p : *extents) { - block_all[id].erase(p.offset, p.length); - log_t.op_alloc_rm(id, p.offset, p.length); - } + if (want > 0) { + got += alloc[id]->allocate(want, alloc_size[id], 0, extents); + ceph_assert(got != 0); + if (got < 0) { + derr << __func__ << " failed to allocate space to return to bluestore" + << dendl; + alloc[id]->dump(); + block_unused_too_granular[id].insert(granular); + return got; + } - flush_bdev(); - int r = _flush_and_sync_log(l); - ceph_assert(r == 0); + for (auto& p : *extents) { + block_all[id].erase(p.offset, p.length); + log_t.op_alloc_rm(id, p.offset, p.length); + } + + flush_bdev(); + int r = _flush_and_sync_log(l); + ceph_assert(r == 0); + } logger->inc(l_bluefs_reclaim_bytes, got); dout(1) << __func__ << " bdev " << id << " want 0x" << std::hex << want @@ -861,9 +881,15 @@ int BlueFS::_adjust_granularity( } if (*length & (alloc_size[id] - 1)) { *length &= ~(alloc_size[id] - 1); - block_unused_too_granular[id].insert( - *offset + *length, - oldo + oldl - *offset - *length); + if (alloc) { + block_unused_too_granular[id].insert( + *offset + *length, + oldo + oldl - *offset - *length); + } else { + block_unused_too_granular[id].erase( + *offset + *length, + oldo + oldl - *offset - *length); + } } if (oldo != *offset || oldl != *length) { derr << __func__ << " " << op << " "