/* * These are the value_type functions for the btree elements, which point * to array blocks. */ static void block_inc(void *context, const void *value) { __le64 block_le; struct dm_array_info *info = context; memcpy(&block_le, value, sizeof(block_le)); dm_tm_inc(info->btree_info.tm, le64_to_cpu(block_le)); }
void inc_children(struct dm_transaction_manager *tm, struct btree_node *n, struct dm_btree_value_type *vt) { unsigned i; uint32_t nr_entries = le32_to_cpu(n->header.nr_entries); if (le32_to_cpu(n->header.flags) & INTERNAL_NODE) for (i = 0; i < nr_entries; i++) dm_tm_inc(tm, value64(n, i)); else if (vt->inc) for (i = 0; i < nr_entries; i++) vt->inc(vt->context, value_ptr(n, i)); }
/* * 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; }