diff options
Diffstat (limited to 'fs/btrfs/send.c')
| -rw-r--r-- | fs/btrfs/send.c | 242 | 
1 files changed, 193 insertions, 49 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index d3f3b43cae0b..e46e0ed74925 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c  | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/radix-tree.h> | 26 | #include <linux/radix-tree.h> | 
| 27 | #include <linux/crc32c.h> | 27 | #include <linux/crc32c.h> | 
| 28 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> | 
| 29 | #include <linux/string.h> | ||
| 29 | 30 | ||
| 30 | #include "send.h" | 31 | #include "send.h" | 
| 31 | #include "backref.h" | 32 | #include "backref.h" | 
| @@ -54,8 +55,8 @@ struct fs_path { | |||
| 54 | 55 | ||
| 55 | char *buf; | 56 | char *buf; | 
| 56 | int buf_len; | 57 | int buf_len; | 
| 57 | int reversed:1; | 58 | unsigned int reversed:1; | 
| 58 | int virtual_mem:1; | 59 | unsigned int virtual_mem:1; | 
| 59 | char inline_buf[]; | 60 | char inline_buf[]; | 
| 60 | }; | 61 | }; | 
| 61 | char pad[PAGE_SIZE]; | 62 | char pad[PAGE_SIZE]; | 
| @@ -219,7 +220,7 @@ static int fs_path_ensure_buf(struct fs_path *p, int len) | |||
| 219 | len = PAGE_ALIGN(len); | 220 | len = PAGE_ALIGN(len); | 
| 220 | 221 | ||
| 221 | if (p->buf == p->inline_buf) { | 222 | if (p->buf == p->inline_buf) { | 
| 222 | tmp_buf = kmalloc(len, GFP_NOFS); | 223 | tmp_buf = kmalloc(len, GFP_NOFS | __GFP_NOWARN); | 
| 223 | if (!tmp_buf) { | 224 | if (!tmp_buf) { | 
| 224 | tmp_buf = vmalloc(len); | 225 | tmp_buf = vmalloc(len); | 
| 225 | if (!tmp_buf) | 226 | if (!tmp_buf) | 
| @@ -1668,6 +1669,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, | |||
| 1668 | u64 *who_ino, u64 *who_gen) | 1669 | u64 *who_ino, u64 *who_gen) | 
| 1669 | { | 1670 | { | 
| 1670 | int ret = 0; | 1671 | int ret = 0; | 
| 1672 | u64 gen; | ||
| 1671 | u64 other_inode = 0; | 1673 | u64 other_inode = 0; | 
| 1672 | u8 other_type = 0; | 1674 | u8 other_type = 0; | 
| 1673 | 1675 | ||
| @@ -1678,6 +1680,24 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, | |||
| 1678 | if (ret <= 0) | 1680 | if (ret <= 0) | 
| 1679 | goto out; | 1681 | goto out; | 
| 1680 | 1682 | ||
| 1683 | /* | ||
| 1684 | * If we have a parent root we need to verify that the parent dir was | ||
| 1685 | * not delted and then re-created, if it was then we have no overwrite | ||
| 1686 | * and we can just unlink this entry. | ||
| 1687 | */ | ||
| 1688 | if (sctx->parent_root) { | ||
| 1689 | ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL, | ||
| 1690 | NULL, NULL, NULL); | ||
| 1691 | if (ret < 0 && ret != -ENOENT) | ||
| 1692 | goto out; | ||
| 1693 | if (ret) { | ||
| 1694 | ret = 0; | ||
| 1695 | goto out; | ||
| 1696 | } | ||
| 1697 | if (gen != dir_gen) | ||
| 1698 | goto out; | ||
| 1699 | } | ||
| 1700 | |||
| 1681 | ret = lookup_dir_item_inode(sctx->parent_root, dir, name, name_len, | 1701 | ret = lookup_dir_item_inode(sctx->parent_root, dir, name, name_len, | 
| 1682 | &other_inode, &other_type); | 1702 | &other_inode, &other_type); | 
| 1683 | if (ret < 0 && ret != -ENOENT) | 1703 | if (ret < 0 && ret != -ENOENT) | 
| @@ -2519,7 +2539,8 @@ static int did_create_dir(struct send_ctx *sctx, u64 dir) | |||
| 2519 | di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item); | 2539 | di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item); | 
| 2520 | btrfs_dir_item_key_to_cpu(eb, di, &di_key); | 2540 | btrfs_dir_item_key_to_cpu(eb, di, &di_key); | 
| 2521 | 2541 | ||
| 2522 | if (di_key.objectid < sctx->send_progress) { | 2542 | if (di_key.type != BTRFS_ROOT_ITEM_KEY && | 
| 2543 | di_key.objectid < sctx->send_progress) { | ||
| 2523 | ret = 1; | 2544 | ret = 1; | 
| 2524 | goto out; | 2545 | goto out; | 
| 2525 | } | 2546 | } | 
| @@ -2581,7 +2602,6 @@ static int record_ref(struct list_head *head, u64 dir, | |||
| 2581 | u64 dir_gen, struct fs_path *path) | 2602 | u64 dir_gen, struct fs_path *path) | 
| 2582 | { | 2603 | { | 
| 2583 | struct recorded_ref *ref; | 2604 | struct recorded_ref *ref; | 
| 2584 | char *tmp; | ||
| 2585 | 2605 | ||
| 2586 | ref = kmalloc(sizeof(*ref), GFP_NOFS); | 2606 | ref = kmalloc(sizeof(*ref), GFP_NOFS); | 
| 2587 | if (!ref) | 2607 | if (!ref) | 
| @@ -2591,25 +2611,35 @@ static int record_ref(struct list_head *head, u64 dir, | |||
| 2591 | ref->dir_gen = dir_gen; | 2611 | ref->dir_gen = dir_gen; | 
| 2592 | ref->full_path = path; | 2612 | ref->full_path = path; | 
| 2593 | 2613 | ||
| 2594 | tmp = strrchr(ref->full_path->start, '/'); | 2614 | ref->name = (char *)kbasename(ref->full_path->start); | 
| 2595 | if (!tmp) { | 2615 | ref->name_len = ref->full_path->end - ref->name; | 
| 2596 | ref->name_len = ref->full_path->end - ref->full_path->start; | 2616 | ref->dir_path = ref->full_path->start; | 
| 2597 | ref->name = ref->full_path->start; | 2617 | if (ref->name == ref->full_path->start) | 
| 2598 | ref->dir_path_len = 0; | 2618 | ref->dir_path_len = 0; | 
| 2599 | ref->dir_path = ref->full_path->start; | 2619 | else | 
| 2600 | } else { | ||
| 2601 | tmp++; | ||
| 2602 | ref->name_len = ref->full_path->end - tmp; | ||
| 2603 | ref->name = tmp; | ||
| 2604 | ref->dir_path = ref->full_path->start; | ||
| 2605 | ref->dir_path_len = ref->full_path->end - | 2620 | ref->dir_path_len = ref->full_path->end - | 
| 2606 | ref->full_path->start - 1 - ref->name_len; | 2621 | ref->full_path->start - 1 - ref->name_len; | 
| 2607 | } | ||
| 2608 | 2622 | ||
| 2609 | list_add_tail(&ref->list, head); | 2623 | list_add_tail(&ref->list, head); | 
| 2610 | return 0; | 2624 | return 0; | 
| 2611 | } | 2625 | } | 
| 2612 | 2626 | ||
| 2627 | static int dup_ref(struct recorded_ref *ref, struct list_head *list) | ||
| 2628 | { | ||
| 2629 | struct recorded_ref *new; | ||
| 2630 | |||
| 2631 | new = kmalloc(sizeof(*ref), GFP_NOFS); | ||
| 2632 | if (!new) | ||
| 2633 | return -ENOMEM; | ||
| 2634 | |||
| 2635 | new->dir = ref->dir; | ||
| 2636 | new->dir_gen = ref->dir_gen; | ||
| 2637 | new->full_path = NULL; | ||
| 2638 | INIT_LIST_HEAD(&new->list); | ||
| 2639 | list_add_tail(&new->list, list); | ||
| 2640 | return 0; | ||
| 2641 | } | ||
| 2642 | |||
| 2613 | static void __free_recorded_refs(struct list_head *head) | 2643 | static void __free_recorded_refs(struct list_head *head) | 
| 2614 | { | 2644 | { | 
| 2615 | struct recorded_ref *cur; | 2645 | struct recorded_ref *cur; | 
| @@ -2724,9 +2754,7 @@ static int process_recorded_refs(struct send_ctx *sctx) | |||
| 2724 | int ret = 0; | 2754 | int ret = 0; | 
| 2725 | struct recorded_ref *cur; | 2755 | struct recorded_ref *cur; | 
| 2726 | struct recorded_ref *cur2; | 2756 | struct recorded_ref *cur2; | 
| 2727 | struct ulist *check_dirs = NULL; | 2757 | struct list_head check_dirs; | 
| 2728 | struct ulist_iterator uit; | ||
| 2729 | struct ulist_node *un; | ||
| 2730 | struct fs_path *valid_path = NULL; | 2758 | struct fs_path *valid_path = NULL; | 
| 2731 | u64 ow_inode = 0; | 2759 | u64 ow_inode = 0; | 
| 2732 | u64 ow_gen; | 2760 | u64 ow_gen; | 
| @@ -2740,6 +2768,7 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 2740 | * which is always '..' | 2768 | * which is always '..' | 
| 2741 | */ | 2769 | */ | 
| 2742 | BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID); | 2770 | BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID); | 
| 2771 | INIT_LIST_HEAD(&check_dirs); | ||
| 2743 | 2772 | ||
| 2744 | valid_path = fs_path_alloc(); | 2773 | valid_path = fs_path_alloc(); | 
| 2745 | if (!valid_path) { | 2774 | if (!valid_path) { | 
| @@ -2747,12 +2776,6 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 2747 | goto out; | 2776 | goto out; | 
| 2748 | } | 2777 | } | 
| 2749 | 2778 | ||
| 2750 | check_dirs = ulist_alloc(GFP_NOFS); | ||
| 2751 | if (!check_dirs) { | ||
| 2752 | ret = -ENOMEM; | ||
| 2753 | goto out; | ||
| 2754 | } | ||
| 2755 | |||
| 2756 | /* | 2779 | /* | 
| 2757 | * First, check if the first ref of the current inode was overwritten | 2780 | * First, check if the first ref of the current inode was overwritten | 
| 2758 | * before. If yes, we know that the current inode was already orphanized | 2781 | * before. If yes, we know that the current inode was already orphanized | 
| @@ -2889,8 +2912,7 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 2889 | goto out; | 2912 | goto out; | 
| 2890 | } | 2913 | } | 
| 2891 | } | 2914 | } | 
| 2892 | ret = ulist_add(check_dirs, cur->dir, cur->dir_gen, | 2915 | ret = dup_ref(cur, &check_dirs); | 
| 2893 | GFP_NOFS); | ||
| 2894 | if (ret < 0) | 2916 | if (ret < 0) | 
| 2895 | goto out; | 2917 | goto out; | 
| 2896 | } | 2918 | } | 
| @@ -2918,8 +2940,7 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 2918 | } | 2940 | } | 
| 2919 | 2941 | ||
| 2920 | list_for_each_entry(cur, &sctx->deleted_refs, list) { | 2942 | list_for_each_entry(cur, &sctx->deleted_refs, list) { | 
| 2921 | ret = ulist_add(check_dirs, cur->dir, cur->dir_gen, | 2943 | ret = dup_ref(cur, &check_dirs); | 
| 2922 | GFP_NOFS); | ||
| 2923 | if (ret < 0) | 2944 | if (ret < 0) | 
| 2924 | goto out; | 2945 | goto out; | 
| 2925 | } | 2946 | } | 
| @@ -2930,8 +2951,7 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 2930 | */ | 2951 | */ | 
| 2931 | cur = list_entry(sctx->deleted_refs.next, struct recorded_ref, | 2952 | cur = list_entry(sctx->deleted_refs.next, struct recorded_ref, | 
| 2932 | list); | 2953 | list); | 
| 2933 | ret = ulist_add(check_dirs, cur->dir, cur->dir_gen, | 2954 | ret = dup_ref(cur, &check_dirs); | 
| 2934 | GFP_NOFS); | ||
| 2935 | if (ret < 0) | 2955 | if (ret < 0) | 
| 2936 | goto out; | 2956 | goto out; | 
| 2937 | } else if (!S_ISDIR(sctx->cur_inode_mode)) { | 2957 | } else if (!S_ISDIR(sctx->cur_inode_mode)) { | 
| @@ -2951,12 +2971,10 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 2951 | if (ret < 0) | 2971 | if (ret < 0) | 
| 2952 | goto out; | 2972 | goto out; | 
| 2953 | } | 2973 | } | 
| 2954 | ret = ulist_add(check_dirs, cur->dir, cur->dir_gen, | 2974 | ret = dup_ref(cur, &check_dirs); | 
| 2955 | GFP_NOFS); | ||
| 2956 | if (ret < 0) | 2975 | if (ret < 0) | 
| 2957 | goto out; | 2976 | goto out; | 
| 2958 | } | 2977 | } | 
| 2959 | |||
| 2960 | /* | 2978 | /* | 
| 2961 | * If the inode is still orphan, unlink the orphan. This may | 2979 | * If the inode is still orphan, unlink the orphan. This may | 
| 2962 | * happen when a previous inode did overwrite the first ref | 2980 | * happen when a previous inode did overwrite the first ref | 
| @@ -2978,33 +2996,32 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 2978 | * deletion and if it's finally possible to perform the rmdir now. | 2996 | * deletion and if it's finally possible to perform the rmdir now. | 
| 2979 | * We also update the inode stats of the parent dirs here. | 2997 | * We also update the inode stats of the parent dirs here. | 
| 2980 | */ | 2998 | */ | 
| 2981 | ULIST_ITER_INIT(&uit); | 2999 | list_for_each_entry(cur, &check_dirs, list) { | 
| 2982 | while ((un = ulist_next(check_dirs, &uit))) { | ||
| 2983 | /* | 3000 | /* | 
| 2984 | * In case we had refs into dirs that were not processed yet, | 3001 | * In case we had refs into dirs that were not processed yet, | 
| 2985 | * we don't need to do the utime and rmdir logic for these dirs. | 3002 | * we don't need to do the utime and rmdir logic for these dirs. | 
| 2986 | * The dir will be processed later. | 3003 | * The dir will be processed later. | 
| 2987 | */ | 3004 | */ | 
| 2988 | if (un->val > sctx->cur_ino) | 3005 | if (cur->dir > sctx->cur_ino) | 
| 2989 | continue; | 3006 | continue; | 
| 2990 | 3007 | ||
| 2991 | ret = get_cur_inode_state(sctx, un->val, un->aux); | 3008 | ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen); | 
| 2992 | if (ret < 0) | 3009 | if (ret < 0) | 
| 2993 | goto out; | 3010 | goto out; | 
| 2994 | 3011 | ||
| 2995 | if (ret == inode_state_did_create || | 3012 | if (ret == inode_state_did_create || | 
| 2996 | ret == inode_state_no_change) { | 3013 | ret == inode_state_no_change) { | 
| 2997 | /* TODO delayed utimes */ | 3014 | /* TODO delayed utimes */ | 
| 2998 | ret = send_utimes(sctx, un->val, un->aux); | 3015 | ret = send_utimes(sctx, cur->dir, cur->dir_gen); | 
| 2999 | if (ret < 0) | 3016 | if (ret < 0) | 
| 3000 | goto out; | 3017 | goto out; | 
| 3001 | } else if (ret == inode_state_did_delete) { | 3018 | } else if (ret == inode_state_did_delete) { | 
| 3002 | ret = can_rmdir(sctx, un->val, sctx->cur_ino); | 3019 | ret = can_rmdir(sctx, cur->dir, sctx->cur_ino); | 
| 3003 | if (ret < 0) | 3020 | if (ret < 0) | 
| 3004 | goto out; | 3021 | goto out; | 
| 3005 | if (ret) { | 3022 | if (ret) { | 
| 3006 | ret = get_cur_path(sctx, un->val, un->aux, | 3023 | ret = get_cur_path(sctx, cur->dir, | 
| 3007 | valid_path); | 3024 | cur->dir_gen, valid_path); | 
| 3008 | if (ret < 0) | 3025 | if (ret < 0) | 
| 3009 | goto out; | 3026 | goto out; | 
| 3010 | ret = send_rmdir(sctx, valid_path); | 3027 | ret = send_rmdir(sctx, valid_path); | 
| @@ -3017,8 +3034,8 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 3017 | ret = 0; | 3034 | ret = 0; | 
| 3018 | 3035 | ||
| 3019 | out: | 3036 | out: | 
| 3037 | __free_recorded_refs(&check_dirs); | ||
| 3020 | free_recorded_refs(sctx); | 3038 | free_recorded_refs(sctx); | 
| 3021 | ulist_free(check_dirs); | ||
| 3022 | fs_path_free(valid_path); | 3039 | fs_path_free(valid_path); | 
| 3023 | return ret; | 3040 | return ret; | 
| 3024 | } | 3041 | } | 
| @@ -3119,6 +3136,8 @@ out: | |||
| 3119 | 3136 | ||
| 3120 | struct find_ref_ctx { | 3137 | struct find_ref_ctx { | 
| 3121 | u64 dir; | 3138 | u64 dir; | 
| 3139 | u64 dir_gen; | ||
| 3140 | struct btrfs_root *root; | ||
| 3122 | struct fs_path *name; | 3141 | struct fs_path *name; | 
| 3123 | int found_idx; | 3142 | int found_idx; | 
| 3124 | }; | 3143 | }; | 
| @@ -3128,9 +3147,21 @@ static int __find_iref(int num, u64 dir, int index, | |||
| 3128 | void *ctx_) | 3147 | void *ctx_) | 
| 3129 | { | 3148 | { | 
| 3130 | struct find_ref_ctx *ctx = ctx_; | 3149 | struct find_ref_ctx *ctx = ctx_; | 
| 3150 | u64 dir_gen; | ||
| 3151 | int ret; | ||
| 3131 | 3152 | ||
| 3132 | if (dir == ctx->dir && fs_path_len(name) == fs_path_len(ctx->name) && | 3153 | if (dir == ctx->dir && fs_path_len(name) == fs_path_len(ctx->name) && | 
| 3133 | strncmp(name->start, ctx->name->start, fs_path_len(name)) == 0) { | 3154 | strncmp(name->start, ctx->name->start, fs_path_len(name)) == 0) { | 
| 3155 | /* | ||
| 3156 | * To avoid doing extra lookups we'll only do this if everything | ||
| 3157 | * else matches. | ||
| 3158 | */ | ||
| 3159 | ret = get_inode_info(ctx->root, dir, NULL, &dir_gen, NULL, | ||
| 3160 | NULL, NULL, NULL); | ||
| 3161 | if (ret) | ||
| 3162 | return ret; | ||
| 3163 | if (dir_gen != ctx->dir_gen) | ||
| 3164 | return 0; | ||
| 3134 | ctx->found_idx = num; | 3165 | ctx->found_idx = num; | 
| 3135 | return 1; | 3166 | return 1; | 
| 3136 | } | 3167 | } | 
| @@ -3140,14 +3171,16 @@ static int __find_iref(int num, u64 dir, int index, | |||
| 3140 | static int find_iref(struct btrfs_root *root, | 3171 | static int find_iref(struct btrfs_root *root, | 
| 3141 | struct btrfs_path *path, | 3172 | struct btrfs_path *path, | 
| 3142 | struct btrfs_key *key, | 3173 | struct btrfs_key *key, | 
| 3143 | u64 dir, struct fs_path *name) | 3174 | u64 dir, u64 dir_gen, struct fs_path *name) | 
| 3144 | { | 3175 | { | 
| 3145 | int ret; | 3176 | int ret; | 
| 3146 | struct find_ref_ctx ctx; | 3177 | struct find_ref_ctx ctx; | 
| 3147 | 3178 | ||
| 3148 | ctx.dir = dir; | 3179 | ctx.dir = dir; | 
| 3149 | ctx.name = name; | 3180 | ctx.name = name; | 
| 3181 | ctx.dir_gen = dir_gen; | ||
| 3150 | ctx.found_idx = -1; | 3182 | ctx.found_idx = -1; | 
| 3183 | ctx.root = root; | ||
| 3151 | 3184 | ||
| 3152 | ret = iterate_inode_ref(root, path, key, 0, __find_iref, &ctx); | 3185 | ret = iterate_inode_ref(root, path, key, 0, __find_iref, &ctx); | 
| 3153 | if (ret < 0) | 3186 | if (ret < 0) | 
| @@ -3163,11 +3196,17 @@ static int __record_changed_new_ref(int num, u64 dir, int index, | |||
| 3163 | struct fs_path *name, | 3196 | struct fs_path *name, | 
| 3164 | void *ctx) | 3197 | void *ctx) | 
| 3165 | { | 3198 | { | 
| 3199 | u64 dir_gen; | ||
| 3166 | int ret; | 3200 | int ret; | 
| 3167 | struct send_ctx *sctx = ctx; | 3201 | struct send_ctx *sctx = ctx; | 
| 3168 | 3202 | ||
| 3203 | ret = get_inode_info(sctx->send_root, dir, NULL, &dir_gen, NULL, | ||
| 3204 | NULL, NULL, NULL); | ||
| 3205 | if (ret) | ||
| 3206 | return ret; | ||
| 3207 | |||
| 3169 | ret = find_iref(sctx->parent_root, sctx->right_path, | 3208 | ret = find_iref(sctx->parent_root, sctx->right_path, | 
| 3170 | sctx->cmp_key, dir, name); | 3209 | sctx->cmp_key, dir, dir_gen, name); | 
| 3171 | if (ret == -ENOENT) | 3210 | if (ret == -ENOENT) | 
| 3172 | ret = __record_new_ref(num, dir, index, name, sctx); | 3211 | ret = __record_new_ref(num, dir, index, name, sctx); | 
| 3173 | else if (ret > 0) | 3212 | else if (ret > 0) | 
| @@ -3180,11 +3219,17 @@ static int __record_changed_deleted_ref(int num, u64 dir, int index, | |||
| 3180 | struct fs_path *name, | 3219 | struct fs_path *name, | 
| 3181 | void *ctx) | 3220 | void *ctx) | 
| 3182 | { | 3221 | { | 
| 3222 | u64 dir_gen; | ||
| 3183 | int ret; | 3223 | int ret; | 
| 3184 | struct send_ctx *sctx = ctx; | 3224 | struct send_ctx *sctx = ctx; | 
| 3185 | 3225 | ||
| 3226 | ret = get_inode_info(sctx->parent_root, dir, NULL, &dir_gen, NULL, | ||
| 3227 | NULL, NULL, NULL); | ||
| 3228 | if (ret) | ||
| 3229 | return ret; | ||
| 3230 | |||
| 3186 | ret = find_iref(sctx->send_root, sctx->left_path, sctx->cmp_key, | 3231 | ret = find_iref(sctx->send_root, sctx->left_path, sctx->cmp_key, | 
| 3187 | dir, name); | 3232 | dir, dir_gen, name); | 
| 3188 | if (ret == -ENOENT) | 3233 | if (ret == -ENOENT) | 
| 3189 | ret = __record_deleted_ref(num, dir, index, name, sctx); | 3234 | ret = __record_deleted_ref(num, dir, index, name, sctx); | 
| 3190 | else if (ret > 0) | 3235 | else if (ret > 0) | 
| @@ -3869,7 +3914,8 @@ static int is_extent_unchanged(struct send_ctx *sctx, | |||
| 3869 | btrfs_item_key_to_cpu(eb, &found_key, slot); | 3914 | btrfs_item_key_to_cpu(eb, &found_key, slot); | 
| 3870 | if (found_key.objectid != key.objectid || | 3915 | if (found_key.objectid != key.objectid || | 
| 3871 | found_key.type != key.type) { | 3916 | found_key.type != key.type) { | 
| 3872 | ret = 0; | 3917 | /* If we're a hole then just pretend nothing changed */ | 
| 3918 | ret = (left_disknr) ? 0 : 1; | ||
| 3873 | goto out; | 3919 | goto out; | 
| 3874 | } | 3920 | } | 
| 3875 | 3921 | ||
| @@ -3895,7 +3941,8 @@ static int is_extent_unchanged(struct send_ctx *sctx, | |||
| 3895 | * This may only happen on the first iteration. | 3941 | * This may only happen on the first iteration. | 
| 3896 | */ | 3942 | */ | 
| 3897 | if (found_key.offset + right_len <= ekey->offset) { | 3943 | if (found_key.offset + right_len <= ekey->offset) { | 
| 3898 | ret = 0; | 3944 | /* If we're a hole just pretend nothing changed */ | 
| 3945 | ret = (left_disknr) ? 0 : 1; | ||
| 3899 | goto out; | 3946 | goto out; | 
| 3900 | } | 3947 | } | 
| 3901 | 3948 | ||
| @@ -3960,8 +4007,8 @@ static int process_extent(struct send_ctx *sctx, | |||
| 3960 | struct btrfs_path *path, | 4007 | struct btrfs_path *path, | 
| 3961 | struct btrfs_key *key) | 4008 | struct btrfs_key *key) | 
| 3962 | { | 4009 | { | 
| 3963 | int ret = 0; | ||
| 3964 | struct clone_root *found_clone = NULL; | 4010 | struct clone_root *found_clone = NULL; | 
| 4011 | int ret = 0; | ||
| 3965 | 4012 | ||
| 3966 | if (S_ISLNK(sctx->cur_inode_mode)) | 4013 | if (S_ISLNK(sctx->cur_inode_mode)) | 
| 3967 | return 0; | 4014 | return 0; | 
| @@ -3974,6 +4021,32 @@ static int process_extent(struct send_ctx *sctx, | |||
| 3974 | ret = 0; | 4021 | ret = 0; | 
| 3975 | goto out; | 4022 | goto out; | 
| 3976 | } | 4023 | } | 
| 4024 | } else { | ||
| 4025 | struct btrfs_file_extent_item *ei; | ||
| 4026 | u8 type; | ||
| 4027 | |||
| 4028 | ei = btrfs_item_ptr(path->nodes[0], path->slots[0], | ||
| 4029 | struct btrfs_file_extent_item); | ||
| 4030 | type = btrfs_file_extent_type(path->nodes[0], ei); | ||
| 4031 | if (type == BTRFS_FILE_EXTENT_PREALLOC || | ||
| 4032 | type == BTRFS_FILE_EXTENT_REG) { | ||
| 4033 | /* | ||
| 4034 | * The send spec does not have a prealloc command yet, | ||
| 4035 | * so just leave a hole for prealloc'ed extents until | ||
| 4036 | * we have enough commands queued up to justify rev'ing | ||
| 4037 | * the send spec. | ||
| 4038 | */ | ||
| 4039 | if (type == BTRFS_FILE_EXTENT_PREALLOC) { | ||
| 4040 | ret = 0; | ||
| 4041 | goto out; | ||
| 4042 | } | ||
| 4043 | |||
| 4044 | /* Have a hole, just skip it. */ | ||
| 4045 | if (btrfs_file_extent_disk_bytenr(path->nodes[0], ei) == 0) { | ||
| 4046 | ret = 0; | ||
| 4047 | goto out; | ||
| 4048 | } | ||
| 4049 | } | ||
| 3977 | } | 4050 | } | 
| 3978 | 4051 | ||
| 3979 | ret = find_extent_clone(sctx, path, key->objectid, key->offset, | 4052 | ret = find_extent_clone(sctx, path, key->objectid, key->offset, | 
| @@ -4361,6 +4434,64 @@ static int changed_extent(struct send_ctx *sctx, | |||
| 4361 | return ret; | 4434 | return ret; | 
| 4362 | } | 4435 | } | 
| 4363 | 4436 | ||
| 4437 | static int dir_changed(struct send_ctx *sctx, u64 dir) | ||
| 4438 | { | ||
| 4439 | u64 orig_gen, new_gen; | ||
| 4440 | int ret; | ||
| 4441 | |||
| 4442 | ret = get_inode_info(sctx->send_root, dir, NULL, &new_gen, NULL, NULL, | ||
| 4443 | NULL, NULL); | ||
| 4444 | if (ret) | ||
| 4445 | return ret; | ||
| 4446 | |||
| 4447 | ret = get_inode_info(sctx->parent_root, dir, NULL, &orig_gen, NULL, | ||
| 4448 | NULL, NULL, NULL); | ||
| 4449 | if (ret) | ||
| 4450 | return ret; | ||
| 4451 | |||
| 4452 | return (orig_gen != new_gen) ? 1 : 0; | ||
| 4453 | } | ||
| 4454 | |||
| 4455 | static int compare_refs(struct send_ctx *sctx, struct btrfs_path *path, | ||
| 4456 | struct btrfs_key *key) | ||
| 4457 | { | ||
| 4458 | struct btrfs_inode_extref *extref; | ||
| 4459 | struct extent_buffer *leaf; | ||
| 4460 | u64 dirid = 0, last_dirid = 0; | ||
| 4461 | unsigned long ptr; | ||
| 4462 | u32 item_size; | ||
| 4463 | u32 cur_offset = 0; | ||
| 4464 | int ref_name_len; | ||
| 4465 | int ret = 0; | ||
| 4466 | |||
| 4467 | /* Easy case, just check this one dirid */ | ||
| 4468 | if (key->type == BTRFS_INODE_REF_KEY) { | ||
| 4469 | dirid = key->offset; | ||
| 4470 | |||
| 4471 | ret = dir_changed(sctx, dirid); | ||
| 4472 | goto out; | ||
| 4473 | } | ||
| 4474 | |||
| 4475 | leaf = path->nodes[0]; | ||
| 4476 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | ||
| 4477 | ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); | ||
| 4478 | while (cur_offset < item_size) { | ||
| 4479 | extref = (struct btrfs_inode_extref *)(ptr + | ||
| 4480 | cur_offset); | ||
| 4481 | dirid = btrfs_inode_extref_parent(leaf, extref); | ||
| 4482 | ref_name_len = btrfs_inode_extref_name_len(leaf, extref); | ||
| 4483 | cur_offset += ref_name_len + sizeof(*extref); | ||
| 4484 | if (dirid == last_dirid) | ||
| 4485 | continue; | ||
| 4486 | ret = dir_changed(sctx, dirid); | ||
| 4487 | if (ret) | ||
| 4488 | break; | ||
| 4489 | last_dirid = dirid; | ||
| 4490 | } | ||
| 4491 | out: | ||
| 4492 | return ret; | ||
| 4493 | } | ||
| 4494 | |||
| 4364 | /* | 4495 | /* | 
| 4365 | * Updates compare related fields in sctx and simply forwards to the actual | 4496 | * Updates compare related fields in sctx and simply forwards to the actual | 
| 4366 | * changed_xxx functions. | 4497 | * changed_xxx functions. | 
| @@ -4376,6 +4507,19 @@ static int changed_cb(struct btrfs_root *left_root, | |||
| 4376 | int ret = 0; | 4507 | int ret = 0; | 
| 4377 | struct send_ctx *sctx = ctx; | 4508 | struct send_ctx *sctx = ctx; | 
| 4378 | 4509 | ||
| 4510 | if (result == BTRFS_COMPARE_TREE_SAME) { | ||
| 4511 | if (key->type != BTRFS_INODE_REF_KEY && | ||
| 4512 | key->type != BTRFS_INODE_EXTREF_KEY) | ||
| 4513 | return 0; | ||
| 4514 | ret = compare_refs(sctx, left_path, key); | ||
| 4515 | if (!ret) | ||
| 4516 | return 0; | ||
| 4517 | if (ret < 0) | ||
| 4518 | return ret; | ||
| 4519 | result = BTRFS_COMPARE_TREE_CHANGED; | ||
| 4520 | ret = 0; | ||
| 4521 | } | ||
| 4522 | |||
| 4379 | sctx->left_path = left_path; | 4523 | sctx->left_path = left_path; | 
| 4380 | sctx->right_path = right_path; | 4524 | sctx->right_path = right_path; | 
| 4381 | sctx->cmp_key = key; | 4525 | sctx->cmp_key = key; | 
