1/* 2 * Copyright (C) 2011 Red Hat, Inc. 3 * 4 * This file is released under the GPL. 5 */ 6 7#include "dm-space-map-common.h" 8#include "dm-transaction-manager.h" 9 10#include <linux/bitops.h> 11#include <linux/device-mapper.h> 12 13#define DM_MSG_PREFIX "space map common" 14 15/*----------------------------------------------------------------*/ 16 17/* 18 * Index validator. 19 */ 20#define INDEX_CSUM_XOR 160478 21 22static void index_prepare_for_write(struct dm_block_validator *v, 23 struct dm_block *b, 24 size_t block_size) 25{ 26 struct disk_metadata_index *mi_le = dm_block_data(b); 27 28 mi_le->blocknr = cpu_to_le64(dm_block_location(b)); 29 mi_le->csum = cpu_to_le32(dm_bm_checksum(&mi_le->padding, 30 block_size - sizeof(__le32), 31 INDEX_CSUM_XOR)); 32} 33 34static int index_check(struct dm_block_validator *v, 35 struct dm_block *b, 36 size_t block_size) 37{ 38 struct disk_metadata_index *mi_le = dm_block_data(b); 39 __le32 csum_disk; 40 41 if (dm_block_location(b) != le64_to_cpu(mi_le->blocknr)) { 42 DMERR_LIMIT("index_check failed: blocknr %llu != wanted %llu", 43 le64_to_cpu(mi_le->blocknr), dm_block_location(b)); 44 return -ENOTBLK; 45 } 46 47 csum_disk = cpu_to_le32(dm_bm_checksum(&mi_le->padding, 48 block_size - sizeof(__le32), 49 INDEX_CSUM_XOR)); 50 if (csum_disk != mi_le->csum) { 51 DMERR_LIMIT("index_check failed: csum %u != wanted %u", 52 le32_to_cpu(csum_disk), le32_to_cpu(mi_le->csum)); 53 return -EILSEQ; 54 } 55 56 return 0; 57} 58 59static struct dm_block_validator index_validator = { 60 .name = "index", 61 .prepare_for_write = index_prepare_for_write, 62 .check = index_check 63}; 64 65/*----------------------------------------------------------------*/ 66 67/* 68 * Bitmap validator 69 */ 70#define BITMAP_CSUM_XOR 240779 71 72static void dm_bitmap_prepare_for_write(struct dm_block_validator *v, 73 struct dm_block *b, 74 size_t block_size) 75{ 76 struct disk_bitmap_header *disk_header = dm_block_data(b); 77 78 disk_header->blocknr = cpu_to_le64(dm_block_location(b)); 79 disk_header->csum = cpu_to_le32(dm_bm_checksum(&disk_header->not_used, 80 block_size - sizeof(__le32), 81 BITMAP_CSUM_XOR)); 82} 83 84static int dm_bitmap_check(struct dm_block_validator *v, 85 struct dm_block *b, 86 size_t block_size) 87{ 88 struct disk_bitmap_header *disk_header = dm_block_data(b); 89 __le32 csum_disk; 90 91 if (dm_block_location(b) != le64_to_cpu(disk_header->blocknr)) { 92 DMERR_LIMIT("bitmap check failed: blocknr %llu != wanted %llu", 93 le64_to_cpu(disk_header->blocknr), dm_block_location(b)); 94 return -ENOTBLK; 95 } 96 97 csum_disk = cpu_to_le32(dm_bm_checksum(&disk_header->not_used, 98 block_size - sizeof(__le32), 99 BITMAP_CSUM_XOR)); 100 if (csum_disk != disk_header->csum) { 101 DMERR_LIMIT("bitmap check failed: csum %u != wanted %u", 102 le32_to_cpu(csum_disk), le32_to_cpu(disk_header->csum)); 103 return -EILSEQ; 104 } 105 106 return 0; 107} 108 109static struct dm_block_validator dm_sm_bitmap_validator = { 110 .name = "sm_bitmap", 111 .prepare_for_write = dm_bitmap_prepare_for_write, 112 .check = dm_bitmap_check, 113}; 114 115/*----------------------------------------------------------------*/ 116 117#define ENTRIES_PER_WORD 32 118#define ENTRIES_SHIFT 5 119 120static void *dm_bitmap_data(struct dm_block *b) 121{ 122 return dm_block_data(b) + sizeof(struct disk_bitmap_header); 123} 124 125#define WORD_MASK_HIGH 0xAAAAAAAAAAAAAAAAULL 126 127static unsigned dm_bitmap_word_used(void *addr, unsigned b) 128{ 129 __le64 *words_le = addr; 130 __le64 *w_le = words_le + (b >> ENTRIES_SHIFT); 131 132 uint64_t bits = le64_to_cpu(*w_le); 133 uint64_t mask = (bits + WORD_MASK_HIGH + 1) & WORD_MASK_HIGH; 134 135 return !(~bits & mask); 136} 137 138static unsigned sm_lookup_bitmap(void *addr, unsigned b) 139{ 140 __le64 *words_le = addr; 141 __le64 *w_le = words_le + (b >> ENTRIES_SHIFT); 142 unsigned hi, lo; 143 144 b = (b & (ENTRIES_PER_WORD - 1)) << 1; 145 hi = !!test_bit_le(b, (void *) w_le); 146 lo = !!test_bit_le(b + 1, (void *) w_le); 147 return (hi << 1) | lo; 148} 149 150static void sm_set_bitmap(void *addr, unsigned b, unsigned val) 151{ 152 __le64 *words_le = addr; 153 __le64 *w_le = words_le + (b >> ENTRIES_SHIFT); 154 155 b = (b & (ENTRIES_PER_WORD - 1)) << 1; 156 157 if (val & 2) 158 __set_bit_le(b, (void *) w_le); 159 else 160 __clear_bit_le(b, (void *) w_le); 161 162 if (val & 1) 163 __set_bit_le(b + 1, (void *) w_le); 164 else 165 __clear_bit_le(b + 1, (void *) w_le); 166} 167 168static int sm_find_free(void *addr, unsigned begin, unsigned end, 169 unsigned *result) 170{ 171 while (begin < end) { 172 if (!(begin & (ENTRIES_PER_WORD - 1)) && 173 dm_bitmap_word_used(addr, begin)) { 174 begin += ENTRIES_PER_WORD; 175 continue; 176 } 177 178 if (!sm_lookup_bitmap(addr, begin)) { 179 *result = begin; 180 return 0; 181 } 182 183 begin++; 184 } 185 186 return -ENOSPC; 187} 188 189/*----------------------------------------------------------------*/ 190 191static int sm_ll_init(struct ll_disk *ll, struct dm_transaction_manager *tm) 192{ 193 memset(ll, 0, sizeof(struct ll_disk)); 194 195 ll->tm = tm; 196 197 ll->bitmap_info.tm = tm; 198 ll->bitmap_info.levels = 1; 199 200 /* 201 * Because the new bitmap blocks are created via a shadow 202 * operation, the old entry has already had its reference count 203 * decremented and we don't need the btree to do any bookkeeping. 204 */ 205 ll->bitmap_info.value_type.size = sizeof(struct disk_index_entry); 206 ll->bitmap_info.value_type.inc = NULL; 207 ll->bitmap_info.value_type.dec = NULL; 208 ll->bitmap_info.value_type.equal = NULL; 209 210 ll->ref_count_info.tm = tm; 211 ll->ref_count_info.levels = 1; 212 ll->ref_count_info.value_type.size = sizeof(uint32_t); 213 ll->ref_count_info.value_type.inc = NULL; 214 ll->ref_count_info.value_type.dec = NULL; 215 ll->ref_count_info.value_type.equal = NULL; 216 217 ll->block_size = dm_bm_block_size(dm_tm_get_bm(tm)); 218 219 if (ll->block_size > (1 << 30)) { 220 DMERR("block size too big to hold bitmaps"); 221 return -EINVAL; 222 } 223 224 ll->entries_per_block = (ll->block_size - sizeof(struct disk_bitmap_header)) * 225 ENTRIES_PER_BYTE; 226 ll->nr_blocks = 0; 227 ll->bitmap_root = 0; 228 ll->ref_count_root = 0; 229 ll->bitmap_index_changed = false; 230 231 return 0; 232} 233 234int sm_ll_extend(struct ll_disk *ll, dm_block_t extra_blocks) 235{ 236 int r; 237 dm_block_t i, nr_blocks, nr_indexes; 238 unsigned old_blocks, blocks; 239 240 nr_blocks = ll->nr_blocks + extra_blocks; 241 old_blocks = dm_sector_div_up(ll->nr_blocks, ll->entries_per_block); 242 blocks = dm_sector_div_up(nr_blocks, ll->entries_per_block); 243 244 nr_indexes = dm_sector_div_up(nr_blocks, ll->entries_per_block); 245 if (nr_indexes > ll->max_entries(ll)) { 246 DMERR("space map too large"); 247 return -EINVAL; 248 } 249 250 /* 251 * We need to set this before the dm_tm_new_block() call below. 252 */ 253 ll->nr_blocks = nr_blocks; 254 for (i = old_blocks; i < blocks; i++) { 255 struct dm_block *b; 256 struct disk_index_entry idx; 257 258 r = dm_tm_new_block(ll->tm, &dm_sm_bitmap_validator, &b); 259 if (r < 0) 260 return r; 261 262 idx.blocknr = cpu_to_le64(dm_block_location(b)); 263 264 dm_tm_unlock(ll->tm, b); 265 266 idx.nr_free = cpu_to_le32(ll->entries_per_block); 267 idx.none_free_before = 0; 268 269 r = ll->save_ie(ll, i, &idx); 270 if (r < 0) 271 return r; 272 } 273 274 return 0; 275} 276 277int sm_ll_lookup_bitmap(struct ll_disk *ll, dm_block_t b, uint32_t *result) 278{ 279 int r; 280 dm_block_t index = b; 281 struct disk_index_entry ie_disk; 282 struct dm_block *blk; 283 284 if (b >= ll->nr_blocks) { 285 DMERR_LIMIT("metadata block out of bounds"); 286 return -EINVAL; 287 } 288 289 b = do_div(index, ll->entries_per_block); 290 r = ll->load_ie(ll, index, &ie_disk); 291 if (r < 0) 292 return r; 293 294 r = dm_tm_read_lock(ll->tm, le64_to_cpu(ie_disk.blocknr), 295 &dm_sm_bitmap_validator, &blk); 296 if (r < 0) 297 return r; 298 299 *result = sm_lookup_bitmap(dm_bitmap_data(blk), b); 300 301 dm_tm_unlock(ll->tm, blk); 302 303 return 0; 304} 305 306static int sm_ll_lookup_big_ref_count(struct ll_disk *ll, dm_block_t b, 307 uint32_t *result) 308{ 309 __le32 le_rc; 310 int r; 311 312 r = dm_btree_lookup(&ll->ref_count_info, ll->ref_count_root, &b, &le_rc); 313 if (r < 0) 314 return r; 315 316 *result = le32_to_cpu(le_rc); 317 318 return r; 319} 320 321int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result) 322{ 323 int r = sm_ll_lookup_bitmap(ll, b, result); 324 325 if (r) 326 return r; 327 328 if (*result != 3) 329 return r; 330 331 return sm_ll_lookup_big_ref_count(ll, b, result); 332} 333 334int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin, 335 dm_block_t end, dm_block_t *result) 336{ 337 int r; 338 struct disk_index_entry ie_disk; 339 dm_block_t i, index_begin = begin; 340 dm_block_t index_end = dm_sector_div_up(end, ll->entries_per_block); 341 342 /* 343 * FIXME: Use shifts 344 */ 345 begin = do_div(index_begin, ll->entries_per_block); 346 end = do_div(end, ll->entries_per_block); 347 if (end == 0) 348 end = ll->entries_per_block; 349 350 for (i = index_begin; i < index_end; i++, begin = 0) { 351 struct dm_block *blk; 352 unsigned position; 353 uint32_t bit_end; 354 355 r = ll->load_ie(ll, i, &ie_disk); 356 if (r < 0) 357 return r; 358 359 if (le32_to_cpu(ie_disk.nr_free) == 0) 360 continue; 361 362 r = dm_tm_read_lock(ll->tm, le64_to_cpu(ie_disk.blocknr), 363 &dm_sm_bitmap_validator, &blk); 364 if (r < 0) 365 return r; 366 367 bit_end = (i == index_end - 1) ? end : ll->entries_per_block; 368 369 r = sm_find_free(dm_bitmap_data(blk), 370 max_t(unsigned, begin, le32_to_cpu(ie_disk.none_free_before)), 371 bit_end, &position); 372 if (r == -ENOSPC) { 373 /* 374 * This might happen because we started searching 375 * part way through the bitmap. 376 */ 377 dm_tm_unlock(ll->tm, blk); 378 continue; 379 } 380 381 dm_tm_unlock(ll->tm, blk); 382 383 *result = i * ll->entries_per_block + (dm_block_t) position; 384 return 0; 385 } 386 387 return -ENOSPC; 388} 389 390int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll, 391 dm_block_t begin, dm_block_t end, dm_block_t *b) 392{ 393 int r; 394 uint32_t count; 395 396 do { 397 r = sm_ll_find_free_block(new_ll, begin, new_ll->nr_blocks, b); 398 if (r) 399 break; 400 401 /* double check this block wasn't used in the old transaction */ 402 if (*b >= old_ll->nr_blocks) 403 count = 0; 404 else { 405 r = sm_ll_lookup(old_ll, *b, &count); 406 if (r) 407 break; 408 409 if (count) 410 begin = *b + 1; 411 } 412 } while (count); 413 414 return r; 415} 416 417static int sm_ll_mutate(struct ll_disk *ll, dm_block_t b, 418 int (*mutator)(void *context, uint32_t old, uint32_t *new), 419 void *context, enum allocation_event *ev) 420{ 421 int r; 422 uint32_t bit, old, ref_count; 423 struct dm_block *nb; 424 dm_block_t index = b; 425 struct disk_index_entry ie_disk; 426 void *bm_le; 427 int inc; 428 429 bit = do_div(index, ll->entries_per_block); 430 r = ll->load_ie(ll, index, &ie_disk); 431 if (r < 0) 432 return r; 433 434 r = dm_tm_shadow_block(ll->tm, le64_to_cpu(ie_disk.blocknr), 435 &dm_sm_bitmap_validator, &nb, &inc); 436 if (r < 0) { 437 DMERR("dm_tm_shadow_block() failed"); 438 return r; 439 } 440 ie_disk.blocknr = cpu_to_le64(dm_block_location(nb)); 441 442 bm_le = dm_bitmap_data(nb); 443 old = sm_lookup_bitmap(bm_le, bit); 444 445 if (old > 2) { 446 r = sm_ll_lookup_big_ref_count(ll, b, &old); 447 if (r < 0) { 448 dm_tm_unlock(ll->tm, nb); 449 return r; 450 } 451 } 452 453 r = mutator(context, old, &ref_count); 454 if (r) { 455 dm_tm_unlock(ll->tm, nb); 456 return r; 457 } 458 459 if (ref_count <= 2) { 460 sm_set_bitmap(bm_le, bit, ref_count); 461 462 dm_tm_unlock(ll->tm, nb); 463 464 if (old > 2) { 465 r = dm_btree_remove(&ll->ref_count_info, 466 ll->ref_count_root, 467 &b, &ll->ref_count_root); 468 if (r) 469 return r; 470 } 471 472 } else { 473 __le32 le_rc = cpu_to_le32(ref_count); 474 475 sm_set_bitmap(bm_le, bit, 3); 476 dm_tm_unlock(ll->tm, nb); 477 478 __dm_bless_for_disk(&le_rc); 479 r = dm_btree_insert(&ll->ref_count_info, ll->ref_count_root, 480 &b, &le_rc, &ll->ref_count_root); 481 if (r < 0) { 482 DMERR("ref count insert failed"); 483 return r; 484 } 485 } 486 487 if (ref_count && !old) { 488 *ev = SM_ALLOC; 489 ll->nr_allocated++; 490 le32_add_cpu(&ie_disk.nr_free, -1); 491 if (le32_to_cpu(ie_disk.none_free_before) == bit) 492 ie_disk.none_free_before = cpu_to_le32(bit + 1); 493 494 } else if (old && !ref_count) { 495 *ev = SM_FREE; 496 ll->nr_allocated--; 497 le32_add_cpu(&ie_disk.nr_free, 1); 498 ie_disk.none_free_before = cpu_to_le32(min(le32_to_cpu(ie_disk.none_free_before), bit)); 499 } else 500 *ev = SM_NONE; 501 502 return ll->save_ie(ll, index, &ie_disk); 503} 504 505static int set_ref_count(void *context, uint32_t old, uint32_t *new) 506{ 507 *new = *((uint32_t *) context); 508 return 0; 509} 510 511int sm_ll_insert(struct ll_disk *ll, dm_block_t b, 512 uint32_t ref_count, enum allocation_event *ev) 513{ 514 return sm_ll_mutate(ll, b, set_ref_count, &ref_count, ev); 515} 516 517static int inc_ref_count(void *context, uint32_t old, uint32_t *new) 518{ 519 *new = old + 1; 520 return 0; 521} 522 523int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev) 524{ 525 return sm_ll_mutate(ll, b, inc_ref_count, NULL, ev); 526} 527 528static int dec_ref_count(void *context, uint32_t old, uint32_t *new) 529{ 530 if (!old) { 531 DMERR_LIMIT("unable to decrement a reference count below 0"); 532 return -EINVAL; 533 } 534 535 *new = old - 1; 536 return 0; 537} 538 539int sm_ll_dec(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev) 540{ 541 return sm_ll_mutate(ll, b, dec_ref_count, NULL, ev); 542} 543 544int sm_ll_commit(struct ll_disk *ll) 545{ 546 int r = 0; 547 548 if (ll->bitmap_index_changed) { 549 r = ll->commit(ll); 550 if (!r) 551 ll->bitmap_index_changed = false; 552 } 553 554 return r; 555} 556 557/*----------------------------------------------------------------*/ 558 559static int metadata_ll_load_ie(struct ll_disk *ll, dm_block_t index, 560 struct disk_index_entry *ie) 561{ 562 memcpy(ie, ll->mi_le.index + index, sizeof(*ie)); 563 return 0; 564} 565 566static int metadata_ll_save_ie(struct ll_disk *ll, dm_block_t index, 567 struct disk_index_entry *ie) 568{ 569 ll->bitmap_index_changed = true; 570 memcpy(ll->mi_le.index + index, ie, sizeof(*ie)); 571 return 0; 572} 573 574static int metadata_ll_init_index(struct ll_disk *ll) 575{ 576 int r; 577 struct dm_block *b; 578 579 r = dm_tm_new_block(ll->tm, &index_validator, &b); 580 if (r < 0) 581 return r; 582 583 ll->bitmap_root = dm_block_location(b); 584 585 dm_tm_unlock(ll->tm, b); 586 587 return 0; 588} 589 590static int metadata_ll_open(struct ll_disk *ll) 591{ 592 int r; 593 struct dm_block *block; 594 595 r = dm_tm_read_lock(ll->tm, ll->bitmap_root, 596 &index_validator, &block); 597 if (r) 598 return r; 599 600 memcpy(&ll->mi_le, dm_block_data(block), sizeof(ll->mi_le)); 601 dm_tm_unlock(ll->tm, block); 602 603 return 0; 604} 605 606static dm_block_t metadata_ll_max_entries(struct ll_disk *ll) 607{ 608 return MAX_METADATA_BITMAPS; 609} 610 611static int metadata_ll_commit(struct ll_disk *ll) 612{ 613 int r, inc; 614 struct dm_block *b; 615 616 r = dm_tm_shadow_block(ll->tm, ll->bitmap_root, &index_validator, &b, &inc); 617 if (r) 618 return r; 619 620 memcpy(dm_block_data(b), &ll->mi_le, sizeof(ll->mi_le)); 621 ll->bitmap_root = dm_block_location(b); 622 623 dm_tm_unlock(ll->tm, b); 624 625 return 0; 626} 627 628int sm_ll_new_metadata(struct ll_disk *ll, struct dm_transaction_manager *tm) 629{ 630 int r; 631 632 r = sm_ll_init(ll, tm); 633 if (r < 0) 634 return r; 635 636 ll->load_ie = metadata_ll_load_ie; 637 ll->save_ie = metadata_ll_save_ie; 638 ll->init_index = metadata_ll_init_index; 639 ll->open_index = metadata_ll_open; 640 ll->max_entries = metadata_ll_max_entries; 641 ll->commit = metadata_ll_commit; 642 643 ll->nr_blocks = 0; 644 ll->nr_allocated = 0; 645 646 r = ll->init_index(ll); 647 if (r < 0) 648 return r; 649 650 r = dm_btree_empty(&ll->ref_count_info, &ll->ref_count_root); 651 if (r < 0) 652 return r; 653 654 return 0; 655} 656 657int sm_ll_open_metadata(struct ll_disk *ll, struct dm_transaction_manager *tm, 658 void *root_le, size_t len) 659{ 660 int r; 661 struct disk_sm_root smr; 662 663 if (len < sizeof(struct disk_sm_root)) { 664 DMERR("sm_metadata root too small"); 665 return -ENOMEM; 666 } 667 668 /* 669 * We don't know the alignment of the root_le buffer, so need to 670 * copy into a new structure. 671 */ 672 memcpy(&smr, root_le, sizeof(smr)); 673 674 r = sm_ll_init(ll, tm); 675 if (r < 0) 676 return r; 677 678 ll->load_ie = metadata_ll_load_ie; 679 ll->save_ie = metadata_ll_save_ie; 680 ll->init_index = metadata_ll_init_index; 681 ll->open_index = metadata_ll_open; 682 ll->max_entries = metadata_ll_max_entries; 683 ll->commit = metadata_ll_commit; 684 685 ll->nr_blocks = le64_to_cpu(smr.nr_blocks); 686 ll->nr_allocated = le64_to_cpu(smr.nr_allocated); 687 ll->bitmap_root = le64_to_cpu(smr.bitmap_root); 688 ll->ref_count_root = le64_to_cpu(smr.ref_count_root); 689 690 return ll->open_index(ll); 691} 692 693/*----------------------------------------------------------------*/ 694 695static int disk_ll_load_ie(struct ll_disk *ll, dm_block_t index, 696 struct disk_index_entry *ie) 697{ 698 return dm_btree_lookup(&ll->bitmap_info, ll->bitmap_root, &index, ie); 699} 700 701static int disk_ll_save_ie(struct ll_disk *ll, dm_block_t index, 702 struct disk_index_entry *ie) 703{ 704 __dm_bless_for_disk(ie); 705 return dm_btree_insert(&ll->bitmap_info, ll->bitmap_root, 706 &index, ie, &ll->bitmap_root); 707} 708 709static int disk_ll_init_index(struct ll_disk *ll) 710{ 711 return dm_btree_empty(&ll->bitmap_info, &ll->bitmap_root); 712} 713 714static int disk_ll_open(struct ll_disk *ll) 715{ 716 /* nothing to do */ 717 return 0; 718} 719 720static dm_block_t disk_ll_max_entries(struct ll_disk *ll) 721{ 722 return -1ULL; 723} 724 725static int disk_ll_commit(struct ll_disk *ll) 726{ 727 return 0; 728} 729 730int sm_ll_new_disk(struct ll_disk *ll, struct dm_transaction_manager *tm) 731{ 732 int r; 733 734 r = sm_ll_init(ll, tm); 735 if (r < 0) 736 return r; 737 738 ll->load_ie = disk_ll_load_ie; 739 ll->save_ie = disk_ll_save_ie; 740 ll->init_index = disk_ll_init_index; 741 ll->open_index = disk_ll_open; 742 ll->max_entries = disk_ll_max_entries; 743 ll->commit = disk_ll_commit; 744 745 ll->nr_blocks = 0; 746 ll->nr_allocated = 0; 747 748 r = ll->init_index(ll); 749 if (r < 0) 750 return r; 751 752 r = dm_btree_empty(&ll->ref_count_info, &ll->ref_count_root); 753 if (r < 0) 754 return r; 755 756 return 0; 757} 758 759int sm_ll_open_disk(struct ll_disk *ll, struct dm_transaction_manager *tm, 760 void *root_le, size_t len) 761{ 762 int r; 763 struct disk_sm_root *smr = root_le; 764 765 if (len < sizeof(struct disk_sm_root)) { 766 DMERR("sm_metadata root too small"); 767 return -ENOMEM; 768 } 769 770 r = sm_ll_init(ll, tm); 771 if (r < 0) 772 return r; 773 774 ll->load_ie = disk_ll_load_ie; 775 ll->save_ie = disk_ll_save_ie; 776 ll->init_index = disk_ll_init_index; 777 ll->open_index = disk_ll_open; 778 ll->max_entries = disk_ll_max_entries; 779 ll->commit = disk_ll_commit; 780 781 ll->nr_blocks = le64_to_cpu(smr->nr_blocks); 782 ll->nr_allocated = le64_to_cpu(smr->nr_allocated); 783 ll->bitmap_root = le64_to_cpu(smr->bitmap_root); 784 ll->ref_count_root = le64_to_cpu(smr->ref_count_root); 785 786 return ll->open_index(ll); 787} 788 789/*----------------------------------------------------------------*/ 790