static void node_mark_dirty(Oc_wu *wu_p, Oc_bpt_node *node_p, bool multi_refs) { if (!multi_refs) { uint64 new_addr; Oc_bpt_test_node *tnode_p; /* Try to emulate what the mark-dirty operation actually does. * Move the page from its current disk-address to a new one. * * There is one exception: never move the root node. */ if (oc_bpt_nd_is_root(NULL, node_p)) return; if (1) { if (oc_bpt_test_utl_random_number(4) != 0) return; // This is a non-root node, move it new_addr = oc_bpt_test_fs_alloc(); oc_bpt_test_fs_dealloc(node_p->disk_addr); tnode_p = vd_node_lookup(node_p->disk_addr); vd_node_remove(node_p->disk_addr); node_p->disk_addr = new_addr; vd_node_insert(tnode_p); } } else { /* This page is referenced by multiple clones. We * can't move it; we need to leave the old page where * it was. */ Oc_bpt_test_node *tnode_p, *old_tnode_p;; tnode_p = vd_node_lookup(node_p->disk_addr); old_tnode_p = tnode_clone(tnode_p); // move the page to a new address vd_node_remove(tnode_p->node.disk_addr); tnode_p->node.disk_addr = oc_bpt_test_fs_alloc(); vd_node_insert(tnode_p); // Place a copy of the page in the old disk-address vd_node_insert(old_tnode_p); // reduce the FS ref-count on the old address. oc_bpt_test_fs_dealloc(old_tnode_p->node.disk_addr); } }
void oc_xt_test_nd_mark_dirty(Oc_wu *wu_p, Oc_xt_node *node_p) { Oc_xt_test_node *tnode_p; uint64 new_addr; if (random_choose(4) != 0) return; /* Try to emulate what the mark-dirty operation actually does. * Move the page from its current disk-address to a new one. * * There is one exception: never move the root node. */ if (oc_xt_nd_is_root(NULL, node_p)) return; // This is a non-root node, move it new_addr = fs_alloc(); // printf("po_id=%d, moving address %Lu->%Lu\n", wu_p->po_id, node_p->lba, new_addr); // fflush(stdout); tnode_p = vd_node_lookup(node_p->disk_addr); vd_node_remove(node_p->disk_addr); node_p->disk_addr = new_addr; vd_node_insert(tnode_p); }
void oc_xt_test_nd_dealloc(Oc_wu *wu_p, uint64 addr) { Oc_xt_test_node *tnode_p; char *data; if (wu_p->po_id != 0) if (random_choose(2) == 0) oc_crt_yield_task(); // extract the node fromt the table prior to removal tnode_p = vd_node_lookup(addr); // remove the node from the virtual-disk vd_node_remove(addr); oc_utl_assert(tnode_p); oc_utl_assert(tnode_p->node.data); oc_utl_assert(tnode_p->magic == MAGIC); // mess up the node so that errors will occur on illegal accesses tnode_p->magic = -1; data = tnode_p->node.data; tnode_p->node.data = NULL; tnode_p->node.lock.counter = 100; tnode_p->node.disk_addr = 0; free(data); free(tnode_p); }
static void node_dealloc(Oc_wu *wu_p, uint64 addr) { if (wu_p->po_id != 0) if (oc_bpt_test_utl_random_number(2) == 0) oc_crt_yield_task(); oc_bpt_test_fs_dealloc(addr); if (oc_bpt_test_fs_get_refcount(wu_p, addr) == 0) { // Free the block only if it's ref-count is zero Oc_bpt_test_node *tnode_p; char *data; // extract the node from the table prior to removal tnode_p = vd_node_lookup(addr); // remove the node from the virtual-disk vd_node_remove(addr); oc_utl_assert(tnode_p); oc_utl_assert(tnode_p->node.data); oc_utl_assert(tnode_p->magic == MAGIC); // mess up the node so that errors will occur on illegal accesses tnode_p->magic = -1; data = tnode_p->node.data; tnode_p->node.data = NULL; tnode_p->node.disk_addr = 0; free(data); free(tnode_p); } }