@@ -1856,7 +1856,7 @@ static int is_first_ref(struct btrfs_root *root,
18561856 */
18571857static int will_overwrite_ref (struct send_ctx * sctx , u64 dir , u64 dir_gen ,
18581858 const char * name , int name_len ,
1859- u64 * who_ino , u64 * who_gen )
1859+ u64 * who_ino , u64 * who_gen , u64 * who_mode )
18601860{
18611861 int ret = 0 ;
18621862 u64 gen ;
@@ -1905,7 +1905,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
19051905 if (other_inode > sctx -> send_progress ||
19061906 is_waiting_for_move (sctx , other_inode )) {
19071907 ret = get_inode_info (sctx -> parent_root , other_inode , NULL ,
1908- who_gen , NULL , NULL , NULL , NULL );
1908+ who_gen , who_mode , NULL , NULL , NULL );
19091909 if (ret < 0 )
19101910 goto out ;
19111911
@@ -3683,6 +3683,36 @@ static int wait_for_parent_move(struct send_ctx *sctx,
36833683 return ret ;
36843684}
36853685
3686+ static int update_ref_path (struct send_ctx * sctx , struct recorded_ref * ref )
3687+ {
3688+ int ret ;
3689+ struct fs_path * new_path ;
3690+
3691+ /*
3692+ * Our reference's name member points to its full_path member string, so
3693+ * we use here a new path.
3694+ */
3695+ new_path = fs_path_alloc ();
3696+ if (!new_path )
3697+ return - ENOMEM ;
3698+
3699+ ret = get_cur_path (sctx , ref -> dir , ref -> dir_gen , new_path );
3700+ if (ret < 0 ) {
3701+ fs_path_free (new_path );
3702+ return ret ;
3703+ }
3704+ ret = fs_path_add (new_path , ref -> name , ref -> name_len );
3705+ if (ret < 0 ) {
3706+ fs_path_free (new_path );
3707+ return ret ;
3708+ }
3709+
3710+ fs_path_free (ref -> full_path );
3711+ set_ref_path (ref , new_path );
3712+
3713+ return 0 ;
3714+ }
3715+
36863716/*
36873717 * This does all the move/link/unlink/rmdir magic.
36883718 */
@@ -3696,10 +3726,12 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
36963726 struct fs_path * valid_path = NULL ;
36973727 u64 ow_inode = 0 ;
36983728 u64 ow_gen ;
3729+ u64 ow_mode ;
36993730 int did_overwrite = 0 ;
37003731 int is_orphan = 0 ;
37013732 u64 last_dir_ino_rm = 0 ;
37023733 bool can_rename = true;
3734+ bool orphanized_dir = false;
37033735 bool orphanized_ancestor = false;
37043736
37053737 btrfs_debug (fs_info , "process_recorded_refs %llu" , sctx -> cur_ino );
@@ -3798,7 +3830,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
37983830 */
37993831 ret = will_overwrite_ref (sctx , cur -> dir , cur -> dir_gen ,
38003832 cur -> name , cur -> name_len ,
3801- & ow_inode , & ow_gen );
3833+ & ow_inode , & ow_gen , & ow_mode );
38023834 if (ret < 0 )
38033835 goto out ;
38043836 if (ret ) {
@@ -3815,6 +3847,8 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
38153847 cur -> full_path );
38163848 if (ret < 0 )
38173849 goto out ;
3850+ if (S_ISDIR (ow_mode ))
3851+ orphanized_dir = true;
38183852
38193853 /*
38203854 * If ow_inode has its rename operation delayed
@@ -3920,6 +3954,18 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
39203954 if (ret < 0 )
39213955 goto out ;
39223956 } else {
3957+ /*
3958+ * We might have previously orphanized an inode
3959+ * which is an ancestor of our current inode,
3960+ * so our reference's full path, which was
3961+ * computed before any such orphanizations, must
3962+ * be updated.
3963+ */
3964+ if (orphanized_dir ) {
3965+ ret = update_ref_path (sctx , cur );
3966+ if (ret < 0 )
3967+ goto out ;
3968+ }
39233969 ret = send_link (sctx , cur -> full_path ,
39243970 valid_path );
39253971 if (ret < 0 )
@@ -3990,34 +4036,9 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
39904036 * ancestor inode.
39914037 */
39924038 if (orphanized_ancestor ) {
3993- struct fs_path * new_path ;
3994-
3995- /*
3996- * Our reference's name member points to
3997- * its full_path member string, so we
3998- * use here a new path.
3999- */
4000- new_path = fs_path_alloc ();
4001- if (!new_path ) {
4002- ret = - ENOMEM ;
4003- goto out ;
4004- }
4005- ret = get_cur_path (sctx , cur -> dir ,
4006- cur -> dir_gen ,
4007- new_path );
4008- if (ret < 0 ) {
4009- fs_path_free (new_path );
4010- goto out ;
4011- }
4012- ret = fs_path_add (new_path ,
4013- cur -> name ,
4014- cur -> name_len );
4015- if (ret < 0 ) {
4016- fs_path_free (new_path );
4039+ ret = update_ref_path (sctx , cur );
4040+ if (ret < 0 )
40174041 goto out ;
4018- }
4019- fs_path_free (cur -> full_path );
4020- set_ref_path (cur , new_path );
40214042 }
40224043 ret = send_unlink (sctx , cur -> full_path );
40234044 if (ret < 0 )
@@ -5249,15 +5270,12 @@ static int is_extent_unchanged(struct send_ctx *sctx,
52495270 goto out ;
52505271 }
52515272
5252- right_disknr = btrfs_file_extent_disk_bytenr (eb , ei );
52535273 if (right_type == BTRFS_FILE_EXTENT_INLINE ) {
52545274 right_len = btrfs_file_extent_inline_len (eb , slot , ei );
52555275 right_len = PAGE_ALIGN (right_len );
52565276 } else {
52575277 right_len = btrfs_file_extent_num_bytes (eb , ei );
52585278 }
5259- right_offset = btrfs_file_extent_offset (eb , ei );
5260- right_gen = btrfs_file_extent_generation (eb , ei );
52615279
52625280 /*
52635281 * Are we at extent 8? If yes, we know the extent is changed.
@@ -5282,6 +5300,10 @@ static int is_extent_unchanged(struct send_ctx *sctx,
52825300 goto out ;
52835301 }
52845302
5303+ right_disknr = btrfs_file_extent_disk_bytenr (eb , ei );
5304+ right_offset = btrfs_file_extent_offset (eb , ei );
5305+ right_gen = btrfs_file_extent_generation (eb , ei );
5306+
52855307 left_offset_fixed = left_offset ;
52865308 if (key .offset < ekey -> offset ) {
52875309 /* Fix the right offset for 2a and 7. */
0 commit comments