static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks) { int r, i; enum allocation_event ev; struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); dm_block_t old_len = smm->ll.nr_blocks; /* * Flick into a mode where all blocks get allocated in the new area. */ smm->begin = old_len; memcpy(sm, &bootstrap_ops, sizeof(*sm)); /* * Extend. */ r = sm_ll_extend(&smm->ll, extra_blocks); if (r) goto out; /* * We repeatedly increment then commit until the commit doesn't * allocate any new blocks. */ do { for (i = old_len; !r && i < smm->begin; i++) { r = sm_ll_inc(&smm->ll, i, &ev); if (r) goto out; } old_len = smm->begin; r = apply_bops(smm); if (r) { DMERR("%s: apply_bops failed", __func__); goto out; } r = sm_ll_commit(&smm->ll); if (r) goto out; } while (old_len != smm->begin); out: /* * Switch back to normal behaviour. */ memcpy(sm, &ops, sizeof(*sm)); return r; }
static int sm_metadata_commit(struct dm_space_map *sm) { int r; struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); r = sm_ll_commit(&smm->ll); if (r) return r; memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll)); smm->begin = 0; smm->allocated_this_transaction = 0; return 0; }