Rename flags to entry_type

This commit is contained in:
Vitaliy Filippov
2025-12-02 01:52:12 +03:00
parent 04531bcfbb
commit ef792608b0
8 changed files with 82 additions and 80 deletions
+1 -1
View File
@@ -223,7 +223,7 @@ resume_1:
bs->heap->unlock_entry(cur_oid, copy_id); bs->heap->unlock_entry(cur_oid, copy_id);
goto resume_0; goto resume_0;
} }
assert(!end_wr->next() && end_wr->flags == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE)); assert(!end_wr->next() && end_wr->entry_type == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE));
clean_loc = end_wr->location; clean_loc = end_wr->location;
if (bs->log_level > 10) if (bs->log_level > 10)
printf("Compacting %jx:%jx l%ju .. l%ju (last l%ju)\n", cur_oid.inode, cur_oid.stripe, end_wr->lsn, begin_wr->lsn, compact_lsn); printf("Compacting %jx:%jx l%ju .. l%ju (last l%ju)\n", cur_oid.inode, cur_oid.stripe, end_wr->lsn, begin_wr->lsn, compact_lsn);
+19 -19
View File
@@ -68,14 +68,14 @@ bool heap_write_t::needs_recheck(blockstore_heap_t *heap)
bool heap_write_t::needs_compact(blockstore_heap_t *heap) bool heap_write_t::needs_compact(blockstore_heap_t *heap)
{ {
return (flags == (BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE) || return (entry_type == (BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE) ||
flags == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE) && heap->dsk->csum_block_size > heap->dsk->bitmap_granularity && entry_type == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE) && heap->dsk->csum_block_size > heap->dsk->bitmap_granularity &&
((offset % heap->dsk->csum_block_size) || (len % heap->dsk->csum_block_size))); ((offset % heap->dsk->csum_block_size) || (len % heap->dsk->csum_block_size)));
} }
bool heap_write_t::is_compacted(uint64_t compacted_lsn) bool heap_write_t::is_compacted(uint64_t compacted_lsn)
{ {
return lsn <= compacted_lsn && (flags == (BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE) || flags == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE)); return lsn <= compacted_lsn && (entry_type == (BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE) || entry_type == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE));
} }
bool heap_write_t::can_be_collapsed(blockstore_heap_t *heap) bool heap_write_t::can_be_collapsed(blockstore_heap_t *heap)
@@ -87,8 +87,8 @@ bool heap_write_t::can_be_collapsed(blockstore_heap_t *heap)
bool heap_write_t::is_allowed_before_compacted(uint64_t compacted_lsn, bool is_last_entry) bool heap_write_t::is_allowed_before_compacted(uint64_t compacted_lsn, bool is_last_entry)
{ {
return lsn <= compacted_lsn && (is_last_entry return lsn <= compacted_lsn && (is_last_entry
? (flags == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE)) ? (entry_type == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE))
: (flags == (BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE) || flags == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE))); : (entry_type == (BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE) || entry_type == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE)));
} }
uint8_t *heap_write_t::get_ext_bitmap(blockstore_heap_t *heap) uint8_t *heap_write_t::get_ext_bitmap(blockstore_heap_t *heap)
@@ -738,7 +738,7 @@ bool blockstore_heap_t::recheck_small_writes(std::function<void(bool is_data, ui
if (is_intent) if (is_intent)
{ {
auto next_wr = wr->next(); auto next_wr = wr->next();
assert(next_wr && next_wr->flags == (BS_HEAP_BIG_WRITE | (wr->flags & BS_HEAP_STABLE))); assert(next_wr && next_wr->entry_type == (BS_HEAP_BIG_WRITE | (wr->entry_type & BS_HEAP_STABLE)));
loc = wr->offset + next_wr->location; loc = wr->offset + next_wr->location;
} }
recheck_in_progress++; recheck_in_progress++;
@@ -1247,8 +1247,8 @@ uint32_t blockstore_heap_t::block_has_compactable(uint8_t *data)
region_marker > sizeof(heap_object_t)) region_marker > sizeof(heap_object_t))
{ {
heap_write_t *wr = (heap_write_t*)data; heap_write_t *wr = (heap_write_t*)data;
if (wr->flags == (BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE) || if (wr->entry_type == (BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE) ||
wr->flags == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE)) wr->entry_type == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE))
{ {
// May be freed in the future // May be freed in the future
sum += wr->size; sum += wr->size;
@@ -1447,7 +1447,7 @@ bool blockstore_heap_t::mvcc_save_copy(heap_object_t *obj)
if (wr->type() == BS_HEAP_BIG_WRITE) if (wr->type() == BS_HEAP_BIG_WRITE)
{ {
mvcc_data_refs[wr->location] += add_ref; mvcc_data_refs[wr->location] += add_ref;
if (wr->flags & BS_HEAP_STABLE) if (wr->entry_type & BS_HEAP_STABLE)
{ {
if (!for_obj) if (!for_obj)
{ {
@@ -1491,19 +1491,19 @@ int blockstore_heap_t::update_object(uint32_t block_num, heap_object_t *obj, hea
{ {
const auto oid = (object_id){ .inode = obj->inode, .stripe = obj->stripe }; const auto oid = (object_id){ .inode = obj->inode, .stripe = obj->stripe };
// First some validation // First some validation
bool is_overwrite = (wr->flags == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE) || wr->flags == (BS_HEAP_TOMBSTONE|BS_HEAP_STABLE)); bool is_overwrite = (wr->entry_type == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE) || wr->entry_type == (BS_HEAP_TOMBSTONE|BS_HEAP_STABLE));
auto first_wr = obj->get_writes(); auto first_wr = obj->get_writes();
if (first_wr->type() == BS_HEAP_TOMBSTONE && !is_overwrite) if (first_wr->type() == BS_HEAP_TOMBSTONE && !is_overwrite)
{ {
// Small overwrites are only allowed over live objects // Small overwrites are only allowed over live objects
return EINVAL; return EINVAL;
} }
if (!(first_wr->flags & BS_HEAP_STABLE) && (wr->flags & BS_HEAP_STABLE)) if (!(first_wr->entry_type & BS_HEAP_STABLE) && (wr->entry_type & BS_HEAP_STABLE))
{ {
// Stable overwrites are not allowed over unstable // Stable overwrites are not allowed over unstable
return EINVAL; return EINVAL;
} }
if (wr->flags == BS_HEAP_INTENT_WRITE && (first_wr->flags & BS_HEAP_STABLE)) if (wr->entry_type == BS_HEAP_INTENT_WRITE && (first_wr->entry_type & BS_HEAP_STABLE))
{ {
// Unstable intent writes over stable are not allowed // Unstable intent writes over stable are not allowed
return EINVAL; return EINVAL;
@@ -1673,7 +1673,7 @@ int blockstore_heap_t::post_stabilize(object_id oid, uint64_t version, uint32_t
uint64_t stab_count = 0; uint64_t stab_count = 0;
for (; wr; wr = wr->next()) for (; wr; wr = wr->next())
{ {
if ((wr->flags & BS_HEAP_STABLE)) if ((wr->entry_type & BS_HEAP_STABLE))
{ {
break; break;
} }
@@ -1721,9 +1721,9 @@ int blockstore_heap_t::post_stabilize(object_id oid, uint64_t version, uint32_t
uint64_t last_lsn = next_lsn; uint64_t last_lsn = next_lsn;
for (wr = obj->get_writes(); wr; wr = wr->next()) for (wr = obj->get_writes(); wr; wr = wr->next())
{ {
if (!(wr->flags & BS_HEAP_STABLE) && wr->version <= version) if (!(wr->entry_type & BS_HEAP_STABLE) && wr->version <= version)
{ {
wr->flags |= BS_HEAP_STABLE; wr->entry_type |= BS_HEAP_STABLE;
wr->lsn = last_lsn--; wr->lsn = last_lsn--;
push_inflight_lsn(oid, wr->lsn, wr->needs_compact(this) ? HEAP_INFLIGHT_COMPACTABLE : 0); push_inflight_lsn(oid, wr->lsn, wr->needs_compact(this) ? HEAP_INFLIGHT_COMPACTABLE : 0);
} }
@@ -1750,14 +1750,14 @@ int blockstore_heap_t::post_rollback(object_id oid, uint64_t version, uint64_t *
// No such version // No such version
return ENOENT; return ENOENT;
} }
if (wr->version == version && (wr->flags & BS_HEAP_STABLE)) if (wr->version == version && (wr->entry_type & BS_HEAP_STABLE))
{ {
// Already rolled back // Already rolled back
return 0; return 0;
} }
for (; wr && wr->version > version; wr = wr->next()) for (; wr && wr->version > version; wr = wr->next())
{ {
if (wr->flags & BS_HEAP_STABLE) if (wr->entry_type & BS_HEAP_STABLE)
{ {
// Already committed, can't rollback // Already committed, can't rollback
return EBUSY; return EBUSY;
@@ -1939,7 +1939,7 @@ void blockstore_heap_t::free_object_space(inode_t inode, heap_write_t *from, hea
if (wr->type() == BS_HEAP_BIG_WRITE) if (wr->type() == BS_HEAP_BIG_WRITE)
{ {
deref_data(inode, wr->location, mode != BS_HEAP_FREE_MAIN); deref_data(inode, wr->location, mode != BS_HEAP_FREE_MAIN);
if (mode == BS_HEAP_FREE_MVCC && (wr->flags & BS_HEAP_STABLE)) if (mode == BS_HEAP_FREE_MVCC && (wr->entry_type & BS_HEAP_STABLE))
{ {
// Stop at the last visible version // Stop at the last visible version
break; break;
@@ -2045,7 +2045,7 @@ int blockstore_heap_t::list_objects(uint32_t pg_num, object_id min_oid, object_i
auto first_wr = obj->get_writes(); auto first_wr = obj->get_writes();
for (auto wr = first_wr; wr; wr = wr->next()) for (auto wr = first_wr; wr; wr = wr->next())
{ {
if (wr->flags & BS_HEAP_STABLE) if (wr->entry_type & BS_HEAP_STABLE)
{ {
stable_version = wr->version; stable_version = wr->version;
break; break;
+2 -2
View File
@@ -35,19 +35,19 @@ struct __attribute__((__packed__)) heap_write_t
// size should have top bit cleared // size should have top bit cleared
uint16_t size = 0; uint16_t size = 0;
int16_t next_pos = 0; int16_t next_pos = 0;
uint8_t entry_type = 0; // BS_HEAP_*
uint64_t lsn = 0; uint64_t lsn = 0;
uint64_t version = 0; uint64_t version = 0;
uint32_t offset = 0; uint32_t offset = 0;
uint32_t len = 0; uint32_t len = 0;
uint64_t location = 0; uint64_t location = 0;
uint8_t flags = 0; // 1|2|3 = small|big|tombstone, 4|0 = stable|unstable
// uint8_t[] external_bitmap // uint8_t[] external_bitmap
// uint8_t[] internal_bitmap // uint8_t[] internal_bitmap
// uint32_t[] checksums // uint32_t[] checksums
heap_write_t *next(); heap_write_t *next();
inline uint8_t type() const { return (flags & BS_HEAP_TYPE); } inline uint8_t type() const { return (entry_type & BS_HEAP_TYPE); }
uint32_t get_size(blockstore_heap_t *heap); uint32_t get_size(blockstore_heap_t *heap);
uint32_t get_csum_size(blockstore_heap_t *heap); uint32_t get_csum_size(blockstore_heap_t *heap);
bool needs_recheck(blockstore_heap_t *heap); bool needs_recheck(blockstore_heap_t *heap);
+7 -7
View File
@@ -136,14 +136,14 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
(!perfect_csum_update || dsk.csum_block_size <= dsk.bitmap_granularity || (!perfect_csum_update || dsk.csum_block_size <= dsk.bitmap_granularity ||
!(op->offset % dsk.csum_block_size) && !(op->offset % dsk.csum_block_size) &&
!(op->len % dsk.csum_block_size) && !(op->len % dsk.csum_block_size) &&
(obj->get_writes()->flags != (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE) || (obj->get_writes()->entry_type != (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE) ||
obj->get_writes()->can_be_collapsed(heap))) && obj->get_writes()->can_be_collapsed(heap))) &&
// One intent-write is allowed even with fsyncs because BIG_WRITE is always counted as fsynced // One intent-write is allowed even with fsyncs because BIG_WRITE is always counted as fsynced
dsk.disable_meta_fsync && dsk.disable_meta_fsync &&
(op->opcode == BS_OP_WRITE_STABLE && (op->opcode == BS_OP_WRITE_STABLE &&
(obj->get_writes()->flags == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE) || (obj->get_writes()->entry_type == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE) ||
obj->get_writes()->flags == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE) && dsk.disable_data_fsync) || obj->get_writes()->entry_type == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE) && dsk.disable_data_fsync) ||
op->opcode == BS_OP_WRITE && obj->get_writes()->flags == BS_HEAP_BIG_WRITE)) op->opcode == BS_OP_WRITE && obj->get_writes()->entry_type == BS_HEAP_BIG_WRITE))
{ {
// Direct intent-write // Direct intent-write
BS_SUBMIT_CHECK_SQES(1); BS_SUBMIT_CHECK_SQES(1);
@@ -163,7 +163,7 @@ process_intent:
wr->offset = op->offset; wr->offset = op->offset;
wr->len = op->len; wr->len = op->len;
wr->location = 0; wr->location = 0;
wr->flags = BS_HEAP_INTENT_WRITE | (op->opcode == BS_OP_WRITE_STABLE ? BS_HEAP_STABLE : 0); wr->entry_type = BS_HEAP_INTENT_WRITE | (op->opcode == BS_OP_WRITE_STABLE ? BS_HEAP_STABLE : 0);
if (op->bitmap) if (op->bitmap)
memcpy(wr->get_ext_bitmap(heap), op->bitmap, dsk.clean_entry_bitmap_size); memcpy(wr->get_ext_bitmap(heap), op->bitmap, dsk.clean_entry_bitmap_size);
heap->calc_checksums(wr, (uint8_t*)op->buf, true); heap->calc_checksums(wr, (uint8_t*)op->buf, true);
@@ -212,7 +212,7 @@ process_intent:
wr->len = op->len; wr->len = op->len;
wr->location = loc; wr->location = loc;
PRIV(op)->location = loc; PRIV(op)->location = loc;
wr->flags = BS_HEAP_SMALL_WRITE | (op->opcode == BS_OP_WRITE_STABLE ? BS_HEAP_STABLE : 0); wr->entry_type = BS_HEAP_SMALL_WRITE | (op->opcode == BS_OP_WRITE_STABLE ? BS_HEAP_STABLE : 0);
if (op->bitmap) if (op->bitmap)
memcpy(wr->get_ext_bitmap(heap), op->bitmap, dsk.clean_entry_bitmap_size); memcpy(wr->get_ext_bitmap(heap), op->bitmap, dsk.clean_entry_bitmap_size);
heap->calc_checksums(wr, (uint8_t*)op->buf, true); heap->calc_checksums(wr, (uint8_t*)op->buf, true);
@@ -271,7 +271,7 @@ int blockstore_impl_t::make_big_write(blockstore_op_t *op, uint32_t offset, uint
wr->offset = offset; wr->offset = offset;
wr->len = len; wr->len = len;
wr->location = PRIV(op)->location; wr->location = PRIV(op)->location;
wr->flags = BS_HEAP_BIG_WRITE | (op->opcode == BS_OP_WRITE_STABLE ? BS_HEAP_STABLE : 0); wr->entry_type = BS_HEAP_BIG_WRITE | (op->opcode == BS_OP_WRITE_STABLE ? BS_HEAP_STABLE : 0);
if (op->bitmap) if (op->bitmap)
memcpy(wr->get_ext_bitmap(heap), op->bitmap, dsk.clean_entry_bitmap_size); memcpy(wr->get_ext_bitmap(heap), op->bitmap, dsk.clean_entry_bitmap_size);
memset(wr->get_int_bitmap(heap), 0, dsk.clean_entry_bitmap_size); memset(wr->get_int_bitmap(heap), 0, dsk.clean_entry_bitmap_size);
+1 -1
View File
@@ -59,7 +59,7 @@ int disk_tool_t::trim_data(std::string device)
{ {
for (auto wr = obj->get_writes(); wr; wr = wr->next()) for (auto wr = obj->get_writes(); wr; wr = wr->next())
{ {
if ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_BIG_WRITE) if ((wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_BIG_WRITE)
{ {
data_alloc->set(wr->location / dsk.data_block_size, true); data_alloc->set(wr->location / dsk.data_block_size, true);
} }
+17 -15
View File
@@ -337,11 +337,11 @@ void disk_tool_t::dump_meta_header(blockstore_meta_header_v3_t *hdr)
void disk_tool_t::dump_heap_entry_as_old(blockstore_heap_t *heap, heap_object_t *obj) void disk_tool_t::dump_heap_entry_as_old(blockstore_heap_t *heap, heap_object_t *obj)
{ {
heap_write_t *wr = NULL; heap_write_t *wr = NULL;
for (wr = obj->get_writes(); wr && wr->flags != (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE) && for (wr = obj->get_writes(); wr && wr->entry_type != (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE) &&
wr->flags != (BS_HEAP_TOMBSTONE|BS_HEAP_STABLE); wr = wr->next()) wr->entry_type != (BS_HEAP_TOMBSTONE|BS_HEAP_STABLE); wr = wr->next())
{ {
} }
if (!wr || wr->flags != (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE)) if (!wr || wr->entry_type != (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE))
{ {
return; return;
} }
@@ -398,19 +398,19 @@ void disk_tool_t::dump_heap_entry(blockstore_heap_t *heap, heap_object_t *obj)
#define ENTRY_FMT "{\"lsn\":%ju,\"version\":%ju,\"type\":\"%s\",\"stable\":%s,\"offset\":%u,\"len\":%u" #define ENTRY_FMT "{\"lsn\":%ju,\"version\":%ju,\"type\":\"%s\",\"stable\":%s,\"offset\":%u,\"len\":%u"
(first_wr ? ENTRY_FMT : ("," ENTRY_FMT)), (first_wr ? ENTRY_FMT : ("," ENTRY_FMT)),
#undef ENTRY_FMT #undef ENTRY_FMT
wr->lsn, wr->version, (wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE ? "small" : ( wr->lsn, wr->version, (wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE ? "small" : (
(wr->flags & BS_HEAP_TYPE) == BS_HEAP_BIG_WRITE ? "big" : ( (wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_BIG_WRITE ? "big" : (
(wr->flags & BS_HEAP_TYPE) == BS_HEAP_INTENT_WRITE ? "intent" : ( (wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_INTENT_WRITE ? "intent" : (
(wr->flags & BS_HEAP_TYPE) == BS_HEAP_TOMBSTONE ? "tombstone" : "unknown"))), (wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_TOMBSTONE ? "tombstone" : "unknown"))),
(wr->flags & BS_HEAP_STABLE) ? "true" : "false", (wr->entry_type & BS_HEAP_STABLE) ? "true" : "false",
wr->offset, wr->len wr->offset, wr->len
); );
if ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_BIG_WRITE || if ((wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_BIG_WRITE ||
(wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE && !dump_with_data) (wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE && !dump_with_data)
{ {
printf(",\"location\":%ju", wr->location); printf(",\"location\":%ju", wr->location);
} }
else if ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE && dump_with_data) else if ((wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE && dump_with_data)
{ {
printf(",\"data\":\""); printf(",\"data\":\"");
for (uint32_t i = 0; i < wr->len; i++) for (uint32_t i = 0; i < wr->len; i++)
@@ -612,6 +612,7 @@ int disk_tool_t::write_json_heap(json11::Json meta, json11::Json journal)
heap_object_t *obj = (heap_object_t*)object_buf.data(); heap_object_t *obj = (heap_object_t*)object_buf.data();
obj->size = sizeof(heap_object_t); obj->size = sizeof(heap_object_t);
obj->write_pos = meta_entry["writes"].array_items().size() ? sizeof(heap_object_t) : 0; obj->write_pos = meta_entry["writes"].array_items().size() ? sizeof(heap_object_t) : 0;
obj->entry_type = BS_HEAP_OBJECT;
obj->inode = oid.inode; obj->inode = oid.inode;
obj->stripe = oid.stripe; obj->stripe = oid.stripe;
size_t pos = sizeof(heap_object_t); size_t pos = sizeof(heap_object_t);
@@ -636,7 +637,7 @@ int disk_tool_t::write_json_heap(json11::Json meta, json11::Json journal)
invalid = true; invalid = true;
break; break;
} }
wr->flags = wr_type | (write_entry["stable"].bool_value() ? BS_HEAP_STABLE : 0); wr->entry_type = wr_type | (write_entry["stable"].bool_value() ? BS_HEAP_STABLE : 0);
wr->lsn = write_entry["lsn"].uint64_value(); wr->lsn = write_entry["lsn"].uint64_value();
wr->version = write_entry["version"].uint64_value(); wr->version = write_entry["version"].uint64_value();
wr->offset = write_entry["offset"].uint64_value(); wr->offset = write_entry["offset"].uint64_value();
@@ -769,11 +770,12 @@ close_err:
heap_object_t *obj = (heap_object_t*)(new_meta_buf + meta_offset + used_space); heap_object_t *obj = (heap_object_t*)(new_meta_buf + meta_offset + used_space);
obj->size = sizeof(heap_object_t); obj->size = sizeof(heap_object_t);
obj->write_pos = sizeof(heap_object_t); obj->write_pos = sizeof(heap_object_t);
obj->entry_type = BS_HEAP_OBJECT;
obj->inode = oid.inode; obj->inode = oid.inode;
obj->stripe = oid.stripe; obj->stripe = oid.stripe;
heap_write_t *wr = obj->get_writes(); heap_write_t *wr = obj->get_writes();
wr->next_pos = 0; wr->next_pos = 0;
wr->flags = BS_HEAP_BIG_WRITE|BS_HEAP_STABLE; wr->entry_type = BS_HEAP_BIG_WRITE|BS_HEAP_STABLE;
wr->lsn = ++next_lsn; wr->lsn = ++next_lsn;
wr->version = sscanf_json(NULL, meta_entry["version"]); wr->version = sscanf_json(NULL, meta_entry["version"]);
wr->offset = 0; wr->offset = 0;
@@ -802,7 +804,7 @@ close_err:
fprintf(stderr, "Error: entry data is missing, please generate the dump with --json --format data\n"); fprintf(stderr, "Error: entry data is missing, please generate the dump with --json --format data\n");
goto close_err; goto close_err;
} }
wr->flags = BS_HEAP_SMALL_WRITE | (rec["type"] == "small_write_instant" ? BS_HEAP_STABLE : 0); wr->entry_type = BS_HEAP_SMALL_WRITE | (rec["type"] == "small_write_instant" ? BS_HEAP_STABLE : 0);
fromhexstr(rec["bitmap"].string_value(), new_clean_entry_bitmap_size, wr->get_ext_bitmap(&heap)); fromhexstr(rec["bitmap"].string_value(), new_clean_entry_bitmap_size, wr->get_ext_bitmap(&heap));
fromhexstr(rec["data"].string_value(), wr->len, new_journal_buf+buffer_pos); fromhexstr(rec["data"].string_value(), wr->len, new_journal_buf+buffer_pos);
if (wr->len > 0) if (wr->len > 0)
@@ -816,7 +818,7 @@ close_err:
} }
else if (rec["type"] == "big_write" || rec["type"] == "big_write_instant") else if (rec["type"] == "big_write" || rec["type"] == "big_write_instant")
{ {
wr->flags = BS_HEAP_BIG_WRITE | (rec["type"] == "big_write_instant" ? BS_HEAP_STABLE : 0); wr->entry_type = BS_HEAP_BIG_WRITE | (rec["type"] == "big_write_instant" ? BS_HEAP_STABLE : 0);
wr->location = sscanf_json(NULL, rec["loc"]); wr->location = sscanf_json(NULL, rec["loc"]);
bitmap_set(wr->get_int_bitmap(&heap), wr->offset, wr->len, new_meta_hdr->bitmap_granularity); bitmap_set(wr->get_int_bitmap(&heap), wr->offset, wr->len, new_meta_hdr->bitmap_granularity);
fromhexstr(rec["bitmap"].string_value(), new_clean_entry_bitmap_size, wr->get_ext_bitmap(&heap)); fromhexstr(rec["bitmap"].string_value(), new_clean_entry_bitmap_size, wr->get_ext_bitmap(&heap));
+11 -11
View File
@@ -41,7 +41,7 @@ int disk_tool_t::raw_resize()
{ {
for (auto wr = obj->get_writes(); wr; wr = wr->next()) for (auto wr = obj->get_writes(); wr; wr = wr->next())
{ {
if ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_BIG_WRITE) if ((wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_BIG_WRITE)
{ {
data_alloc->set(wr->location / dsk.data_block_size, true); data_alloc->set(wr->location / dsk.data_block_size, true);
} }
@@ -567,7 +567,7 @@ int disk_tool_t::resize_rebuild_meta()
{ {
for (auto wr = obj->get_writes(); wr; wr = wr->next()) for (auto wr = obj->get_writes(); wr; wr = wr->next())
{ {
if ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_BIG_WRITE) if ((wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_BIG_WRITE)
{ {
if (wr->next() && new_meta_hdr->data_csum_type != 0 && if (wr->next() && new_meta_hdr->data_csum_type != 0 &&
((wr->offset % new_meta_hdr->csum_block_size) || (wr->len % new_meta_hdr->csum_block_size))) ((wr->offset % new_meta_hdr->csum_block_size) || (wr->len % new_meta_hdr->csum_block_size)))
@@ -587,7 +587,7 @@ int disk_tool_t::resize_rebuild_meta()
block_num += data_idx_diff; block_num += data_idx_diff;
wr->location = block_num * dsk.data_block_size; wr->location = block_num * dsk.data_block_size;
} }
else if ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE) else if ((wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE)
{ {
if (new_heap && wr->len > 0) if (new_heap && wr->len > 0)
{ {
@@ -604,8 +604,8 @@ int disk_tool_t::resize_rebuild_meta()
else if (!new_heap) else if (!new_heap)
{ {
fprintf(stderr, "Object %jx:%jx can't be converted to the old format because it contains %s\n", fprintf(stderr, "Object %jx:%jx can't be converted to the old format because it contains %s\n",
obj->inode, obj->stripe, (wr->flags & BS_HEAP_TYPE) == BS_HEAP_TOMBSTONE obj->inode, obj->stripe, (wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_TOMBSTONE
? "a tombstone" : ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_INTENT_WRITE ? "an intent_write entry" : "an unknown entry")); ? "a tombstone" : ((wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_INTENT_WRITE ? "an intent_write entry" : "an unknown entry"));
exit(1); exit(1);
} }
} }
@@ -625,20 +625,20 @@ int disk_tool_t::resize_rebuild_meta()
for (ssize_t i = writes.size()-2; i >= 0; i--) for (ssize_t i = writes.size()-2; i >= 0; i--)
{ {
auto wr = writes[i]; auto wr = writes[i];
assert((wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE || wr->flags == BS_HEAP_BIG_WRITE); assert((wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE || wr->entry_type == BS_HEAP_BIG_WRITE);
uint32_t je_size = dsk.dirty_dyn_size(wr->offset, wr->len) + uint32_t je_size = dsk.dirty_dyn_size(wr->offset, wr->len) +
((wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE ? sizeof(journal_entry_small_write) : sizeof(journal_entry_big_write)); ((wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE ? sizeof(journal_entry_small_write) : sizeof(journal_entry_big_write));
choose_journal_block(je_size); choose_journal_block(je_size);
journal_entry *je = (journal_entry*)(new_journal_ptr + new_journal_in_pos); journal_entry *je = (journal_entry*)(new_journal_ptr + new_journal_in_pos);
je->magic = JOURNAL_MAGIC; je->magic = JOURNAL_MAGIC;
je->type = (wr->flags & BS_HEAP_STABLE) ? JE_SMALL_WRITE_INSTANT : JE_SMALL_WRITE; je->type = (wr->entry_type & BS_HEAP_STABLE) ? JE_SMALL_WRITE_INSTANT : JE_SMALL_WRITE;
je->size = je_size; je->size = je_size;
je->crc32_prev = new_crc32_prev; je->crc32_prev = new_crc32_prev;
je->small_write.oid = (object_id){ .inode = obj->inode, .stripe = obj->stripe }; je->small_write.oid = (object_id){ .inode = obj->inode, .stripe = obj->stripe };
je->small_write.version = wr->version; je->small_write.version = wr->version;
je->small_write.offset = wr->offset; je->small_write.offset = wr->offset;
je->small_write.len = wr->len; je->small_write.len = wr->len;
if ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE) if ((wr->entry_type & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE)
{ {
je->small_write.data_offset = new_journal_data-new_journal_buf; je->small_write.data_offset = new_journal_data-new_journal_buf;
if (je->small_write.data_offset + je->small_write.len > new_journal_len) if (je->small_write.data_offset + je->small_write.len > new_journal_len)
@@ -663,7 +663,7 @@ int disk_tool_t::resize_rebuild_meta()
new_crc32_prev = je->crc32; new_crc32_prev = je->crc32;
} }
// New -> Old // New -> Old
if (writes[writes.size()-1]->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE) if (writes[writes.size()-1]->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE)
{ {
auto big_wr = writes[writes.size()-1]; auto big_wr = writes[writes.size()-1];
uint64_t block_num = big_wr->location / dsk.data_block_size; uint64_t block_num = big_wr->location / dsk.data_block_size;
@@ -696,7 +696,7 @@ int disk_tool_t::resize_rebuild_meta()
// Old -> New // Old -> New
uint8_t wr_buf[new_heap->get_max_write_entry_size()]; uint8_t wr_buf[new_heap->get_max_write_entry_size()];
heap_write_t *wr = (heap_write_t*)wr_buf; heap_write_t *wr = (heap_write_t*)wr_buf;
wr->flags = BS_HEAP_BIG_WRITE|BS_HEAP_STABLE; wr->entry_type = BS_HEAP_BIG_WRITE|BS_HEAP_STABLE;
wr->location = block_num * dsk.data_block_size; wr->location = block_num * dsk.data_block_size;
wr->next_pos = 0; wr->next_pos = 0;
wr->offset = 0; wr->offset = 0;
+24 -24
View File
@@ -70,7 +70,7 @@ int _test_do_big_write(blockstore_heap_t & heap, blockstore_disk_t & dsk, uint64
wr->offset = offset; wr->offset = offset;
wr->len = len; wr->len = len;
wr->location = location; wr->location = location;
wr->flags = BS_HEAP_BIG_WRITE | (stable ? BS_HEAP_STABLE : 0); wr->entry_type = BS_HEAP_BIG_WRITE | (stable ? BS_HEAP_STABLE : 0);
assert(heap.get_max_write_entry_size() >= wr->get_size(&heap)); assert(heap.get_max_write_entry_size() >= wr->get_size(&heap));
assert(wr->get_size(&heap) == sizeof(heap_write_t) + 2*dsk.clean_entry_bitmap_size + (dsk.csum_block_size assert(wr->get_size(&heap) == sizeof(heap_write_t) + 2*dsk.clean_entry_bitmap_size + (dsk.csum_block_size
? dsk.data_block_size/dsk.csum_block_size*4 : 0)); ? dsk.data_block_size/dsk.csum_block_size*4 : 0));
@@ -108,7 +108,7 @@ int _test_do_small_write(blockstore_heap_t & heap, blockstore_disk_t & dsk, uint
wr->offset = offset; wr->offset = offset;
wr->len = len; wr->len = len;
wr->location = location; wr->location = location;
wr->flags = (is_intent ? BS_HEAP_INTENT_WRITE : BS_HEAP_SMALL_WRITE) | (stable ? BS_HEAP_STABLE : 0); wr->entry_type = (is_intent ? BS_HEAP_INTENT_WRITE : BS_HEAP_SMALL_WRITE) | (stable ? BS_HEAP_STABLE : 0);
assert(wr->get_size(&heap) == sizeof(heap_write_t) + dsk.clean_entry_bitmap_size + (dsk.csum_block_size assert(wr->get_size(&heap) == sizeof(heap_write_t) + dsk.clean_entry_bitmap_size + (dsk.csum_block_size
? ((offset+len+dsk.csum_block_size-1)/dsk.csum_block_size - offset/dsk.csum_block_size)*4 : 4)); ? ((offset+len+dsk.csum_block_size-1)/dsk.csum_block_size - offset/dsk.csum_block_size)*4 : 4));
memset(wr->get_ext_bitmap(&heap), 0xff, dsk.clean_entry_bitmap_size); memset(wr->get_ext_bitmap(&heap), 0xff, dsk.clean_entry_bitmap_size);
@@ -192,7 +192,7 @@ void test_mvcc(bool csum)
assert(wr->offset == 0); assert(wr->offset == 0);
assert(wr->len == dsk.data_block_size); assert(wr->len == dsk.data_block_size);
assert(wr->location == 0); assert(wr->location == 0);
assert(wr->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
uint64_t old_size = obj->size + wr->size; uint64_t old_size = obj->size + wr->size;
assert(heap.read_locked_entry(oid, copy_id) == obj); assert(heap.read_locked_entry(oid, copy_id) == obj);
@@ -213,7 +213,7 @@ void test_mvcc(bool csum)
wr = obj->get_writes(); wr = obj->get_writes();
assert(wr->lsn == 3); assert(wr->lsn == 3);
assert(wr->version == 3); assert(wr->version == 3);
assert(wr->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
assert(heap.read_locked_entry(oid, copy_id) != obj); // big_write is MVCCed assert(heap.read_locked_entry(oid, copy_id) != obj); // big_write is MVCCed
obj = heap.read_locked_entry(oid, copy_id); obj = heap.read_locked_entry(oid, copy_id);
@@ -346,7 +346,7 @@ void test_compact(bool csum, bool stable)
heap_object_t *obj = heap.lock_and_read_entry(oid, copy_id); heap_object_t *obj = heap.lock_and_read_entry(oid, copy_id);
assert(obj); assert(obj);
assert(count_writes(obj) == 1); assert(count_writes(obj) == 1);
assert(obj->get_writes()->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(obj->get_writes()->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
uint8_t ref_int_bitmap[dsk.clean_entry_bitmap_size]; uint8_t ref_int_bitmap[dsk.clean_entry_bitmap_size];
memset(ref_int_bitmap, 0, dsk.clean_entry_bitmap_size); memset(ref_int_bitmap, 0, dsk.clean_entry_bitmap_size);
bitmap_set(ref_int_bitmap, 0, 4096, 4096); bitmap_set(ref_int_bitmap, 0, 4096, 4096);
@@ -565,7 +565,7 @@ void test_recheck(bool async, bool csum, bool intent)
assert(wr->offset == 0); assert(wr->offset == 0);
assert(wr->len == dsk.data_block_size); assert(wr->len == dsk.data_block_size);
assert(wr->location == 0x20000); assert(wr->location == 0x20000);
assert(wr->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
// read object 2 - both writes should be present // read object 2 - both writes should be present
oid = { .inode = INODE_WITH_POOL(1, 2), .stripe = 0 }; oid = { .inode = INODE_WITH_POOL(1, 2), .stripe = 0 };
@@ -578,7 +578,7 @@ void test_recheck(bool async, bool csum, bool intent)
assert(wr->offset == 8192); assert(wr->offset == 8192);
assert(wr->len == 12*1024); assert(wr->len == 12*1024);
assert(wr->location == 24*1024); assert(wr->location == 24*1024);
assert(wr->flags == BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE);
} }
printf("OK test_recheck %s %s %s\n", async ? "async" : "sync", csum ? "csum" : "no_csum", intent ? "intent" : "buffered"); printf("OK test_recheck %s %s %s\n", async ? "async" : "sync", csum ? "csum" : "no_csum", intent ? "intent" : "buffered");
@@ -618,14 +618,14 @@ void test_corruption()
wr->offset = 0; wr->offset = 0;
wr->len = 0; wr->len = 0;
wr->location = 0; wr->location = 0;
wr->flags = BS_HEAP_TOMBSTONE|BS_HEAP_STABLE; wr->entry_type = BS_HEAP_TOMBSTONE|BS_HEAP_STABLE;
assert(!wr->get_checksums(&heap)); assert(!wr->get_checksums(&heap));
res = heap.post_write(oid, wr, NULL, NULL); res = heap.post_write(oid, wr, NULL, NULL);
assert(res == 0); assert(res == 0);
// try to do a small_write over a tombstone to fail // try to do a small_write over a tombstone to fail
wr->version = 3; wr->version = 3;
wr->flags = BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE; wr->entry_type = BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE;
res = heap.post_write(oid, wr, NULL, NULL); res = heap.post_write(oid, wr, NULL, NULL);
assert(res == EINVAL); assert(res == EINVAL);
@@ -657,7 +657,7 @@ void test_corruption()
assert(count_writes(obj) == 1); assert(count_writes(obj) == 1);
heap_write_t *wr = obj->get_writes(); heap_write_t *wr = obj->get_writes();
assert(wr->location == 0x40000); assert(wr->location == 0x40000);
assert(wr->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
// object 3 should be present // object 3 should be present
oid = { .inode = INODE_WITH_POOL(1, 1), .stripe = 0x40000 }; oid = { .inode = INODE_WITH_POOL(1, 1), .stripe = 0x40000 };
@@ -666,7 +666,7 @@ void test_corruption()
assert(count_writes(obj) == 1); assert(count_writes(obj) == 1);
wr = obj->get_writes(); wr = obj->get_writes();
assert(wr->location == 0x60000); assert(wr->location == 0x60000);
assert(wr->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
// object 4 should be a tombstone // object 4 should be a tombstone
oid = { .inode = INODE_WITH_POOL(1, 1), .stripe = 0x60000 }; oid = { .inode = INODE_WITH_POOL(1, 1), .stripe = 0x60000 };
@@ -674,7 +674,7 @@ void test_corruption()
assert(obj); assert(obj);
assert(count_writes(obj) == 1); assert(count_writes(obj) == 1);
wr = obj->get_writes(); wr = obj->get_writes();
assert(wr->flags == BS_HEAP_TOMBSTONE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_TOMBSTONE|BS_HEAP_STABLE);
} }
printf("OK test_corruption\n"); printf("OK test_corruption\n");
@@ -742,11 +742,11 @@ void test_full_overwrite(bool stable)
heap_write_t *wr = obj->get_writes(); heap_write_t *wr = obj->get_writes();
assert(wr->version == 4); assert(wr->version == 4);
assert(wr->location == 20480); assert(wr->location == 20480);
assert(wr->flags == BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE);
wr = wr->next(); wr = wr->next();
assert(wr->version == 3); assert(wr->version == 3);
assert(wr->location == 0x40000); assert(wr->location == 0x40000);
assert(wr->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
// check that the data block 0x20000 is freed and 0x40000 is used // check that the data block 0x20000 is freed and 0x40000 is used
assert(!heap.is_data_used(0x20000)); assert(!heap.is_data_used(0x20000));
@@ -849,7 +849,7 @@ void _test_invalid_data_setup(blockstore_disk_t & dsk, std::vector<uint8_t> & bu
wr->next_pos = 0; wr->next_pos = 0;
wr->lsn = 1; wr->lsn = 1;
wr->version = 1; wr->version = 1;
wr->flags = BS_HEAP_TOMBSTONE; wr->entry_type = BS_HEAP_TOMBSTONE;
wr->size = sizeof(heap_write_t); wr->size = sizeof(heap_write_t);
obj->crc32c = obj->calc_crc32c(); obj->crc32c = obj->calc_crc32c();
@@ -861,7 +861,7 @@ void _test_invalid_data_setup(blockstore_disk_t & dsk, std::vector<uint8_t> & bu
wr = obj->get_writes(); wr = obj->get_writes();
wr->lsn = 1; wr->lsn = 1;
wr->version = 1; wr->version = 1;
wr->flags = BS_HEAP_TOMBSTONE; wr->entry_type = BS_HEAP_TOMBSTONE;
wr->size = sizeof(heap_write_t); wr->size = sizeof(heap_write_t);
obj->crc32c = obj->calc_crc32c(); obj->crc32c = obj->calc_crc32c();
@@ -872,7 +872,7 @@ void _test_invalid_data_setup(blockstore_disk_t & dsk, std::vector<uint8_t> & bu
wr = obj->get_writes(); wr = obj->get_writes();
wr->lsn = 2; wr->lsn = 2;
wr->version = 1; wr->version = 1;
wr->flags = BS_HEAP_TOMBSTONE; wr->entry_type = BS_HEAP_TOMBSTONE;
wr->size = sizeof(heap_write_t); wr->size = sizeof(heap_write_t);
obj->crc32c = obj->calc_crc32c(); obj->crc32c = obj->calc_crc32c();
} }
@@ -1180,11 +1180,11 @@ void test_rollback()
assert(wr->version == 2); assert(wr->version == 2);
assert(wr->location == 16384); assert(wr->location == 16384);
assert(wr->len == 4096); assert(wr->len == 4096);
assert(wr->flags == BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE);
wr = wr->next(); wr = wr->next();
assert(wr->version == 1); assert(wr->version == 1);
assert(wr->location == 0x20000); assert(wr->location == 0x20000);
assert(wr->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
assert(heap.is_data_used(0x20000)); assert(heap.is_data_used(0x20000));
assert(!heap.is_data_used(0x40000)); assert(!heap.is_data_used(0x40000));
@@ -1404,7 +1404,7 @@ void test_duplicate()
heap_write_t *wr = obj->get_writes(); heap_write_t *wr = obj->get_writes();
assert(wr->version == 2); assert(wr->version == 2);
assert(wr->location == 0x40000); assert(wr->location == 0x40000);
assert(wr->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
assert(heap.get_meta_block_used_space(0) == 0); assert(heap.get_meta_block_used_space(0) == 0);
assert(heap.get_meta_block_used_space(1) == obj->size+wr->size); assert(heap.get_meta_block_used_space(1) == obj->size+wr->size);
@@ -1428,7 +1428,7 @@ void test_duplicate()
heap_write_t *wr = obj->get_writes(); heap_write_t *wr = obj->get_writes();
assert(wr->version == 2); assert(wr->version == 2);
assert(wr->location == 0x40000); assert(wr->location == 0x40000);
assert(wr->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
assert(heap.get_meta_block_used_space(0) == 0); assert(heap.get_meta_block_used_space(0) == 0);
assert(heap.get_meta_block_used_space(1) == obj->size+wr->size); assert(heap.get_meta_block_used_space(1) == obj->size+wr->size);
@@ -1500,21 +1500,21 @@ void test_autocompact(bool csum)
assert(wr->offset == 7*4096); assert(wr->offset == 7*4096);
assert(wr->len == 4096); assert(wr->len == 4096);
assert(wr->location == 7*4096); assert(wr->location == 7*4096);
assert(wr->flags == BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE);
wr = wr->next(); wr = wr->next();
assert(wr->lsn == 4); assert(wr->lsn == 4);
assert(wr->version == 4); assert(wr->version == 4);
assert(wr->offset == 5*4096); assert(wr->offset == 5*4096);
assert(wr->len == 4096); assert(wr->len == 4096);
assert(wr->location == 6*4096); assert(wr->location == 6*4096);
assert(wr->flags == BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_SMALL_WRITE|BS_HEAP_STABLE);
wr = wr->next(); wr = wr->next();
assert(wr->lsn == 3); assert(wr->lsn == 3);
assert(wr->version == 3); assert(wr->version == 3);
assert(wr->offset == 0); assert(wr->offset == 0);
assert(wr->len == dsk.data_block_size); assert(wr->len == dsk.data_block_size);
assert(wr->location == 0x20000); assert(wr->location == 0x20000);
assert(wr->flags == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE); assert(wr->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
// check that blocks are auto-freed // check that blocks are auto-freed
assert(heap.is_data_used(0x20000)); assert(heap.is_data_used(0x20000));