@@ -3813,10 +3813,20 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
3813
3813
return retval ;
3814
3814
}
3815
3815
3816
+ /*
3817
+ * We need to protect against old.inode directory getting converted
3818
+ * from inline directory format into a normal one.
3819
+ */
3820
+ if (S_ISDIR (old .inode -> i_mode ))
3821
+ inode_lock_nested (old .inode , I_MUTEX_NONDIR2 );
3822
+
3816
3823
old .bh = ext4_find_entry (old .dir , & old .dentry -> d_name , & old .de ,
3817
3824
& old .inlined );
3818
- if (IS_ERR (old .bh ))
3819
- return PTR_ERR (old .bh );
3825
+ if (IS_ERR (old .bh )) {
3826
+ retval = PTR_ERR (old .bh );
3827
+ goto unlock_moved_dir ;
3828
+ }
3829
+
3820
3830
/*
3821
3831
* Check for inode number is _not_ due to possible IO errors.
3822
3832
* We might rmdir the source, keep it as pwd of some process
@@ -3873,11 +3883,6 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
3873
3883
if (new .dir != old .dir && EXT4_DIR_LINK_MAX (new .dir ))
3874
3884
goto end_rename ;
3875
3885
}
3876
- /*
3877
- * We need to protect against old.inode directory getting
3878
- * converted from inline directory format into a normal one.
3879
- */
3880
- inode_lock_nested (old .inode , I_MUTEX_NONDIR2 );
3881
3886
retval = ext4_rename_dir_prepare (handle , & old );
3882
3887
if (retval ) {
3883
3888
inode_unlock (old .inode );
@@ -4014,12 +4019,15 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
4014
4019
} else {
4015
4020
ext4_journal_stop (handle );
4016
4021
}
4017
- if (old .dir_bh )
4018
- inode_unlock (old .inode );
4019
4022
release_bh :
4020
4023
brelse (old .dir_bh );
4021
4024
brelse (old .bh );
4022
4025
brelse (new .bh );
4026
+
4027
+ unlock_moved_dir :
4028
+ if (S_ISDIR (old .inode -> i_mode ))
4029
+ inode_unlock (old .inode );
4030
+
4023
4031
return retval ;
4024
4032
}
4025
4033
0 commit comments