11 #include <linux/list.h>
12 #include <linux/slab.h>
15 #define DM_MSG_PREFIX "space map metadata"
33 #define MAX_RECURSIVE_ALLOCATIONS 1024
64 DMERR(
"too many recursive allocations");
106 DMERR(
"lost track of recursion depth");
130 static int combine_errors(
int r1,
int r2)
149 DMERR(
"doesn't support extend");
157 *count = smm->
ll.nr_blocks;
166 *count = smm->
old_ll.nr_blocks - smm->
old_ll.nr_allocated -
177 unsigned adjustment = 0;
204 *result += adjustment;
209 static int sm_metadata_count_is_more_than_one(
struct dm_space_map *sm,
212 int r,
i, adjustment = 0;
237 if (adjustment > 1) {
252 *result = rc + adjustment > 1;
265 DMERR(
"cannot recurse set_count()");
273 return combine_errors(r, r2);
290 return combine_errors(r, r2);
307 return combine_errors(r, r2);
333 return combine_errors(r, r2);
338 int r = sm_metadata_new_block_(sm, b);
340 DMERR(
"out of metadata space");
360 static int sm_metadata_root_size(
struct dm_space_map *sm,
size_t *result)
367 static int sm_metadata_copy_root(
struct dm_space_map *sm,
void *where_le,
size_t max)
375 root_le.ref_count_root =
cpu_to_le64(smm->
ll.ref_count_root);
377 if (max <
sizeof(root_le))
380 memcpy(where_le, &root_le,
sizeof(root_le));
386 .destroy = sm_metadata_destroy,
387 .extend = sm_metadata_extend,
388 .get_nr_blocks = sm_metadata_get_nr_blocks,
389 .get_nr_free = sm_metadata_get_nr_free,
390 .get_count = sm_metadata_get_count,
391 .count_is_more_than_one = sm_metadata_count_is_more_than_one,
392 .set_count = sm_metadata_set_count,
393 .inc_block = sm_metadata_inc_block,
394 .dec_block = sm_metadata_dec_block,
395 .new_block = sm_metadata_new_block,
396 .commit = sm_metadata_commit,
397 .root_size = sm_metadata_root_size,
398 .copy_root = sm_metadata_copy_root
407 static void sm_bootstrap_destroy(
struct dm_space_map *sm)
413 DMERR(
"boostrap doesn't support extend");
422 return smm->
ll.nr_blocks;
429 *count = smm->
ll.nr_blocks - smm->
begin;
439 return b < smm->
begin ? 1 : 0;
442 static int sm_bootstrap_count_is_more_than_one(
struct dm_space_map *sm,
453 DMERR(
"boostrap doesn't support set_count");
465 if (smm->
begin == smm->
ll.nr_blocks)
477 return add_bop(smm,
BOP_INC, b);
484 return add_bop(smm,
BOP_DEC, b);
492 static int sm_bootstrap_root_size(
struct dm_space_map *sm,
size_t *result)
494 DMERR(
"boostrap doesn't support root_size");
499 static int sm_bootstrap_copy_root(
struct dm_space_map *sm,
void *where,
502 DMERR(
"boostrap doesn't support copy_root");
508 .destroy = sm_bootstrap_destroy,
509 .extend = sm_bootstrap_extend,
510 .get_nr_blocks = sm_bootstrap_get_nr_blocks,
511 .get_nr_free = sm_bootstrap_get_nr_free,
512 .get_count = sm_bootstrap_get_count,
513 .count_is_more_than_one = sm_bootstrap_count_is_more_than_one,
514 .set_count = sm_bootstrap_set_count,
515 .inc_block = sm_bootstrap_inc_block,
516 .dec_block = sm_bootstrap_dec_block,
517 .new_block = sm_bootstrap_new_block,
518 .commit = sm_bootstrap_commit,
519 .root_size = sm_bootstrap_root_size,
520 .copy_root = sm_bootstrap_copy_root
548 smm->
begin = superblock + 1;
553 memcpy(&smm->
sm, &bootstrap_ops,
sizeof(smm->
sm));
569 for (i = superblock; !r && i < smm->
begin; i++)
575 return sm_metadata_commit(sm);
580 void *root_le,
size_t len)