static int init_child(struct dm_btree_info *info, struct dm_btree_value_type *vt, struct btree_node *parent, unsigned index, struct child *result) { int r, inc; dm_block_t root; result->index = index; root = value64(parent, index); r = dm_tm_shadow_block(info->tm, root, &btree_node_validator, &result->block, &inc); if (r) return r; result->n = dm_block_data(result->block); if (inc) inc_children(info->tm, result->n, vt); *((__le64 *) value_ptr(parent, index)) = cpu_to_le64(dm_block_location(result->block)); return 0; }
static int bn_shadow(struct dm_btree_info *info, dm_block_t orig, struct dm_btree_value_type *vt, struct dm_block **result) { int r, inc; r = dm_tm_shadow_block(info->tm, orig, &btree_node_validator, result, &inc); if (!r && inc) inc_children(info->tm, dm_block_data(*result), vt); return r; }
/* * Looks up an array block in the btree. Then shadows it, and updates the * btree to point to this new shadow. 'root' is an input/output parameter * for both the current root block, and the new one. */ static int shadow_ablock(struct dm_array_info *info, dm_block_t *root, unsigned index, struct dm_block **block, struct array_block **ab) { int r, inc; uint64_t key = index; dm_block_t b; __le64 block_le; /* * lookup */ r = dm_btree_lookup(&info->btree_info, *root, &key, &block_le); if (r) return r; b = le64_to_cpu(block_le); /* * shadow */ r = dm_tm_shadow_block(info->btree_info.tm, b, &array_validator, block, &inc); if (r) return r; *ab = dm_block_data(*block); if (inc) inc_ablock_entries(info, *ab); /* * Reinsert. * * The shadow op will often be a noop. Only insert if it really * copied data. */ if (dm_block_location(*block) != b) { /* * dm_tm_shadow_block will have already decremented the old * block, but it is still referenced by the btree. We * increment to stop the insert decrementing it below zero * when overwriting the old value. */ dm_tm_inc(info->btree_info.tm, b); r = insert_ablock(info, index, *block, root); } return r; }
/* * Looks up an array block in the btree. Then shadows it, and updates the * btree to point to this new shadow. 'root' is an input/output parameter * for both the current root block, and the new one. */ static int shadow_ablock(struct dm_array_info *info, dm_block_t *root, unsigned index, struct dm_block **block, struct array_block **ab) { int r, inc; uint64_t key = index; dm_block_t b; __le64 block_le; /* * lookup */ r = dm_btree_lookup(&info->btree_info, *root, &key, &block_le); if (r) return r; b = le64_to_cpu(block_le); /* * shadow */ r = dm_tm_shadow_block(info->btree_info.tm, b, &array_validator, block, &inc); if (r) return r; *ab = dm_block_data(*block); if (inc) inc_ablock_entries(info, *ab); /* * Reinsert. * * The shadow op will often be a noop. Only insert if it really * copied data. */ if (dm_block_location(*block) != b) r = insert_ablock(info, index, *block, root); return r; }