1 /* 2 * Copyright (C) 2011 Red Hat, Inc. 3 * 4 * This file is released under the GPL. 5 */ 6 7 #include "dm-space-map.h" 8 #include "dm-space-map-common.h" 9 #include "dm-space-map-metadata.h" 10 11 #include <linux/list.h> 12 #include <linux/slab.h> 13 #include <linux/device-mapper.h> 14 15 #define DM_MSG_PREFIX "space map metadata" 16 17 /*----------------------------------------------------------------*/ 18 19 /* 20 * An edge triggered threshold. 21 */ 22 struct threshold { 23 bool threshold_set; 24 bool value_set; 25 dm_block_t threshold; 26 dm_block_t current_value; 27 dm_sm_threshold_fn fn; 28 void *context; 29 }; 30 31 static void threshold_init(struct threshold *t) 32 { 33 t->threshold_set = false; 34 t->value_set = false; 35 } 36 37 static void set_threshold(struct threshold *t, dm_block_t value, 38 dm_sm_threshold_fn fn, void *context) 39 { 40 t->threshold_set = true; 41 t->threshold = value; 42 t->fn = fn; 43 t->context = context; 44 } 45 46 static bool below_threshold(struct threshold *t, dm_block_t value) 47 { 48 return t->threshold_set && value <= t->threshold; 49 } 50 51 static bool threshold_already_triggered(struct threshold *t) 52 { 53 return t->value_set && below_threshold(t, t->current_value); 54 } 55 56 static void check_threshold(struct threshold *t, dm_block_t value) 57 { 58 if (below_threshold(t, value) && 59 !threshold_already_triggered(t)) 60 t->fn(t->context); 61 62 t->value_set = true; 63 t->current_value = value; 64 } 65 66 /*----------------------------------------------------------------*/ 67 68 /* 69 * Space map interface. 70 * 71 * The low level disk format is written using the standard btree and 72 * transaction manager. This means that performing disk operations may 73 * cause us to recurse into the space map in order to allocate new blocks. 74 * For this reason we have a pool of pre-allocated blocks large enough to 75 * service any metadata_ll_disk operation. 76 */ 77 78 /* 79 * FIXME: we should calculate this based on the size of the device. 80 * Only the metadata space map needs this functionality. 81 */ 82 #define MAX_RECURSIVE_ALLOCATIONS 1024 83 84 enum block_op_type { 85 BOP_INC, 86 BOP_DEC 87 }; 88 89 struct block_op { 90 enum block_op_type type; 91 dm_block_t block; 92 }; 93 94 struct sm_metadata { 95 struct dm_space_map sm; 96 97 struct ll_disk ll; 98 struct ll_disk old_ll; 99 100 dm_block_t begin; 101 102 unsigned recursion_count; 103 unsigned allocated_this_transaction; 104 unsigned nr_uncommitted; 105 struct block_op uncommitted[MAX_RECURSIVE_ALLOCATIONS]; 106 107 struct threshold threshold; 108 }; 109 110 static int add_bop(struct sm_metadata *smm, enum block_op_type type, dm_block_t b) 111 { 112 struct block_op *op; 113 114 if (smm->nr_uncommitted == MAX_RECURSIVE_ALLOCATIONS) { 115 DMERR("too many recursive allocations"); 116 return -ENOMEM; 117 } 118 119 op = smm->uncommitted + smm->nr_uncommitted++; 120 op->type = type; 121 op->block = b; 122 123 return 0; 124 } 125 126 static int commit_bop(struct sm_metadata *smm, struct block_op *op) 127 { 128 int r = 0; 129 enum allocation_event ev; 130 131 switch (op->type) { 132 case BOP_INC: 133 r = sm_ll_inc(&smm->ll, op->block, &ev); 134 break; 135 136 case BOP_DEC: 137 r = sm_ll_dec(&smm->ll, op->block, &ev); 138 break; 139 } 140 141 return r; 142 } 143 144 static void in(struct sm_metadata *smm) 145 { 146 smm->recursion_count++; 147 } 148 149 static int out(struct sm_metadata *smm) 150 { 151 int r = 0; 152 153 /* 154 * If we're not recursing then very bad things are happening. 155 */ 156 if (!smm->recursion_count) { 157 DMERR("lost track of recursion depth"); 158 return -ENOMEM; 159 } 160 161 if (smm->recursion_count == 1 && smm->nr_uncommitted) { 162 while (smm->nr_uncommitted && !r) { 163 smm->nr_uncommitted--; 164 r = commit_bop(smm, smm->uncommitted + 165 smm->nr_uncommitted); 166 if (r) 167 break; 168 } 169 } 170 171 smm->recursion_count--; 172 173 return r; 174 } 175 176 /* 177 * When using the out() function above, we often want to combine an error 178 * code for the operation run in the recursive context with that from 179 * out(). 180 */ 181 static int combine_errors(int r1, int r2) 182 { 183 return r1 ? r1 : r2; 184 } 185 186 static int recursing(struct sm_metadata *smm) 187 { 188 return smm->recursion_count; 189 } 190 191 static void sm_metadata_destroy(struct dm_space_map *sm) 192 { 193 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 194 195 kfree(smm); 196 } 197 198 static int sm_metadata_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count) 199 { 200 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 201 202 *count = smm->ll.nr_blocks; 203 204 return 0; 205 } 206 207 static int sm_metadata_get_nr_free(struct dm_space_map *sm, dm_block_t *count) 208 { 209 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 210 211 *count = smm->old_ll.nr_blocks - smm->old_ll.nr_allocated - 212 smm->allocated_this_transaction; 213 214 return 0; 215 } 216 217 static int sm_metadata_get_count(struct dm_space_map *sm, dm_block_t b, 218 uint32_t *result) 219 { 220 int r, i; 221 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 222 unsigned adjustment = 0; 223 224 /* 225 * We may have some uncommitted adjustments to add. This list 226 * should always be really short. 227 */ 228 for (i = 0; i < smm->nr_uncommitted; i++) { 229 struct block_op *op = smm->uncommitted + i; 230 231 if (op->block != b) 232 continue; 233 234 switch (op->type) { 235 case BOP_INC: 236 adjustment++; 237 break; 238 239 case BOP_DEC: 240 adjustment--; 241 break; 242 } 243 } 244 245 r = sm_ll_lookup(&smm->ll, b, result); 246 if (r) 247 return r; 248 249 *result += adjustment; 250 251 return 0; 252 } 253 254 static int sm_metadata_count_is_more_than_one(struct dm_space_map *sm, 255 dm_block_t b, int *result) 256 { 257 int r, i, adjustment = 0; 258 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 259 uint32_t rc; 260 261 /* 262 * We may have some uncommitted adjustments to add. This list 263 * should always be really short. 264 */ 265 for (i = 0; i < smm->nr_uncommitted; i++) { 266 struct block_op *op = smm->uncommitted + i; 267 268 if (op->block != b) 269 continue; 270 271 switch (op->type) { 272 case BOP_INC: 273 adjustment++; 274 break; 275 276 case BOP_DEC: 277 adjustment--; 278 break; 279 } 280 } 281 282 if (adjustment > 1) { 283 *result = 1; 284 return 0; 285 } 286 287 r = sm_ll_lookup_bitmap(&smm->ll, b, &rc); 288 if (r) 289 return r; 290 291 if (rc == 3) 292 /* 293 * We err on the side of caution, and always return true. 294 */ 295 *result = 1; 296 else 297 *result = rc + adjustment > 1; 298 299 return 0; 300 } 301 302 static int sm_metadata_set_count(struct dm_space_map *sm, dm_block_t b, 303 uint32_t count) 304 { 305 int r, r2; 306 enum allocation_event ev; 307 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 308 309 if (smm->recursion_count) { 310 DMERR("cannot recurse set_count()"); 311 return -EINVAL; 312 } 313 314 in(smm); 315 r = sm_ll_insert(&smm->ll, b, count, &ev); 316 r2 = out(smm); 317 318 return combine_errors(r, r2); 319 } 320 321 static int sm_metadata_inc_block(struct dm_space_map *sm, dm_block_t b) 322 { 323 int r, r2 = 0; 324 enum allocation_event ev; 325 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 326 327 if (recursing(smm)) 328 r = add_bop(smm, BOP_INC, b); 329 else { 330 in(smm); 331 r = sm_ll_inc(&smm->ll, b, &ev); 332 r2 = out(smm); 333 } 334 335 return combine_errors(r, r2); 336 } 337 338 static int sm_metadata_dec_block(struct dm_space_map *sm, dm_block_t b) 339 { 340 int r, r2 = 0; 341 enum allocation_event ev; 342 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 343 344 if (recursing(smm)) 345 r = add_bop(smm, BOP_DEC, b); 346 else { 347 in(smm); 348 r = sm_ll_dec(&smm->ll, b, &ev); 349 r2 = out(smm); 350 } 351 352 return combine_errors(r, r2); 353 } 354 355 static int sm_metadata_new_block_(struct dm_space_map *sm, dm_block_t *b) 356 { 357 int r, r2 = 0; 358 enum allocation_event ev; 359 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 360 361 r = sm_ll_find_free_block(&smm->old_ll, smm->begin, smm->old_ll.nr_blocks, b); 362 if (r) 363 return r; 364 365 smm->begin = *b + 1; 366 367 if (recursing(smm)) 368 r = add_bop(smm, BOP_INC, *b); 369 else { 370 in(smm); 371 r = sm_ll_inc(&smm->ll, *b, &ev); 372 r2 = out(smm); 373 } 374 375 if (!r) 376 smm->allocated_this_transaction++; 377 378 return combine_errors(r, r2); 379 } 380 381 static int sm_metadata_new_block(struct dm_space_map *sm, dm_block_t *b) 382 { 383 dm_block_t count; 384 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 385 386 int r = sm_metadata_new_block_(sm, b); 387 if (r) { 388 DMERR("unable to allocate new metadata block"); 389 return r; 390 } 391 392 r = sm_metadata_get_nr_free(sm, &count); 393 if (r) { 394 DMERR("couldn't get free block count"); 395 return r; 396 } 397 398 check_threshold(&smm->threshold, count); 399 400 return r; 401 } 402 403 static int sm_metadata_commit(struct dm_space_map *sm) 404 { 405 int r; 406 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 407 408 r = sm_ll_commit(&smm->ll); 409 if (r) 410 return r; 411 412 memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll)); 413 smm->begin = 0; 414 smm->allocated_this_transaction = 0; 415 416 return 0; 417 } 418 419 static int sm_metadata_register_threshold_callback(struct dm_space_map *sm, 420 dm_block_t threshold, 421 dm_sm_threshold_fn fn, 422 void *context) 423 { 424 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 425 426 set_threshold(&smm->threshold, threshold, fn, context); 427 428 return 0; 429 } 430 431 static int sm_metadata_root_size(struct dm_space_map *sm, size_t *result) 432 { 433 *result = sizeof(struct disk_sm_root); 434 435 return 0; 436 } 437 438 static int sm_metadata_copy_root(struct dm_space_map *sm, void *where_le, size_t max) 439 { 440 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 441 struct disk_sm_root root_le; 442 443 root_le.nr_blocks = cpu_to_le64(smm->ll.nr_blocks); 444 root_le.nr_allocated = cpu_to_le64(smm->ll.nr_allocated); 445 root_le.bitmap_root = cpu_to_le64(smm->ll.bitmap_root); 446 root_le.ref_count_root = cpu_to_le64(smm->ll.ref_count_root); 447 448 if (max < sizeof(root_le)) 449 return -ENOSPC; 450 451 memcpy(where_le, &root_le, sizeof(root_le)); 452 453 return 0; 454 } 455 456 static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks); 457 458 static struct dm_space_map ops = { 459 .destroy = sm_metadata_destroy, 460 .extend = sm_metadata_extend, 461 .get_nr_blocks = sm_metadata_get_nr_blocks, 462 .get_nr_free = sm_metadata_get_nr_free, 463 .get_count = sm_metadata_get_count, 464 .count_is_more_than_one = sm_metadata_count_is_more_than_one, 465 .set_count = sm_metadata_set_count, 466 .inc_block = sm_metadata_inc_block, 467 .dec_block = sm_metadata_dec_block, 468 .new_block = sm_metadata_new_block, 469 .commit = sm_metadata_commit, 470 .root_size = sm_metadata_root_size, 471 .copy_root = sm_metadata_copy_root, 472 .register_threshold_callback = sm_metadata_register_threshold_callback 473 }; 474 475 /*----------------------------------------------------------------*/ 476 477 /* 478 * When a new space map is created that manages its own space. We use 479 * this tiny bootstrap allocator. 480 */ 481 static void sm_bootstrap_destroy(struct dm_space_map *sm) 482 { 483 } 484 485 static int sm_bootstrap_extend(struct dm_space_map *sm, dm_block_t extra_blocks) 486 { 487 DMERR("bootstrap doesn't support extend"); 488 489 return -EINVAL; 490 } 491 492 static int sm_bootstrap_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count) 493 { 494 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 495 496 return smm->ll.nr_blocks; 497 } 498 499 static int sm_bootstrap_get_nr_free(struct dm_space_map *sm, dm_block_t *count) 500 { 501 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 502 503 *count = smm->ll.nr_blocks - smm->begin; 504 505 return 0; 506 } 507 508 static int sm_bootstrap_get_count(struct dm_space_map *sm, dm_block_t b, 509 uint32_t *result) 510 { 511 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 512 513 return b < smm->begin ? 1 : 0; 514 } 515 516 static int sm_bootstrap_count_is_more_than_one(struct dm_space_map *sm, 517 dm_block_t b, int *result) 518 { 519 *result = 0; 520 521 return 0; 522 } 523 524 static int sm_bootstrap_set_count(struct dm_space_map *sm, dm_block_t b, 525 uint32_t count) 526 { 527 DMERR("bootstrap doesn't support set_count"); 528 529 return -EINVAL; 530 } 531 532 static int sm_bootstrap_new_block(struct dm_space_map *sm, dm_block_t *b) 533 { 534 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 535 536 /* 537 * We know the entire device is unused. 538 */ 539 if (smm->begin == smm->ll.nr_blocks) 540 return -ENOSPC; 541 542 *b = smm->begin++; 543 544 return 0; 545 } 546 547 static int sm_bootstrap_inc_block(struct dm_space_map *sm, dm_block_t b) 548 { 549 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 550 551 return add_bop(smm, BOP_INC, b); 552 } 553 554 static int sm_bootstrap_dec_block(struct dm_space_map *sm, dm_block_t b) 555 { 556 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 557 558 return add_bop(smm, BOP_DEC, b); 559 } 560 561 static int sm_bootstrap_commit(struct dm_space_map *sm) 562 { 563 return 0; 564 } 565 566 static int sm_bootstrap_root_size(struct dm_space_map *sm, size_t *result) 567 { 568 DMERR("bootstrap doesn't support root_size"); 569 570 return -EINVAL; 571 } 572 573 static int sm_bootstrap_copy_root(struct dm_space_map *sm, void *where, 574 size_t max) 575 { 576 DMERR("bootstrap doesn't support copy_root"); 577 578 return -EINVAL; 579 } 580 581 static struct dm_space_map bootstrap_ops = { 582 .destroy = sm_bootstrap_destroy, 583 .extend = sm_bootstrap_extend, 584 .get_nr_blocks = sm_bootstrap_get_nr_blocks, 585 .get_nr_free = sm_bootstrap_get_nr_free, 586 .get_count = sm_bootstrap_get_count, 587 .count_is_more_than_one = sm_bootstrap_count_is_more_than_one, 588 .set_count = sm_bootstrap_set_count, 589 .inc_block = sm_bootstrap_inc_block, 590 .dec_block = sm_bootstrap_dec_block, 591 .new_block = sm_bootstrap_new_block, 592 .commit = sm_bootstrap_commit, 593 .root_size = sm_bootstrap_root_size, 594 .copy_root = sm_bootstrap_copy_root, 595 .register_threshold_callback = NULL 596 }; 597 598 /*----------------------------------------------------------------*/ 599 600 static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks) 601 { 602 int r, i; 603 enum allocation_event ev; 604 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 605 dm_block_t old_len = smm->ll.nr_blocks; 606 607 /* 608 * Flick into a mode where all blocks get allocated in the new area. 609 */ 610 smm->begin = old_len; 611 memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm)); 612 613 /* 614 * Extend. 615 */ 616 r = sm_ll_extend(&smm->ll, extra_blocks); 617 618 /* 619 * Switch back to normal behaviour. 620 */ 621 memcpy(&smm->sm, &ops, sizeof(smm->sm)); 622 for (i = old_len; !r && i < smm->begin; i++) 623 r = sm_ll_inc(&smm->ll, i, &ev); 624 625 return r; 626 } 627 628 /*----------------------------------------------------------------*/ 629 630 struct dm_space_map *dm_sm_metadata_init(void) 631 { 632 struct sm_metadata *smm; 633 634 smm = kmalloc(sizeof(*smm), GFP_KERNEL); 635 if (!smm) 636 return ERR_PTR(-ENOMEM); 637 638 memcpy(&smm->sm, &ops, sizeof(smm->sm)); 639 640 return &smm->sm; 641 } 642 643 int dm_sm_metadata_create(struct dm_space_map *sm, 644 struct dm_transaction_manager *tm, 645 dm_block_t nr_blocks, 646 dm_block_t superblock) 647 { 648 int r; 649 dm_block_t i; 650 enum allocation_event ev; 651 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 652 653 smm->begin = superblock + 1; 654 smm->recursion_count = 0; 655 smm->allocated_this_transaction = 0; 656 smm->nr_uncommitted = 0; 657 threshold_init(&smm->threshold); 658 659 memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm)); 660 661 r = sm_ll_new_metadata(&smm->ll, tm); 662 if (r) 663 return r; 664 665 r = sm_ll_extend(&smm->ll, nr_blocks); 666 if (r) 667 return r; 668 669 memcpy(&smm->sm, &ops, sizeof(smm->sm)); 670 671 /* 672 * Now we need to update the newly created data structures with the 673 * allocated blocks that they were built from. 674 */ 675 for (i = superblock; !r && i < smm->begin; i++) 676 r = sm_ll_inc(&smm->ll, i, &ev); 677 678 if (r) 679 return r; 680 681 return sm_metadata_commit(sm); 682 } 683 684 int dm_sm_metadata_open(struct dm_space_map *sm, 685 struct dm_transaction_manager *tm, 686 void *root_le, size_t len) 687 { 688 int r; 689 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 690 691 r = sm_ll_open_metadata(&smm->ll, tm, root_le, len); 692 if (r) 693 return r; 694 695 smm->begin = 0; 696 smm->recursion_count = 0; 697 smm->allocated_this_transaction = 0; 698 smm->nr_uncommitted = 0; 699 threshold_init(&smm->threshold); 700 701 memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll)); 702 return 0; 703 } 704