diff options
Diffstat (limited to 'fs/btrfs/send.c')
| -rw-r--r-- | fs/btrfs/send.c | 171 |
1 files changed, 156 insertions, 15 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index fe5857223515..d6033f540cc7 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
| @@ -230,6 +230,7 @@ struct pending_dir_move { | |||
| 230 | u64 parent_ino; | 230 | u64 parent_ino; |
| 231 | u64 ino; | 231 | u64 ino; |
| 232 | u64 gen; | 232 | u64 gen; |
| 233 | bool is_orphan; | ||
| 233 | struct list_head update_refs; | 234 | struct list_head update_refs; |
| 234 | }; | 235 | }; |
| 235 | 236 | ||
| @@ -2984,7 +2985,8 @@ static int add_pending_dir_move(struct send_ctx *sctx, | |||
| 2984 | u64 ino_gen, | 2985 | u64 ino_gen, |
| 2985 | u64 parent_ino, | 2986 | u64 parent_ino, |
| 2986 | struct list_head *new_refs, | 2987 | struct list_head *new_refs, |
| 2987 | struct list_head *deleted_refs) | 2988 | struct list_head *deleted_refs, |
| 2989 | const bool is_orphan) | ||
| 2988 | { | 2990 | { |
| 2989 | struct rb_node **p = &sctx->pending_dir_moves.rb_node; | 2991 | struct rb_node **p = &sctx->pending_dir_moves.rb_node; |
| 2990 | struct rb_node *parent = NULL; | 2992 | struct rb_node *parent = NULL; |
| @@ -2999,6 +3001,7 @@ static int add_pending_dir_move(struct send_ctx *sctx, | |||
| 2999 | pm->parent_ino = parent_ino; | 3001 | pm->parent_ino = parent_ino; |
| 3000 | pm->ino = ino; | 3002 | pm->ino = ino; |
| 3001 | pm->gen = ino_gen; | 3003 | pm->gen = ino_gen; |
| 3004 | pm->is_orphan = is_orphan; | ||
| 3002 | INIT_LIST_HEAD(&pm->list); | 3005 | INIT_LIST_HEAD(&pm->list); |
| 3003 | INIT_LIST_HEAD(&pm->update_refs); | 3006 | INIT_LIST_HEAD(&pm->update_refs); |
| 3004 | RB_CLEAR_NODE(&pm->node); | 3007 | RB_CLEAR_NODE(&pm->node); |
| @@ -3131,16 +3134,20 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) | |||
| 3131 | rmdir_ino = dm->rmdir_ino; | 3134 | rmdir_ino = dm->rmdir_ino; |
| 3132 | free_waiting_dir_move(sctx, dm); | 3135 | free_waiting_dir_move(sctx, dm); |
| 3133 | 3136 | ||
| 3134 | ret = get_first_ref(sctx->parent_root, pm->ino, | 3137 | if (pm->is_orphan) { |
| 3135 | &parent_ino, &parent_gen, name); | 3138 | ret = gen_unique_name(sctx, pm->ino, |
| 3136 | if (ret < 0) | 3139 | pm->gen, from_path); |
| 3137 | goto out; | 3140 | } else { |
| 3138 | 3141 | ret = get_first_ref(sctx->parent_root, pm->ino, | |
| 3139 | ret = get_cur_path(sctx, parent_ino, parent_gen, | 3142 | &parent_ino, &parent_gen, name); |
| 3140 | from_path); | 3143 | if (ret < 0) |
| 3141 | if (ret < 0) | 3144 | goto out; |
| 3142 | goto out; | 3145 | ret = get_cur_path(sctx, parent_ino, parent_gen, |
| 3143 | ret = fs_path_add_path(from_path, name); | 3146 | from_path); |
| 3147 | if (ret < 0) | ||
| 3148 | goto out; | ||
| 3149 | ret = fs_path_add_path(from_path, name); | ||
| 3150 | } | ||
| 3144 | if (ret < 0) | 3151 | if (ret < 0) |
| 3145 | goto out; | 3152 | goto out; |
| 3146 | 3153 | ||
| @@ -3150,7 +3157,8 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) | |||
| 3150 | LIST_HEAD(deleted_refs); | 3157 | LIST_HEAD(deleted_refs); |
| 3151 | ASSERT(ancestor > BTRFS_FIRST_FREE_OBJECTID); | 3158 | ASSERT(ancestor > BTRFS_FIRST_FREE_OBJECTID); |
| 3152 | ret = add_pending_dir_move(sctx, pm->ino, pm->gen, ancestor, | 3159 | ret = add_pending_dir_move(sctx, pm->ino, pm->gen, ancestor, |
| 3153 | &pm->update_refs, &deleted_refs); | 3160 | &pm->update_refs, &deleted_refs, |
| 3161 | pm->is_orphan); | ||
| 3154 | if (ret < 0) | 3162 | if (ret < 0) |
| 3155 | goto out; | 3163 | goto out; |
| 3156 | if (rmdir_ino) { | 3164 | if (rmdir_ino) { |
| @@ -3283,6 +3291,127 @@ out: | |||
| 3283 | return ret; | 3291 | return ret; |
| 3284 | } | 3292 | } |
| 3285 | 3293 | ||
| 3294 | /* | ||
| 3295 | * We might need to delay a directory rename even when no ancestor directory | ||
| 3296 | * (in the send root) with a higher inode number than ours (sctx->cur_ino) was | ||
| 3297 | * renamed. This happens when we rename a directory to the old name (the name | ||
| 3298 | * in the parent root) of some other unrelated directory that got its rename | ||
| 3299 | * delayed due to some ancestor with higher number that got renamed. | ||
| 3300 | * | ||
| 3301 | * Example: | ||
| 3302 | * | ||
| 3303 | * Parent snapshot: | ||
| 3304 | * . (ino 256) | ||
| 3305 | * |---- a/ (ino 257) | ||
| 3306 | * | |---- file (ino 260) | ||
| 3307 | * | | ||
| 3308 | * |---- b/ (ino 258) | ||
| 3309 | * |---- c/ (ino 259) | ||
| 3310 | * | ||
| 3311 | * Send snapshot: | ||
| 3312 | * . (ino 256) | ||
| 3313 | * |---- a/ (ino 258) | ||
| 3314 | * |---- x/ (ino 259) | ||
| 3315 | * |---- y/ (ino 257) | ||
| 3316 | * |----- file (ino 260) | ||
| 3317 | * | ||
| 3318 | * Here we can not rename 258 from 'b' to 'a' without the rename of inode 257 | ||
| 3319 | * from 'a' to 'x/y' happening first, which in turn depends on the rename of | ||
| 3320 | * inode 259 from 'c' to 'x'. So the order of rename commands the send stream | ||
| 3321 | * must issue is: | ||
| 3322 | * | ||
| 3323 | * 1 - rename 259 from 'c' to 'x' | ||
| 3324 | * 2 - rename 257 from 'a' to 'x/y' | ||
| 3325 | * 3 - rename 258 from 'b' to 'a' | ||
| 3326 | * | ||
| 3327 | * Returns 1 if the rename of sctx->cur_ino needs to be delayed, 0 if it can | ||
| 3328 | * be done right away and < 0 on error. | ||
| 3329 | */ | ||
| 3330 | static int wait_for_dest_dir_move(struct send_ctx *sctx, | ||
| 3331 | struct recorded_ref *parent_ref, | ||
| 3332 | const bool is_orphan) | ||
| 3333 | { | ||
| 3334 | struct btrfs_path *path; | ||
| 3335 | struct btrfs_key key; | ||
| 3336 | struct btrfs_key di_key; | ||
| 3337 | struct btrfs_dir_item *di; | ||
| 3338 | u64 left_gen; | ||
| 3339 | u64 right_gen; | ||
| 3340 | int ret = 0; | ||
| 3341 | |||
| 3342 | if (RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) | ||
| 3343 | return 0; | ||
| 3344 | |||
| 3345 | path = alloc_path_for_send(); | ||
| 3346 | if (!path) | ||
| 3347 | return -ENOMEM; | ||
| 3348 | |||
| 3349 | key.objectid = parent_ref->dir; | ||
| 3350 | key.type = BTRFS_DIR_ITEM_KEY; | ||
| 3351 | key.offset = btrfs_name_hash(parent_ref->name, parent_ref->name_len); | ||
| 3352 | |||
| 3353 | ret = btrfs_search_slot(NULL, sctx->parent_root, &key, path, 0, 0); | ||
| 3354 | if (ret < 0) { | ||
| 3355 | goto out; | ||
| 3356 | } else if (ret > 0) { | ||
| 3357 | ret = 0; | ||
| 3358 | goto out; | ||
| 3359 | } | ||
| 3360 | |||
| 3361 | di = btrfs_match_dir_item_name(sctx->parent_root, path, | ||
| 3362 | parent_ref->name, parent_ref->name_len); | ||
| 3363 | if (!di) { | ||
| 3364 | ret = 0; | ||
| 3365 | goto out; | ||
| 3366 | } | ||
| 3367 | /* | ||
| 3368 | * di_key.objectid has the number of the inode that has a dentry in the | ||
| 3369 | * parent directory with the same name that sctx->cur_ino is being | ||
| 3370 | * renamed to. We need to check if that inode is in the send root as | ||
| 3371 | * well and if it is currently marked as an inode with a pending rename, | ||
| 3372 | * if it is, we need to delay the rename of sctx->cur_ino as well, so | ||
| 3373 | * that it happens after that other inode is renamed. | ||
| 3374 | */ | ||
| 3375 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, &di_key); | ||
| 3376 | if (di_key.type != BTRFS_INODE_ITEM_KEY) { | ||
| 3377 | ret = 0; | ||
| 3378 | goto out; | ||
| 3379 | } | ||
| 3380 | |||
| 3381 | ret = get_inode_info(sctx->parent_root, di_key.objectid, NULL, | ||
| 3382 | &left_gen, NULL, NULL, NULL, NULL); | ||
| 3383 | if (ret < 0) | ||
| 3384 | goto out; | ||
| 3385 | ret = get_inode_info(sctx->send_root, di_key.objectid, NULL, | ||
| 3386 | &right_gen, NULL, NULL, NULL, NULL); | ||
| 3387 | if (ret < 0) { | ||
| 3388 | if (ret == -ENOENT) | ||
| 3389 | ret = 0; | ||
| 3390 | goto out; | ||
| 3391 | } | ||
| 3392 | |||
| 3393 | /* Different inode, no need to delay the rename of sctx->cur_ino */ | ||
| 3394 | if (right_gen != left_gen) { | ||
| 3395 | ret = 0; | ||
| 3396 | goto out; | ||
| 3397 | } | ||
| 3398 | |||
| 3399 | if (is_waiting_for_move(sctx, di_key.objectid)) { | ||
| 3400 | ret = add_pending_dir_move(sctx, | ||
| 3401 | sctx->cur_ino, | ||
| 3402 | sctx->cur_inode_gen, | ||
| 3403 | di_key.objectid, | ||
| 3404 | &sctx->new_refs, | ||
| 3405 | &sctx->deleted_refs, | ||
| 3406 | is_orphan); | ||
| 3407 | if (!ret) | ||
| 3408 | ret = 1; | ||
| 3409 | } | ||
| 3410 | out: | ||
| 3411 | btrfs_free_path(path); | ||
| 3412 | return ret; | ||
| 3413 | } | ||
| 3414 | |||
| 3286 | static int wait_for_parent_move(struct send_ctx *sctx, | 3415 | static int wait_for_parent_move(struct send_ctx *sctx, |
| 3287 | struct recorded_ref *parent_ref) | 3416 | struct recorded_ref *parent_ref) |
| 3288 | { | 3417 | { |
| @@ -3349,7 +3478,8 @@ out: | |||
| 3349 | sctx->cur_inode_gen, | 3478 | sctx->cur_inode_gen, |
| 3350 | ino, | 3479 | ino, |
| 3351 | &sctx->new_refs, | 3480 | &sctx->new_refs, |
| 3352 | &sctx->deleted_refs); | 3481 | &sctx->deleted_refs, |
| 3482 | false); | ||
| 3353 | if (!ret) | 3483 | if (!ret) |
| 3354 | ret = 1; | 3484 | ret = 1; |
| 3355 | } | 3485 | } |
| @@ -3372,6 +3502,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) | |||
| 3372 | int did_overwrite = 0; | 3502 | int did_overwrite = 0; |
| 3373 | int is_orphan = 0; | 3503 | int is_orphan = 0; |
| 3374 | u64 last_dir_ino_rm = 0; | 3504 | u64 last_dir_ino_rm = 0; |
| 3505 | bool can_rename = true; | ||
| 3375 | 3506 | ||
| 3376 | verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | 3507 | verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); |
| 3377 | 3508 | ||
| @@ -3490,12 +3621,22 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 3490 | } | 3621 | } |
| 3491 | } | 3622 | } |
| 3492 | 3623 | ||
| 3624 | if (S_ISDIR(sctx->cur_inode_mode) && sctx->parent_root) { | ||
| 3625 | ret = wait_for_dest_dir_move(sctx, cur, is_orphan); | ||
| 3626 | if (ret < 0) | ||
| 3627 | goto out; | ||
| 3628 | if (ret == 1) { | ||
| 3629 | can_rename = false; | ||
| 3630 | *pending_move = 1; | ||
| 3631 | } | ||
| 3632 | } | ||
| 3633 | |||
| 3493 | /* | 3634 | /* |
| 3494 | * link/move the ref to the new place. If we have an orphan | 3635 | * link/move the ref to the new place. If we have an orphan |
| 3495 | * inode, move it and update valid_path. If not, link or move | 3636 | * inode, move it and update valid_path. If not, link or move |
| 3496 | * it depending on the inode mode. | 3637 | * it depending on the inode mode. |
| 3497 | */ | 3638 | */ |
| 3498 | if (is_orphan) { | 3639 | if (is_orphan && can_rename) { |
| 3499 | ret = send_rename(sctx, valid_path, cur->full_path); | 3640 | ret = send_rename(sctx, valid_path, cur->full_path); |
| 3500 | if (ret < 0) | 3641 | if (ret < 0) |
| 3501 | goto out; | 3642 | goto out; |
| @@ -3503,7 +3644,7 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 3503 | ret = fs_path_copy(valid_path, cur->full_path); | 3644 | ret = fs_path_copy(valid_path, cur->full_path); |
| 3504 | if (ret < 0) | 3645 | if (ret < 0) |
| 3505 | goto out; | 3646 | goto out; |
| 3506 | } else { | 3647 | } else if (can_rename) { |
| 3507 | if (S_ISDIR(sctx->cur_inode_mode)) { | 3648 | if (S_ISDIR(sctx->cur_inode_mode)) { |
| 3508 | /* | 3649 | /* |
| 3509 | * Dirs can't be linked, so move it. For moved | 3650 | * Dirs can't be linked, so move it. For moved |
