}
+// Blob
+
+#undef dout_prefix
+#define dout_prefix *_dout << "bluestore.blob(" << this << ") "
+
+void BlueStore::Blob::discard_unallocated()
+{
+ size_t pos = 0;
+ for (auto e : blob.extents) {
+ if (!e.is_valid()) {
+ bc.discard(pos, e.length);
+ }
+ pos += e.length;
+ }
+}
+
// BlobMap
#undef dout_prefix
vector<bluestore_pextent_t> r;
bool compressed = b->blob.is_compressed();
b->blob.put_ref(l.offset, l.length, min_alloc_size, &r);
+ if (l.blob > 0) {
+ // blob is owned by the onode; invalidate buffers as *we* drop
+ // logical refs.
+ b->bc.discard(l.offset, l.length);
+ } else {
+ // blob is shared. we can't invalidate our logical extents as
+ // we drop them because other onodes may still reference them.
+ // but we can throw out anything that is no longer allocated.
+ // Note that this will leave behind edge bits that are no
+ // longer referenced but not deallocated (until they age out
+ // of the cache naturally).
+ b->discard_unallocated();
+ }
txc->statfs_delta.stored() -= l.length;
if (compressed) {
txc->statfs_delta.compressed_original() -= l.length;
friend ostream& operator<<(ostream& out, const Blob &b) {
return out << b.id << ":" << b.blob;
}
+
+ /// discard buffers for unallocated regions
+ void discard_unallocated();
};
/// a map of blobs, indexed by int64_t