tree-log.c (860a7a0c321ce0267fdb6ebdcd03aa63c5fcb31d) | tree-log.c (07d400a6df4767a90d49a153fdb7f4cfa1e3f23e) |
---|---|
1/* 2 * Copyright (C) 2008 Oracle. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License v2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, --- 419 unchanged lines hidden (view full) --- 428 if (key->type == BTRFS_INODE_ITEM_KEY) { 429 struct btrfs_inode_item *dst_item; 430 dst_item = (struct btrfs_inode_item *)dst_ptr; 431 if (btrfs_inode_generation(path->nodes[0], dst_item) == 0) { 432 btrfs_set_inode_generation(path->nodes[0], dst_item, 433 trans->transid); 434 } 435 } | 1/* 2 * Copyright (C) 2008 Oracle. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License v2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, --- 419 unchanged lines hidden (view full) --- 428 if (key->type == BTRFS_INODE_ITEM_KEY) { 429 struct btrfs_inode_item *dst_item; 430 dst_item = (struct btrfs_inode_item *)dst_ptr; 431 if (btrfs_inode_generation(path->nodes[0], dst_item) == 0) { 432 btrfs_set_inode_generation(path->nodes[0], dst_item, 433 trans->transid); 434 } 435 } |
436 437 if (overwrite_root && 438 key->type == BTRFS_EXTENT_DATA_KEY) { 439 int extent_type; 440 struct btrfs_file_extent_item *fi; 441 442 fi = (struct btrfs_file_extent_item *)dst_ptr; 443 extent_type = btrfs_file_extent_type(path->nodes[0], fi); 444 if (extent_type == BTRFS_FILE_EXTENT_REG || 445 extent_type == BTRFS_FILE_EXTENT_PREALLOC) { 446 struct btrfs_key ins; 447 ins.objectid = btrfs_file_extent_disk_bytenr( 448 path->nodes[0], fi); 449 ins.offset = btrfs_file_extent_disk_num_bytes( 450 path->nodes[0], fi); 451 ins.type = BTRFS_EXTENT_ITEM_KEY; 452 453 /* 454 * is this extent already allocated in the extent 455 * allocation tree? If so, just add a reference 456 */ 457 ret = btrfs_lookup_extent(root, ins.objectid, 458 ins.offset); 459 if (ret == 0) { 460 ret = btrfs_inc_extent_ref(trans, root, 461 ins.objectid, ins.offset, 462 path->nodes[0]->start, 463 root->root_key.objectid, 464 trans->transid, key->objectid); 465 } else { 466 /* 467 * insert the extent pointer in the extent 468 * allocation tree 469 */ 470 ret = btrfs_alloc_logged_extent(trans, root, 471 path->nodes[0]->start, 472 root->root_key.objectid, 473 trans->transid, key->objectid, 474 &ins); 475 BUG_ON(ret); 476 } 477 } 478 } | |
479no_copy: 480 btrfs_mark_buffer_dirty(path->nodes[0]); 481 btrfs_release_path(root, path); 482 return 0; 483} 484 485/* 486 * simple helper to read an inode off the disk from a given root --- 38 unchanged lines hidden (view full) --- 525 struct extent_buffer *eb, int slot, 526 struct btrfs_key *key) 527{ 528 int found_type; 529 u64 mask = root->sectorsize - 1; 530 u64 extent_end; 531 u64 alloc_hint; 532 u64 start = key->offset; | 436no_copy: 437 btrfs_mark_buffer_dirty(path->nodes[0]); 438 btrfs_release_path(root, path); 439 return 0; 440} 441 442/* 443 * simple helper to read an inode off the disk from a given root --- 38 unchanged lines hidden (view full) --- 482 struct extent_buffer *eb, int slot, 483 struct btrfs_key *key) 484{ 485 int found_type; 486 u64 mask = root->sectorsize - 1; 487 u64 extent_end; 488 u64 alloc_hint; 489 u64 start = key->offset; |
490 u64 saved_nbytes; |
|
533 struct btrfs_file_extent_item *item; 534 struct inode *inode = NULL; 535 unsigned long size; 536 int ret = 0; 537 538 item = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); 539 found_type = btrfs_file_extent_type(eb, item); 540 --- 45 unchanged lines hidden (view full) --- 586 */ 587 if (memcmp(&cmp1, &cmp2, sizeof(cmp1)) == 0) { 588 btrfs_release_path(root, path); 589 goto out; 590 } 591 } 592 btrfs_release_path(root, path); 593 | 491 struct btrfs_file_extent_item *item; 492 struct inode *inode = NULL; 493 unsigned long size; 494 int ret = 0; 495 496 item = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); 497 found_type = btrfs_file_extent_type(eb, item); 498 --- 45 unchanged lines hidden (view full) --- 544 */ 545 if (memcmp(&cmp1, &cmp2, sizeof(cmp1)) == 0) { 546 btrfs_release_path(root, path); 547 goto out; 548 } 549 } 550 btrfs_release_path(root, path); 551 |
552 saved_nbytes = inode_get_bytes(inode); |
|
594 /* drop any overlapping extents */ 595 ret = btrfs_drop_extents(trans, root, inode, 596 start, extent_end, start, &alloc_hint); 597 BUG_ON(ret); 598 | 553 /* drop any overlapping extents */ 554 ret = btrfs_drop_extents(trans, root, inode, 555 start, extent_end, start, &alloc_hint); 556 BUG_ON(ret); 557 |
599 /* insert the extent */ 600 ret = overwrite_item(trans, root, path, eb, slot, key); 601 BUG_ON(ret); | 558 if (found_type == BTRFS_FILE_EXTENT_REG || 559 found_type == BTRFS_FILE_EXTENT_PREALLOC) { 560 unsigned long dest_offset; 561 struct btrfs_key ins; |
602 | 562 |
603 /* btrfs_drop_extents changes i_bytes & i_blocks, update it here */ 604 inode_add_bytes(inode, extent_end - start); | 563 ret = btrfs_insert_empty_item(trans, root, path, key, 564 sizeof(*item)); 565 BUG_ON(ret); 566 dest_offset = btrfs_item_ptr_offset(path->nodes[0], 567 path->slots[0]); 568 copy_extent_buffer(path->nodes[0], eb, dest_offset, 569 (unsigned long)item, sizeof(*item)); 570 571 ins.objectid = btrfs_file_extent_disk_bytenr(eb, item); 572 ins.offset = btrfs_file_extent_disk_num_bytes(eb, item); 573 ins.type = BTRFS_EXTENT_ITEM_KEY; 574 575 if (ins.objectid > 0) { 576 u64 csum_start; 577 u64 csum_end; 578 LIST_HEAD(ordered_sums); 579 /* 580 * is this extent already allocated in the extent 581 * allocation tree? If so, just add a reference 582 */ 583 ret = btrfs_lookup_extent(root, ins.objectid, 584 ins.offset); 585 if (ret == 0) { 586 ret = btrfs_inc_extent_ref(trans, root, 587 ins.objectid, ins.offset, 588 path->nodes[0]->start, 589 root->root_key.objectid, 590 trans->transid, key->objectid); 591 } else { 592 /* 593 * insert the extent pointer in the extent 594 * allocation tree 595 */ 596 ret = btrfs_alloc_logged_extent(trans, root, 597 path->nodes[0]->start, 598 root->root_key.objectid, 599 trans->transid, key->objectid, 600 &ins); 601 BUG_ON(ret); 602 } 603 btrfs_release_path(root, path); 604 605 if (btrfs_file_extent_compression(eb, item)) { 606 csum_start = ins.objectid; 607 csum_end = csum_start + ins.offset; 608 } else { 609 csum_start = ins.objectid + 610 btrfs_file_extent_offset(eb, item); 611 csum_end = csum_start + 612 btrfs_file_extent_num_bytes(eb, item); 613 } 614 615 ret = btrfs_lookup_csums_range(root->log_root, 616 csum_start, csum_end - 1, 617 &ordered_sums); 618 BUG_ON(ret); 619 while (!list_empty(&ordered_sums)) { 620 struct btrfs_ordered_sum *sums; 621 sums = list_entry(ordered_sums.next, 622 struct btrfs_ordered_sum, 623 list); 624 ret = btrfs_csum_file_blocks(trans, 625 root->fs_info->csum_root, 626 sums); 627 BUG_ON(ret); 628 list_del(&sums->list); 629 kfree(sums); 630 } 631 } else { 632 btrfs_release_path(root, path); 633 } 634 } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { 635 /* inline extents are easy, we just overwrite them */ 636 ret = overwrite_item(trans, root, path, eb, slot, key); 637 BUG_ON(ret); 638 } 639 640 inode_set_bytes(inode, saved_nbytes); |
605 btrfs_update_inode(trans, root, inode); 606out: 607 if (inode) 608 iput(inode); 609 return ret; 610} 611 612/* --- 285 unchanged lines hidden (view full) --- 898out_nowrite: 899 btrfs_release_path(root, path); 900 iput(dir); 901 iput(inode); 902 return 0; 903} 904 905/* | 641 btrfs_update_inode(trans, root, inode); 642out: 643 if (inode) 644 iput(inode); 645 return ret; 646} 647 648/* --- 285 unchanged lines hidden (view full) --- 934out_nowrite: 935 btrfs_release_path(root, path); 936 iput(dir); 937 iput(inode); 938 return 0; 939} 940 941/* |
906 * replay one csum item from the log tree into the subvolume 'root' 907 * eb, slot and key all refer to the log tree 908 * path is for temp use by this function and should be released on return 909 * 910 * This copies the checksums out of the log tree and inserts them into 911 * the subvolume. Any existing checksums for this range in the file 912 * are overwritten, and new items are added where required. 913 * 914 * We keep this simple by reusing the btrfs_ordered_sum code from 915 * the data=ordered mode. This basically means making a copy 916 * of all the checksums in ram, which we have to do anyway for kmap 917 * rules. 918 * 919 * The copy is then sent down to btrfs_csum_file_blocks, which 920 * does all the hard work of finding existing items in the file 921 * or adding new ones. 922 */ 923static noinline int replay_one_csum(struct btrfs_trans_handle *trans, 924 struct btrfs_root *root, 925 struct btrfs_path *path, 926 struct extent_buffer *eb, int slot, 927 struct btrfs_key *key) 928{ 929 int ret; 930 u32 item_size = btrfs_item_size_nr(eb, slot); 931 u64 cur_offset; 932 u16 csum_size = 933 btrfs_super_csum_size(&root->fs_info->super_copy); 934 unsigned long file_bytes; 935 struct btrfs_ordered_sum *sums; 936 struct btrfs_sector_sum *sector_sum; 937 unsigned long ptr; 938 939 file_bytes = (item_size / csum_size) * root->sectorsize; 940 sums = kzalloc(btrfs_ordered_sum_size(root, file_bytes), GFP_NOFS); 941 if (!sums) 942 return -ENOMEM; 943 944 INIT_LIST_HEAD(&sums->list); 945 sums->len = file_bytes; 946 sums->bytenr = key->offset; 947 948 /* 949 * copy all the sums into the ordered sum struct 950 */ 951 sector_sum = sums->sums; 952 cur_offset = key->offset; 953 ptr = btrfs_item_ptr_offset(eb, slot); 954 while (item_size > 0) { 955 sector_sum->bytenr = cur_offset; 956 read_extent_buffer(eb, §or_sum->sum, ptr, csum_size); 957 sector_sum++; 958 item_size -= csum_size; 959 ptr += csum_size; 960 cur_offset += root->sectorsize; 961 } 962 963 /* let btrfs_csum_file_blocks add them into the file */ 964 ret = btrfs_csum_file_blocks(trans, root->fs_info->csum_root, sums); 965 BUG_ON(ret); 966 kfree(sums); 967 return 0; 968} 969/* | |
970 * There are a few corners where the link count of the file can't 971 * be properly maintained during replay. So, instead of adding 972 * lots of complexity to the log code, we just scan the backrefs 973 * for any file that has been through replay. 974 * 975 * The scan will update the link count on the inode to reflect the 976 * number of back refs found. If it goes down to zero, the iput 977 * will free the inode. --- 676 unchanged lines hidden (view full) --- 1654 } else if (key.type == BTRFS_INODE_REF_KEY) { 1655 ret = add_inode_ref(wc->trans, root, log, path, 1656 eb, i, &key); 1657 BUG_ON(ret && ret != -ENOENT); 1658 } else if (key.type == BTRFS_EXTENT_DATA_KEY) { 1659 ret = replay_one_extent(wc->trans, root, path, 1660 eb, i, &key); 1661 BUG_ON(ret); | 942 * There are a few corners where the link count of the file can't 943 * be properly maintained during replay. So, instead of adding 944 * lots of complexity to the log code, we just scan the backrefs 945 * for any file that has been through replay. 946 * 947 * The scan will update the link count on the inode to reflect the 948 * number of back refs found. If it goes down to zero, the iput 949 * will free the inode. --- 676 unchanged lines hidden (view full) --- 1626 } else if (key.type == BTRFS_INODE_REF_KEY) { 1627 ret = add_inode_ref(wc->trans, root, log, path, 1628 eb, i, &key); 1629 BUG_ON(ret && ret != -ENOENT); 1630 } else if (key.type == BTRFS_EXTENT_DATA_KEY) { 1631 ret = replay_one_extent(wc->trans, root, path, 1632 eb, i, &key); 1633 BUG_ON(ret); |
1662 } else if (key.type == BTRFS_EXTENT_CSUM_KEY) { 1663 ret = replay_one_csum(wc->trans, root, path, 1664 eb, i, &key); 1665 BUG_ON(ret); | |
1666 } else if (key.type == BTRFS_DIR_ITEM_KEY || 1667 key.type == BTRFS_DIR_INDEX_KEY) { 1668 ret = replay_one_dir_item(wc->trans, root, path, 1669 eb, i, &key); 1670 BUG_ON(ret); 1671 } 1672 } 1673 btrfs_free_path(path); --- 342 unchanged lines hidden (view full) --- 2016 struct key; 2017 u64 start; 2018 u64 end; 2019 struct walk_control wc = { 2020 .free = 1, 2021 .process_func = process_one_buffer 2022 }; 2023 | 1634 } else if (key.type == BTRFS_DIR_ITEM_KEY || 1635 key.type == BTRFS_DIR_INDEX_KEY) { 1636 ret = replay_one_dir_item(wc->trans, root, path, 1637 eb, i, &key); 1638 BUG_ON(ret); 1639 } 1640 } 1641 btrfs_free_path(path); --- 342 unchanged lines hidden (view full) --- 1984 struct key; 1985 u64 start; 1986 u64 end; 1987 struct walk_control wc = { 1988 .free = 1, 1989 .process_func = process_one_buffer 1990 }; 1991 |
2024 if (!root->log_root) | 1992 if (!root->log_root || root->fs_info->log_root_recovering) |
2025 return 0; 2026 2027 log = root->log_root; 2028 ret = walk_log_tree(trans, log, &wc); 2029 BUG_ON(ret); 2030 2031 while (1) { 2032 ret = find_first_extent_bit(&log->dirty_log_pages, --- 415 unchanged lines hidden (view full) --- 2448 ret = btrfs_del_item(trans, log, path); 2449 BUG_ON(ret); 2450 btrfs_release_path(log, path); 2451 } 2452 btrfs_release_path(log, path); 2453 return 0; 2454} 2455 | 1993 return 0; 1994 1995 log = root->log_root; 1996 ret = walk_log_tree(trans, log, &wc); 1997 BUG_ON(ret); 1998 1999 while (1) { 2000 ret = find_first_extent_bit(&log->dirty_log_pages, --- 415 unchanged lines hidden (view full) --- 2416 ret = btrfs_del_item(trans, log, path); 2417 BUG_ON(ret); 2418 btrfs_release_path(log, path); 2419 } 2420 btrfs_release_path(log, path); 2421 return 0; 2422} 2423 |
2456static noinline int copy_extent_csums(struct btrfs_trans_handle *trans, 2457 struct list_head *list, 2458 struct btrfs_root *root, 2459 u64 disk_bytenr, u64 len) 2460{ 2461 struct btrfs_ordered_sum *sums; 2462 struct btrfs_sector_sum *sector_sum; 2463 int ret; 2464 struct btrfs_path *path; 2465 struct btrfs_csum_item *item = NULL; 2466 u64 end = disk_bytenr + len; 2467 u64 item_start_offset = 0; 2468 u64 item_last_offset = 0; 2469 u32 diff; 2470 u32 sum; 2471 u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy); 2472 2473 sums = kzalloc(btrfs_ordered_sum_size(root, len), GFP_NOFS); 2474 2475 sector_sum = sums->sums; 2476 sums->bytenr = disk_bytenr; 2477 sums->len = len; 2478 list_add_tail(&sums->list, list); 2479 2480 path = btrfs_alloc_path(); 2481 while (disk_bytenr < end) { 2482 if (!item || disk_bytenr < item_start_offset || 2483 disk_bytenr >= item_last_offset) { 2484 struct btrfs_key found_key; 2485 u32 item_size; 2486 2487 if (item) 2488 btrfs_release_path(root, path); 2489 item = btrfs_lookup_csum(NULL, root, path, 2490 disk_bytenr, 0); 2491 if (IS_ERR(item)) { 2492 ret = PTR_ERR(item); 2493 if (ret == -ENOENT || ret == -EFBIG) 2494 ret = 0; 2495 sum = 0; 2496 printk(KERN_INFO "log no csum found for " 2497 "byte %llu\n", 2498 (unsigned long long)disk_bytenr); 2499 item = NULL; 2500 btrfs_release_path(root, path); 2501 goto found; 2502 } 2503 btrfs_item_key_to_cpu(path->nodes[0], &found_key, 2504 path->slots[0]); 2505 2506 item_start_offset = found_key.offset; 2507 item_size = btrfs_item_size_nr(path->nodes[0], 2508 path->slots[0]); 2509 item_last_offset = item_start_offset + 2510 (item_size / csum_size) * 2511 root->sectorsize; 2512 item = btrfs_item_ptr(path->nodes[0], path->slots[0], 2513 struct btrfs_csum_item); 2514 } 2515 /* 2516 * this byte range must be able to fit inside 2517 * a single leaf so it will also fit inside a u32 2518 */ 2519 diff = disk_bytenr - item_start_offset; 2520 diff = diff / root->sectorsize; 2521 diff = diff * csum_size; 2522 2523 read_extent_buffer(path->nodes[0], &sum, 2524 ((unsigned long)item) + diff, 2525 csum_size); 2526found: 2527 sector_sum->bytenr = disk_bytenr; 2528 sector_sum->sum = sum; 2529 disk_bytenr += root->sectorsize; 2530 sector_sum++; 2531 } 2532 btrfs_free_path(path); 2533 return 0; 2534} 2535 | |
2536static noinline int copy_items(struct btrfs_trans_handle *trans, 2537 struct btrfs_root *log, 2538 struct btrfs_path *dst_path, 2539 struct extent_buffer *src, 2540 int start_slot, int nr, int inode_only) 2541{ 2542 unsigned long src_offset; 2543 unsigned long dst_offset; --- 73 unchanged lines hidden (view full) --- 2617 if (ds != 0) { 2618 ret = btrfs_inc_extent_ref(trans, log, 2619 ds, dl, 2620 dst_path->nodes[0]->start, 2621 BTRFS_TREE_LOG_OBJECTID, 2622 trans->transid, 2623 ins_keys[i].objectid); 2624 BUG_ON(ret); | 2424static noinline int copy_items(struct btrfs_trans_handle *trans, 2425 struct btrfs_root *log, 2426 struct btrfs_path *dst_path, 2427 struct extent_buffer *src, 2428 int start_slot, int nr, int inode_only) 2429{ 2430 unsigned long src_offset; 2431 unsigned long dst_offset; --- 73 unchanged lines hidden (view full) --- 2505 if (ds != 0) { 2506 ret = btrfs_inc_extent_ref(trans, log, 2507 ds, dl, 2508 dst_path->nodes[0]->start, 2509 BTRFS_TREE_LOG_OBJECTID, 2510 trans->transid, 2511 ins_keys[i].objectid); 2512 BUG_ON(ret); |
2625 ret = copy_extent_csums(trans, 2626 &ordered_sums, 2627 log->fs_info->csum_root, 2628 ds + cs, cl); | 2513 ret = btrfs_lookup_csums_range( 2514 log->fs_info->csum_root, 2515 ds + cs, ds + cs + cl - 1, 2516 &ordered_sums); |
2629 BUG_ON(ret); 2630 } 2631 } 2632 } 2633 dst_path->slots[0]++; 2634 } 2635 2636 btrfs_mark_buffer_dirty(dst_path->nodes[0]); --- 300 unchanged lines hidden (view full) --- 2937 BUG_ON(!log); 2938 2939 2940 tmp_key.objectid = found_key.offset; 2941 tmp_key.type = BTRFS_ROOT_ITEM_KEY; 2942 tmp_key.offset = (u64)-1; 2943 2944 wc.replay_dest = btrfs_read_fs_root_no_name(fs_info, &tmp_key); | 2517 BUG_ON(ret); 2518 } 2519 } 2520 } 2521 dst_path->slots[0]++; 2522 } 2523 2524 btrfs_mark_buffer_dirty(dst_path->nodes[0]); --- 300 unchanged lines hidden (view full) --- 2825 BUG_ON(!log); 2826 2827 2828 tmp_key.objectid = found_key.offset; 2829 tmp_key.type = BTRFS_ROOT_ITEM_KEY; 2830 tmp_key.offset = (u64)-1; 2831 2832 wc.replay_dest = btrfs_read_fs_root_no_name(fs_info, &tmp_key); |
2945 | |
2946 BUG_ON(!wc.replay_dest); 2947 | 2833 BUG_ON(!wc.replay_dest); 2834 |
2835 wc.replay_dest->log_root = log; |
|
2948 btrfs_record_root_in_trans(wc.replay_dest); 2949 ret = walk_log_tree(trans, log, &wc); 2950 BUG_ON(ret); 2951 2952 if (wc.stage == LOG_WALK_REPLAY_ALL) { 2953 ret = fixup_inode_link_counts(trans, wc.replay_dest, 2954 path); 2955 BUG_ON(ret); 2956 } 2957 ret = btrfs_find_highest_inode(wc.replay_dest, &highest_inode); 2958 if (ret == 0) { 2959 wc.replay_dest->highest_inode = highest_inode; 2960 wc.replay_dest->last_inode_alloc = highest_inode; 2961 } 2962 2963 key.offset = found_key.offset - 1; | 2836 btrfs_record_root_in_trans(wc.replay_dest); 2837 ret = walk_log_tree(trans, log, &wc); 2838 BUG_ON(ret); 2839 2840 if (wc.stage == LOG_WALK_REPLAY_ALL) { 2841 ret = fixup_inode_link_counts(trans, wc.replay_dest, 2842 path); 2843 BUG_ON(ret); 2844 } 2845 ret = btrfs_find_highest_inode(wc.replay_dest, &highest_inode); 2846 if (ret == 0) { 2847 wc.replay_dest->highest_inode = highest_inode; 2848 wc.replay_dest->last_inode_alloc = highest_inode; 2849 } 2850 2851 key.offset = found_key.offset - 1; |
2852 wc.replay_dest->log_root = NULL; |
|
2964 free_extent_buffer(log->node); 2965 kfree(log); 2966 2967 if (found_key.offset == 0) 2968 break; 2969 } 2970 btrfs_release_path(log_root_tree, path); 2971 --- 25 unchanged lines hidden --- | 2853 free_extent_buffer(log->node); 2854 kfree(log); 2855 2856 if (found_key.offset == 0) 2857 break; 2858 } 2859 btrfs_release_path(log_root_tree, path); 2860 --- 25 unchanged lines hidden --- |