diff options
-rw-r--r-- | fs/btrfs/send.c | 105 |
1 files changed, 64 insertions, 41 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 89fefbd955f3..a2621e7aaa5c 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -2501,17 +2501,26 @@ static int did_create_dir(struct send_ctx *sctx, u64 dir) | |||
2501 | key.objectid = dir; | 2501 | key.objectid = dir; |
2502 | key.type = BTRFS_DIR_INDEX_KEY; | 2502 | key.type = BTRFS_DIR_INDEX_KEY; |
2503 | key.offset = 0; | 2503 | key.offset = 0; |
2504 | ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0); | ||
2505 | if (ret < 0) | ||
2506 | goto out; | ||
2507 | |||
2504 | while (1) { | 2508 | while (1) { |
2505 | ret = btrfs_search_slot_for_read(sctx->send_root, &key, path, | 2509 | eb = path->nodes[0]; |
2506 | 1, 0); | 2510 | slot = path->slots[0]; |
2507 | if (ret < 0) | 2511 | if (slot >= btrfs_header_nritems(eb)) { |
2508 | goto out; | 2512 | ret = btrfs_next_leaf(sctx->send_root, path); |
2509 | if (!ret) { | 2513 | if (ret < 0) { |
2510 | eb = path->nodes[0]; | 2514 | goto out; |
2511 | slot = path->slots[0]; | 2515 | } else if (ret > 0) { |
2512 | btrfs_item_key_to_cpu(eb, &found_key, slot); | 2516 | ret = 0; |
2517 | break; | ||
2518 | } | ||
2519 | continue; | ||
2513 | } | 2520 | } |
2514 | if (ret || found_key.objectid != key.objectid || | 2521 | |
2522 | btrfs_item_key_to_cpu(eb, &found_key, slot); | ||
2523 | if (found_key.objectid != key.objectid || | ||
2515 | found_key.type != key.type) { | 2524 | found_key.type != key.type) { |
2516 | ret = 0; | 2525 | ret = 0; |
2517 | goto out; | 2526 | goto out; |
@@ -2526,8 +2535,7 @@ static int did_create_dir(struct send_ctx *sctx, u64 dir) | |||
2526 | goto out; | 2535 | goto out; |
2527 | } | 2536 | } |
2528 | 2537 | ||
2529 | key.offset = found_key.offset + 1; | 2538 | path->slots[0]++; |
2530 | btrfs_release_path(path); | ||
2531 | } | 2539 | } |
2532 | 2540 | ||
2533 | out: | 2541 | out: |
@@ -2693,19 +2701,24 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 send_progress) | |||
2693 | key.objectid = dir; | 2701 | key.objectid = dir; |
2694 | key.type = BTRFS_DIR_INDEX_KEY; | 2702 | key.type = BTRFS_DIR_INDEX_KEY; |
2695 | key.offset = 0; | 2703 | key.offset = 0; |
2704 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
2705 | if (ret < 0) | ||
2706 | goto out; | ||
2696 | 2707 | ||
2697 | while (1) { | 2708 | while (1) { |
2698 | ret = btrfs_search_slot_for_read(root, &key, path, 1, 0); | 2709 | if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) { |
2699 | if (ret < 0) | 2710 | ret = btrfs_next_leaf(root, path); |
2700 | goto out; | 2711 | if (ret < 0) |
2701 | if (!ret) { | 2712 | goto out; |
2702 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, | 2713 | else if (ret > 0) |
2703 | path->slots[0]); | 2714 | break; |
2715 | continue; | ||
2704 | } | 2716 | } |
2705 | if (ret || found_key.objectid != key.objectid || | 2717 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, |
2706 | found_key.type != key.type) { | 2718 | path->slots[0]); |
2719 | if (found_key.objectid != key.objectid || | ||
2720 | found_key.type != key.type) | ||
2707 | break; | 2721 | break; |
2708 | } | ||
2709 | 2722 | ||
2710 | di = btrfs_item_ptr(path->nodes[0], path->slots[0], | 2723 | di = btrfs_item_ptr(path->nodes[0], path->slots[0], |
2711 | struct btrfs_dir_item); | 2724 | struct btrfs_dir_item); |
@@ -2716,8 +2729,7 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 send_progress) | |||
2716 | goto out; | 2729 | goto out; |
2717 | } | 2730 | } |
2718 | 2731 | ||
2719 | btrfs_release_path(path); | 2732 | path->slots[0]++; |
2720 | key.offset = found_key.offset + 1; | ||
2721 | } | 2733 | } |
2722 | 2734 | ||
2723 | ret = 1; | 2735 | ret = 1; |
@@ -3620,15 +3632,22 @@ static int process_all_refs(struct send_ctx *sctx, | |||
3620 | key.objectid = sctx->cmp_key->objectid; | 3632 | key.objectid = sctx->cmp_key->objectid; |
3621 | key.type = BTRFS_INODE_REF_KEY; | 3633 | key.type = BTRFS_INODE_REF_KEY; |
3622 | key.offset = 0; | 3634 | key.offset = 0; |
3623 | while (1) { | 3635 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
3624 | ret = btrfs_search_slot_for_read(root, &key, path, 1, 0); | 3636 | if (ret < 0) |
3625 | if (ret < 0) | 3637 | goto out; |
3626 | goto out; | ||
3627 | if (ret) | ||
3628 | break; | ||
3629 | 3638 | ||
3639 | while (1) { | ||
3630 | eb = path->nodes[0]; | 3640 | eb = path->nodes[0]; |
3631 | slot = path->slots[0]; | 3641 | slot = path->slots[0]; |
3642 | if (slot >= btrfs_header_nritems(eb)) { | ||
3643 | ret = btrfs_next_leaf(root, path); | ||
3644 | if (ret < 0) | ||
3645 | goto out; | ||
3646 | else if (ret > 0) | ||
3647 | break; | ||
3648 | continue; | ||
3649 | } | ||
3650 | |||
3632 | btrfs_item_key_to_cpu(eb, &found_key, slot); | 3651 | btrfs_item_key_to_cpu(eb, &found_key, slot); |
3633 | 3652 | ||
3634 | if (found_key.objectid != key.objectid || | 3653 | if (found_key.objectid != key.objectid || |
@@ -3637,11 +3656,10 @@ static int process_all_refs(struct send_ctx *sctx, | |||
3637 | break; | 3656 | break; |
3638 | 3657 | ||
3639 | ret = iterate_inode_ref(root, path, &found_key, 0, cb, sctx); | 3658 | ret = iterate_inode_ref(root, path, &found_key, 0, cb, sctx); |
3640 | btrfs_release_path(path); | ||
3641 | if (ret < 0) | 3659 | if (ret < 0) |
3642 | goto out; | 3660 | goto out; |
3643 | 3661 | ||
3644 | key.offset = found_key.offset + 1; | 3662 | path->slots[0]++; |
3645 | } | 3663 | } |
3646 | btrfs_release_path(path); | 3664 | btrfs_release_path(path); |
3647 | 3665 | ||
@@ -3922,19 +3940,25 @@ static int process_all_new_xattrs(struct send_ctx *sctx) | |||
3922 | key.objectid = sctx->cmp_key->objectid; | 3940 | key.objectid = sctx->cmp_key->objectid; |
3923 | key.type = BTRFS_XATTR_ITEM_KEY; | 3941 | key.type = BTRFS_XATTR_ITEM_KEY; |
3924 | key.offset = 0; | 3942 | key.offset = 0; |
3925 | while (1) { | 3943 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
3926 | ret = btrfs_search_slot_for_read(root, &key, path, 1, 0); | 3944 | if (ret < 0) |
3927 | if (ret < 0) | 3945 | goto out; |
3928 | goto out; | ||
3929 | if (ret) { | ||
3930 | ret = 0; | ||
3931 | goto out; | ||
3932 | } | ||
3933 | 3946 | ||
3947 | while (1) { | ||
3934 | eb = path->nodes[0]; | 3948 | eb = path->nodes[0]; |
3935 | slot = path->slots[0]; | 3949 | slot = path->slots[0]; |
3936 | btrfs_item_key_to_cpu(eb, &found_key, slot); | 3950 | if (slot >= btrfs_header_nritems(eb)) { |
3951 | ret = btrfs_next_leaf(root, path); | ||
3952 | if (ret < 0) { | ||
3953 | goto out; | ||
3954 | } else if (ret > 0) { | ||
3955 | ret = 0; | ||
3956 | break; | ||
3957 | } | ||
3958 | continue; | ||
3959 | } | ||
3937 | 3960 | ||
3961 | btrfs_item_key_to_cpu(eb, &found_key, slot); | ||
3938 | if (found_key.objectid != key.objectid || | 3962 | if (found_key.objectid != key.objectid || |
3939 | found_key.type != key.type) { | 3963 | found_key.type != key.type) { |
3940 | ret = 0; | 3964 | ret = 0; |
@@ -3946,8 +3970,7 @@ static int process_all_new_xattrs(struct send_ctx *sctx) | |||
3946 | if (ret < 0) | 3970 | if (ret < 0) |
3947 | goto out; | 3971 | goto out; |
3948 | 3972 | ||
3949 | btrfs_release_path(path); | 3973 | path->slots[0]++; |
3950 | key.offset = found_key.offset + 1; | ||
3951 | } | 3974 | } |
3952 | 3975 | ||
3953 | out: | 3976 | out: |