return true;
}
+#undef dout_prefix
+#define dout_prefix *_dout << "bluestore.blob(" << this << ") "
+#undef dout_context
+#define dout_context cct
+
+// Cut Buffers that are not covered by extents.
+// It happens when we punch hole in Blob, but not refill with new data.
+// Normally it is not a problem (other then wasted memory),
+// but when 2 Blobs are merged Buffers might collide.
+// Todo: in future cut Buffers when we delete extents from Blobs,
+// and get rid of this function.
+void BlueStore::Blob::discard_unused_buffers(CephContext* cct, BufferCacheShard* cache)
+{
+ dout(25) << __func__ << " input " << *this << " bc=" << bc << dendl;
+ const PExtentVector& extents = get_blob().get_extents();
+ uint32_t epos = 0;
+ auto e = extents.begin();
+ while(e != extents.end()) {
+ if (!e->is_valid()) {
+ bc._discard(cache, epos, e->length);
+ }
+ epos += e->length;
+ ++e;
+ }
+ ceph_assert(epos <= blob.get_logical_length());
+ // Preferably, we would trim up to blob.get_logical_length(),
+ // but we copied writing buffers (see _dup_writing) before blob logical_length is fixed.
+ bc._discard(cache, epos, OBJECT_MAX_SIZE - epos);
+ dout(25) << __func__ << " output bc=" << bc << dendl;
+}
+
void BlueStore::Blob::dup(const Blob& from, bool copy_used_in_blob)
{
set_shared_blob(from.shared_blob);
void _rm_buffer(BufferCacheShard* cache, Buffer *b) {
_rm_buffer(cache, buffer_map.find(b->offset));
}
- void _rm_buffer(BufferCacheShard* cache,
+ std::map<uint32_t, std::unique_ptr<Buffer>>::iterator
+ _rm_buffer(BufferCacheShard* cache,
std::map<uint32_t, std::unique_ptr<Buffer>>::iterator p) {
ceph_assert(p != buffer_map.end());
cache->_audit("_rm_buffer start");
} else {
cache->_rm(p->second.get());
}
- buffer_map.erase(p);
+ p = buffer_map.erase(p);
cache->_audit("_rm_buffer end");
+ return p;
}
std::map<uint32_t,std::unique_ptr<Buffer>>::iterator _data_lower_bound(
#endif
return blob;
}
+ /// clear buffers from unused sections
+ void discard_unused_buffers(CephContext* cct, BufferCacheShard* cache);
inline const BufferSpace& get_bc() const {
return bc;