@@ -1856,7 +1856,7 @@ static int is_first_ref(struct btrfs_root *root,
1856
1856
*/
1857
1857
static int will_overwrite_ref (struct send_ctx * sctx , u64 dir , u64 dir_gen ,
1858
1858
const char * name , int name_len ,
1859
- u64 * who_ino , u64 * who_gen )
1859
+ u64 * who_ino , u64 * who_gen , u64 * who_mode )
1860
1860
{
1861
1861
int ret = 0 ;
1862
1862
u64 gen ;
@@ -1905,7 +1905,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
1905
1905
if (other_inode > sctx -> send_progress ||
1906
1906
is_waiting_for_move (sctx , other_inode )) {
1907
1907
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 );
1909
1909
if (ret < 0 )
1910
1910
goto out ;
1911
1911
@@ -3683,6 +3683,36 @@ static int wait_for_parent_move(struct send_ctx *sctx,
3683
3683
return ret ;
3684
3684
}
3685
3685
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
+
3686
3716
/*
3687
3717
* This does all the move/link/unlink/rmdir magic.
3688
3718
*/
@@ -3696,10 +3726,12 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
3696
3726
struct fs_path * valid_path = NULL ;
3697
3727
u64 ow_inode = 0 ;
3698
3728
u64 ow_gen ;
3729
+ u64 ow_mode ;
3699
3730
int did_overwrite = 0 ;
3700
3731
int is_orphan = 0 ;
3701
3732
u64 last_dir_ino_rm = 0 ;
3702
3733
bool can_rename = true;
3734
+ bool orphanized_dir = false;
3703
3735
bool orphanized_ancestor = false;
3704
3736
3705
3737
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)
3798
3830
*/
3799
3831
ret = will_overwrite_ref (sctx , cur -> dir , cur -> dir_gen ,
3800
3832
cur -> name , cur -> name_len ,
3801
- & ow_inode , & ow_gen );
3833
+ & ow_inode , & ow_gen , & ow_mode );
3802
3834
if (ret < 0 )
3803
3835
goto out ;
3804
3836
if (ret ) {
@@ -3815,6 +3847,8 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
3815
3847
cur -> full_path );
3816
3848
if (ret < 0 )
3817
3849
goto out ;
3850
+ if (S_ISDIR (ow_mode ))
3851
+ orphanized_dir = true;
3818
3852
3819
3853
/*
3820
3854
* If ow_inode has its rename operation delayed
@@ -3920,6 +3954,18 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
3920
3954
if (ret < 0 )
3921
3955
goto out ;
3922
3956
} 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
+ }
3923
3969
ret = send_link (sctx , cur -> full_path ,
3924
3970
valid_path );
3925
3971
if (ret < 0 )
@@ -3990,34 +4036,9 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
3990
4036
* ancestor inode.
3991
4037
*/
3992
4038
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 )
4017
4041
goto out ;
4018
- }
4019
- fs_path_free (cur -> full_path );
4020
- set_ref_path (cur , new_path );
4021
4042
}
4022
4043
ret = send_unlink (sctx , cur -> full_path );
4023
4044
if (ret < 0 )
@@ -5249,15 +5270,12 @@ static int is_extent_unchanged(struct send_ctx *sctx,
5249
5270
goto out ;
5250
5271
}
5251
5272
5252
- right_disknr = btrfs_file_extent_disk_bytenr (eb , ei );
5253
5273
if (right_type == BTRFS_FILE_EXTENT_INLINE ) {
5254
5274
right_len = btrfs_file_extent_inline_len (eb , slot , ei );
5255
5275
right_len = PAGE_ALIGN (right_len );
5256
5276
} else {
5257
5277
right_len = btrfs_file_extent_num_bytes (eb , ei );
5258
5278
}
5259
- right_offset = btrfs_file_extent_offset (eb , ei );
5260
- right_gen = btrfs_file_extent_generation (eb , ei );
5261
5279
5262
5280
/*
5263
5281
* 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,
5282
5300
goto out ;
5283
5301
}
5284
5302
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
+
5285
5307
left_offset_fixed = left_offset ;
5286
5308
if (key .offset < ekey -> offset ) {
5287
5309
/* Fix the right offset for 2a and 7. */
0 commit comments