@@ -1102,49 +1102,30 @@ struct ovl_renamedata {
11021102 bool overwrite ;
11031103};
11041104
1105- static int ovl_rename (struct mnt_idmap * idmap , struct inode * olddir ,
1106- struct dentry * old , struct inode * newdir ,
1107- struct dentry * new , unsigned int flags )
1105+ static int ovl_rename_start (struct ovl_renamedata * ovlrd , struct list_head * list )
11081106{
1109- int err ;
1110- struct dentry * old_upperdir ;
1111- struct dentry * new_upperdir ;
1112- struct renamedata rd = {};
1113- bool old_opaque ;
1114- bool new_opaque ;
1107+ struct dentry * old = ovlrd -> old_dentry ;
1108+ struct dentry * new = ovlrd -> new_dentry ;
11151109 bool is_dir = d_is_dir (old );
11161110 bool new_is_dir = d_is_dir (new );
1117- bool samedir = old -> d_parent == new -> d_parent ;
1118- struct dentry * whiteout = NULL ;
1119- const struct cred * old_cred = NULL ;
1120- struct ovl_fs * ofs = OVL_FS (old -> d_sb );
1121- struct ovl_renamedata _ovlrd = {
1122- .old_dentry = old ,
1123- .new_dentry = new ,
1124- .flags = flags ,
1125- .cleanup_whiteout = false,
1126- .overwrite = !(flags & RENAME_EXCHANGE ),
1127- };
1128- struct ovl_renamedata * ovlrd = & _ovlrd ;
1129- LIST_HEAD (list );
1111+ int err ;
11301112
1131- err = - EINVAL ;
11321113 if (ovlrd -> flags & ~(RENAME_EXCHANGE | RENAME_NOREPLACE ))
1133- goto out ;
1114+ return - EINVAL ;
11341115
11351116 ovlrd -> flags &= ~RENAME_NOREPLACE ;
11361117
11371118 /* Don't copy up directory trees */
11381119 err = - EXDEV ;
11391120 if (!ovl_can_move (old ))
1140- goto out ;
1121+ return err ;
11411122 if (!ovlrd -> overwrite && !ovl_can_move (new ))
1142- goto out ;
1123+ return err ;
11431124
11441125 if (ovlrd -> overwrite && new_is_dir && !ovl_pure_upper (new )) {
1145- err = ovl_check_empty_dir (new , & list );
1126+ err = ovl_check_empty_dir (new , list );
11461127 if (err )
1147- goto out ;
1128+ return err ;
11481129 }
11491130
11501131 if (ovlrd -> overwrite ) {
@@ -1164,19 +1145,20 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir,
11641145
11651146 err = ovl_copy_up (old );
11661147 if (err )
1167- goto out ;
1148+ return err ;
11681149
11691150 err = ovl_copy_up (new -> d_parent );
11701151 if (err )
1171- goto out ;
1152+ return err ;
1153+
11721154 if (!ovlrd -> overwrite ) {
11731155 err = ovl_copy_up (new );
11741156 if (err )
1175- goto out ;
1157+ return err ;
11761158 } else if (d_inode (new )) {
11771159 err = ovl_nlink_start (new );
11781160 if (err )
1179- goto out ;
1161+ return err ;
11801162
11811163 ovlrd -> update_nlink = true;
11821164 }
@@ -1185,22 +1167,34 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir,
11851167 /* ovl_nlink_start() took ovl_want_write() */
11861168 err = ovl_want_write (old );
11871169 if (err )
1188- goto out ;
1170+ return err ;
11891171 }
11901172
1191- old_cred = ovl_override_creds (old -> d_sb );
1173+ return 0 ;
1174+ }
11921175
1193- if (!list_empty (& list )) {
1194- ovlrd -> opaquedir = ovl_clear_empty (new , & list );
1195- err = PTR_ERR (ovlrd -> opaquedir );
1196- if (IS_ERR (ovlrd -> opaquedir )) {
1197- ovlrd -> opaquedir = NULL ;
1198- goto out_revert_creds ;
1199- }
1200- }
1176+ static int ovl_rename_upper (struct ovl_renamedata * ovlrd , struct list_head * list )
1177+ {
1178+ struct dentry * old = ovlrd -> old_dentry ;
1179+ struct dentry * new = ovlrd -> new_dentry ;
1180+ struct ovl_fs * ofs = OVL_FS (old -> d_sb );
1181+ struct dentry * old_upperdir = ovl_dentry_upper (old -> d_parent );
1182+ struct dentry * new_upperdir = ovl_dentry_upper (new -> d_parent );
1183+ bool is_dir = d_is_dir (old );
1184+ bool new_is_dir = d_is_dir (new );
1185+ bool samedir = old -> d_parent == new -> d_parent ;
1186+ struct renamedata rd = {};
1187+ struct dentry * de ;
1188+ struct dentry * whiteout = NULL ;
1189+ bool old_opaque , new_opaque ;
1190+ int err ;
12011191
1202- old_upperdir = ovl_dentry_upper (old -> d_parent );
1203- new_upperdir = ovl_dentry_upper (new -> d_parent );
1192+ if (!list_empty (list )) {
1193+ de = ovl_clear_empty (new , list );
1194+ if (IS_ERR (de ))
1195+ return PTR_ERR (de );
1196+ ovlrd -> opaquedir = de ;
1197+ }
12041198
12051199 if (!samedir ) {
12061200 /*
@@ -1212,12 +1206,12 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir,
12121206 if (ovl_type_origin (old )) {
12131207 err = ovl_set_impure (new -> d_parent , new_upperdir );
12141208 if (err )
1215- goto out_revert_creds ;
1209+ return err ;
12161210 }
12171211 if (!ovlrd -> overwrite && ovl_type_origin (new )) {
12181212 err = ovl_set_impure (old -> d_parent , old_upperdir );
12191213 if (err )
1220- goto out_revert_creds ;
1214+ return err ;
12211215 }
12221216 }
12231217
@@ -1229,9 +1223,8 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir,
12291223 err = start_renaming (& rd , 0 ,
12301224 & QSTR_LEN (old -> d_name .name , old -> d_name .len ),
12311225 & QSTR_LEN (new -> d_name .name , new -> d_name .len ));
1232-
12331226 if (err )
1234- goto out_revert_creds ;
1227+ return err ;
12351228
12361229 err = - ESTALE ;
12371230 if (!ovl_matches_upper (old , rd .old_dentry ))
@@ -1283,10 +1276,11 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir,
12831276 if (!err && ovlrd -> cleanup_whiteout )
12841277 whiteout = dget (rd .new_dentry );
12851278
1279+ out_unlock :
12861280 end_renaming (& rd );
12871281
12881282 if (err )
1289- goto out_revert_creds ;
1283+ return err ;
12901284
12911285 if (whiteout ) {
12921286 ovl_cleanup (ofs , old_upperdir , whiteout );
@@ -1310,20 +1304,47 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir,
13101304 if (d_inode (new ) && ovl_dentry_upper (new ))
13111305 ovl_copyattr (d_inode (new ));
13121306
1313- out_revert_creds :
1314- ovl_revert_creds (old_cred );
1307+ return err ;
1308+ }
1309+
1310+ static void ovl_rename_end (struct ovl_renamedata * ovlrd )
1311+ {
13151312 if (ovlrd -> update_nlink )
1316- ovl_nlink_end (new );
1313+ ovl_nlink_end (ovlrd -> new_dentry );
13171314 else
1318- ovl_drop_write (old );
1315+ ovl_drop_write (ovlrd -> old_dentry );
1316+ }
1317+
1318+ static int ovl_rename (struct mnt_idmap * idmap , struct inode * olddir ,
1319+ struct dentry * old , struct inode * newdir ,
1320+ struct dentry * new , unsigned int flags )
1321+ {
1322+ const struct cred * old_cred = NULL ;
1323+ struct ovl_renamedata ovlrd = {
1324+ .old_parent = old -> d_parent ,
1325+ .old_dentry = old ,
1326+ .new_parent = new -> d_parent ,
1327+ .new_dentry = new ,
1328+ .flags = flags ,
1329+ .overwrite = !(flags & RENAME_EXCHANGE ),
1330+ };
1331+ LIST_HEAD (list );
1332+ int err ;
1333+
1334+ err = ovl_rename_start (& ovlrd , & list );
1335+ if (err )
1336+ goto out ;
1337+
1338+ old_cred = ovl_override_creds (old -> d_sb );
1339+
1340+ err = ovl_rename_upper (& ovlrd , & list );
1341+
1342+ ovl_revert_creds (old_cred );
1343+ ovl_rename_end (& ovlrd );
13191344out :
13201345 dput (ovlrd -> opaquedir );
13211346 ovl_cache_free (& list );
13221347 return err ;
1323-
1324- out_unlock :
1325- end_renaming (& rd );
1326- goto out_revert_creds ;
13271348}
13281349
13291350static int ovl_create_tmpfile (struct file * file , struct dentry * dentry ,
0 commit comments