diff mbox series

[17/20] udf: Convert udf_rename() to new directory iteration code

Message ID 20221216152656.6236-17-jack@suse.cz (mailing list archive)
State New, archived
Headers show
Series udf: Fix various syzbot reports | expand

Commit Message

Jan Kara Dec. 16, 2022, 3:24 p.m. UTC
Convert udf_rename() to use new directory iteration code.

Reported-by: syzbot+0eaad3590d65102b9391@syzkaller.appspotmail.com
Reported-by: syzbot+b7fc73213bc2361ab650@syzkaller.appspotmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/udf/namei.c | 165 +++++++++++++++++++++++--------------------------
 1 file changed, 78 insertions(+), 87 deletions(-)

Comments

kernel test robot Dec. 16, 2022, 5:22 p.m. UTC | #1
Hi Jan,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on next-20221216]
[cannot apply to v6.1]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Jan-Kara/udf-Fix-various-syzbot-reports/20221216-232952
patch link:    https://lore.kernel.org/r/20221216152656.6236-17-jack%40suse.cz
patch subject: [PATCH 17/20] udf: Convert udf_rename() to new directory iteration code
config: m68k-allmodconfig
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/54711e9617a9ee8205a88ce6ed78daacc4e59362
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Jan-Kara/udf-Fix-various-syzbot-reports/20221216-232952
        git checkout 54711e9617a9ee8205a88ce6ed78daacc4e59362
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash fs/udf/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   fs/udf/namei.c:830:12: warning: 'udf_delete_entry' defined but not used [-Wunused-function]
     830 | static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
         |            ^~~~~~~~~~~~~~~~
   fs/udf/namei.c:581:30: warning: 'udf_add_entry' defined but not used [-Wunused-function]
     581 | static struct fileIdentDesc *udf_add_entry(struct inode *dir,
         |                              ^~~~~~~~~~~~~
   fs/udf/namei.c:229:30: warning: 'udf_find_entry' defined but not used [-Wunused-function]
     229 | static struct fileIdentDesc *udf_find_entry(struct inode *dir,
         |                              ^~~~~~~~~~~~~~
   fs/udf/namei.c: In function 'udf_rename':
>> fs/udf/namei.c:1383:1: warning: the frame size of 1076 bytes is larger than 1024 bytes [-Wframe-larger-than=]
    1383 | }
         | ^


vim +1383 fs/udf/namei.c

^1da177e4c3f41 Linus Torvalds    2005-04-16  1246  
^1da177e4c3f41 Linus Torvalds    2005-04-16  1247  /* Anybody can rename anything with this: the permission checks are left to the
^1da177e4c3f41 Linus Torvalds    2005-04-16  1248   * higher-level routines.
^1da177e4c3f41 Linus Torvalds    2005-04-16  1249   */
549c7297717c32 Christian Brauner 2021-01-21  1250  static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
549c7297717c32 Christian Brauner 2021-01-21  1251  		      struct dentry *old_dentry, struct inode *new_dir,
549c7297717c32 Christian Brauner 2021-01-21  1252  		      struct dentry *new_dentry, unsigned int flags)
^1da177e4c3f41 Linus Torvalds    2005-04-16  1253  {
2b0143b5c986be David Howells     2015-03-17  1254  	struct inode *old_inode = d_inode(old_dentry);
2b0143b5c986be David Howells     2015-03-17  1255  	struct inode *new_inode = d_inode(new_dentry);
54711e9617a9ee Jan Kara          2022-12-16  1256  	struct udf_fileident_iter oiter, niter, diriter;
54711e9617a9ee Jan Kara          2022-12-16  1257  	bool has_diriter = false;
54711e9617a9ee Jan Kara          2022-12-16  1258  	int retval;
5ca4e4be841e38 Pekka Enberg      2008-10-15  1259  	struct kernel_lb_addr tloc;
^1da177e4c3f41 Linus Torvalds    2005-04-16  1260  
f03b8ad8d38634 Miklos Szeredi    2016-09-27  1261  	if (flags & ~RENAME_NOREPLACE)
f03b8ad8d38634 Miklos Szeredi    2016-09-27  1262  		return -EINVAL;
f03b8ad8d38634 Miklos Szeredi    2016-09-27  1263  
54711e9617a9ee Jan Kara          2022-12-16  1264  	retval = udf_fiiter_find_entry(old_dir, &old_dentry->d_name, &oiter);
54711e9617a9ee Jan Kara          2022-12-16  1265  	if (retval)
54711e9617a9ee Jan Kara          2022-12-16  1266  		return retval;
^1da177e4c3f41 Linus Torvalds    2005-04-16  1267  
54711e9617a9ee Jan Kara          2022-12-16  1268  	tloc = lelb_to_cpu(oiter.fi.icb.extLocation);
54711e9617a9ee Jan Kara          2022-12-16  1269  	if (udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) != old_inode->i_ino) {
54711e9617a9ee Jan Kara          2022-12-16  1270   		retval = -ENOENT;
54711e9617a9ee Jan Kara          2022-12-16  1271  		goto out_oiter;
^1da177e4c3f41 Linus Torvalds    2005-04-16  1272  	}
^1da177e4c3f41 Linus Torvalds    2005-04-16  1273  
54711e9617a9ee Jan Kara          2022-12-16  1274  	if (S_ISDIR(old_inode->i_mode)) {
cb00ea3528eb3c Cyrill Gorcunov   2007-07-19  1275  		if (new_inode) {
^1da177e4c3f41 Linus Torvalds    2005-04-16  1276  			retval = -ENOTEMPTY;
^1da177e4c3f41 Linus Torvalds    2005-04-16  1277  			if (!empty_dir(new_inode))
54711e9617a9ee Jan Kara          2022-12-16  1278  				goto out_oiter;
54711e9617a9ee Jan Kara          2022-12-16  1279  		}
54711e9617a9ee Jan Kara          2022-12-16  1280  		retval = udf_fiiter_find_entry(old_inode, &dotdot_name,
54711e9617a9ee Jan Kara          2022-12-16  1281  					       &diriter);
54711e9617a9ee Jan Kara          2022-12-16  1282  		if (retval == -ENOENT) {
54711e9617a9ee Jan Kara          2022-12-16  1283  			udf_err(old_inode->i_sb,
54711e9617a9ee Jan Kara          2022-12-16  1284  				"directory (ino %lu) has no '..' entry\n",
54711e9617a9ee Jan Kara          2022-12-16  1285  				old_inode->i_ino);
54711e9617a9ee Jan Kara          2022-12-16  1286  			retval = -EFSCORRUPTED;
54711e9617a9ee Jan Kara          2022-12-16  1287  		}
54711e9617a9ee Jan Kara          2022-12-16  1288  		if (retval)
54711e9617a9ee Jan Kara          2022-12-16  1289  			goto out_oiter;
54711e9617a9ee Jan Kara          2022-12-16  1290  		has_diriter = true;
54711e9617a9ee Jan Kara          2022-12-16  1291  		tloc = lelb_to_cpu(diriter.fi.icb.extLocation);
97e961fdbf3248 Pekka Enberg      2008-10-15  1292  		if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) !=
54711e9617a9ee Jan Kara          2022-12-16  1293  				old_dir->i_ino) {
54711e9617a9ee Jan Kara          2022-12-16  1294  			retval = -EFSCORRUPTED;
54711e9617a9ee Jan Kara          2022-12-16  1295  			udf_err(old_inode->i_sb,
54711e9617a9ee Jan Kara          2022-12-16  1296  				"directory (ino %lu) has parent entry pointing to another inode (%lu != %u)\n",
54711e9617a9ee Jan Kara          2022-12-16  1297  				old_inode->i_ino, old_dir->i_ino,
54711e9617a9ee Jan Kara          2022-12-16  1298  				udf_get_lb_pblock(old_inode->i_sb, &tloc, 0));
54711e9617a9ee Jan Kara          2022-12-16  1299  			goto out_oiter;
54711e9617a9ee Jan Kara          2022-12-16  1300  		}
^1da177e4c3f41 Linus Torvalds    2005-04-16  1301  	}
54711e9617a9ee Jan Kara          2022-12-16  1302  
54711e9617a9ee Jan Kara          2022-12-16  1303  	retval = udf_fiiter_find_entry(new_dir, &new_dentry->d_name, &niter);
54711e9617a9ee Jan Kara          2022-12-16  1304  	if (retval && retval != -ENOENT)
54711e9617a9ee Jan Kara          2022-12-16  1305  		goto out_oiter;
54711e9617a9ee Jan Kara          2022-12-16  1306  	/* Entry found but not passed by VFS? */
54711e9617a9ee Jan Kara          2022-12-16  1307  	if (WARN_ON_ONCE(!retval && !new_inode)) {
54711e9617a9ee Jan Kara          2022-12-16  1308  		retval = -EFSCORRUPTED;
54711e9617a9ee Jan Kara          2022-12-16  1309  		udf_fiiter_release(&niter);
54711e9617a9ee Jan Kara          2022-12-16  1310  		goto out_oiter;
54711e9617a9ee Jan Kara          2022-12-16  1311  	}
54711e9617a9ee Jan Kara          2022-12-16  1312  	/* Entry not found? Need to add one... */
54711e9617a9ee Jan Kara          2022-12-16  1313  	if (retval) {
54711e9617a9ee Jan Kara          2022-12-16  1314  		udf_fiiter_release(&niter);
54711e9617a9ee Jan Kara          2022-12-16  1315  		retval = udf_fiiter_add_entry(new_dir, new_dentry, &niter);
54711e9617a9ee Jan Kara          2022-12-16  1316  		if (retval)
54711e9617a9ee Jan Kara          2022-12-16  1317  			goto out_oiter;
^1da177e4c3f41 Linus Torvalds    2005-04-16  1318  	}
^1da177e4c3f41 Linus Torvalds    2005-04-16  1319  
^1da177e4c3f41 Linus Torvalds    2005-04-16  1320  	/*
^1da177e4c3f41 Linus Torvalds    2005-04-16  1321  	 * Like most other Unix systems, set the ctime for inodes on a
^1da177e4c3f41 Linus Torvalds    2005-04-16  1322  	 * rename.
^1da177e4c3f41 Linus Torvalds    2005-04-16  1323  	 */
c2050a454c7f12 Deepa Dinamani    2016-09-14  1324  	old_inode->i_ctime = current_time(old_inode);
^1da177e4c3f41 Linus Torvalds    2005-04-16  1325  	mark_inode_dirty(old_inode);
^1da177e4c3f41 Linus Torvalds    2005-04-16  1326  
^1da177e4c3f41 Linus Torvalds    2005-04-16  1327  	/*
^1da177e4c3f41 Linus Torvalds    2005-04-16  1328  	 * ok, that's it
^1da177e4c3f41 Linus Torvalds    2005-04-16  1329  	 */
54711e9617a9ee Jan Kara          2022-12-16  1330  	niter.fi.fileVersionNum = oiter.fi.fileVersionNum;
54711e9617a9ee Jan Kara          2022-12-16  1331  	niter.fi.fileCharacteristics = oiter.fi.fileCharacteristics;
54711e9617a9ee Jan Kara          2022-12-16  1332  	memcpy(&(niter.fi.icb), &(oiter.fi.icb), sizeof(oiter.fi.icb));
54711e9617a9ee Jan Kara          2022-12-16  1333  	udf_fiiter_write_fi(&niter, NULL);
54711e9617a9ee Jan Kara          2022-12-16  1334  	udf_fiiter_release(&niter);
^1da177e4c3f41 Linus Torvalds    2005-04-16  1335  
54711e9617a9ee Jan Kara          2022-12-16  1336  	/*
54711e9617a9ee Jan Kara          2022-12-16  1337  	 * The old entry may have moved due to new entry allocation. Find it
54711e9617a9ee Jan Kara          2022-12-16  1338   	 * again.
54711e9617a9ee Jan Kara          2022-12-16  1339  	 */
54711e9617a9ee Jan Kara          2022-12-16  1340  	udf_fiiter_release(&oiter);
54711e9617a9ee Jan Kara          2022-12-16  1341  	retval = udf_fiiter_find_entry(old_dir, &old_dentry->d_name, &oiter);
54711e9617a9ee Jan Kara          2022-12-16  1342  	if (retval) {
54711e9617a9ee Jan Kara          2022-12-16  1343  		udf_err(old_dir->i_sb,
54711e9617a9ee Jan Kara          2022-12-16  1344  			"failed to find renamed entry again in directory (ino %lu)\n",
54711e9617a9ee Jan Kara          2022-12-16  1345  			old_dir->i_ino);
54711e9617a9ee Jan Kara          2022-12-16  1346  	} else {
54711e9617a9ee Jan Kara          2022-12-16  1347  		udf_fiiter_delete_entry(&oiter);
54711e9617a9ee Jan Kara          2022-12-16  1348  		udf_fiiter_release(&oiter);
54711e9617a9ee Jan Kara          2022-12-16  1349  	}
^1da177e4c3f41 Linus Torvalds    2005-04-16  1350  
cb00ea3528eb3c Cyrill Gorcunov   2007-07-19  1351  	if (new_inode) {
c2050a454c7f12 Deepa Dinamani    2016-09-14  1352  		new_inode->i_ctime = current_time(new_inode);
9a53c3a783c2fa Dave Hansen       2006-09-30  1353  		inode_dec_link_count(new_inode);
^1da177e4c3f41 Linus Torvalds    2005-04-16  1354  	}
c2050a454c7f12 Deepa Dinamani    2016-09-14  1355  	old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
c2050a454c7f12 Deepa Dinamani    2016-09-14  1356  	new_dir->i_ctime = new_dir->i_mtime = current_time(new_dir);
^1da177e4c3f41 Linus Torvalds    2005-04-16  1357  	mark_inode_dirty(old_dir);
3adc12e9648291 Jan Kara          2015-03-24  1358  	mark_inode_dirty(new_dir);
^1da177e4c3f41 Linus Torvalds    2005-04-16  1359  
54711e9617a9ee Jan Kara          2022-12-16  1360  	if (has_diriter) {
54711e9617a9ee Jan Kara          2022-12-16  1361  		diriter.fi.icb.extLocation =
54711e9617a9ee Jan Kara          2022-12-16  1362  					cpu_to_lelb(UDF_I(new_dir)->i_location);
54711e9617a9ee Jan Kara          2022-12-16  1363  		udf_update_tag((char *)&diriter.fi,
54711e9617a9ee Jan Kara          2022-12-16  1364  			       udf_dir_entry_len(&diriter.fi));
54711e9617a9ee Jan Kara          2022-12-16  1365  		udf_fiiter_write_fi(&diriter, NULL);
54711e9617a9ee Jan Kara          2022-12-16  1366  		udf_fiiter_release(&diriter);
4b11111aba6c80 Marcin Slusarz    2008-02-08  1367  
9a53c3a783c2fa Dave Hansen       2006-09-30  1368  		inode_dec_link_count(old_dir);
4b11111aba6c80 Marcin Slusarz    2008-02-08  1369  		if (new_inode)
9a53c3a783c2fa Dave Hansen       2006-09-30  1370  			inode_dec_link_count(new_inode);
4b11111aba6c80 Marcin Slusarz    2008-02-08  1371  		else {
d8c76e6f45c111 Dave Hansen       2006-09-30  1372  			inc_nlink(new_dir);
^1da177e4c3f41 Linus Torvalds    2005-04-16  1373  			mark_inode_dirty(new_dir);
^1da177e4c3f41 Linus Torvalds    2005-04-16  1374  		}
^1da177e4c3f41 Linus Torvalds    2005-04-16  1375  	}
54711e9617a9ee Jan Kara          2022-12-16  1376  	return 0;
54711e9617a9ee Jan Kara          2022-12-16  1377  out_oiter:
54711e9617a9ee Jan Kara          2022-12-16  1378  	if (has_diriter)
54711e9617a9ee Jan Kara          2022-12-16  1379  		udf_fiiter_release(&diriter);
54711e9617a9ee Jan Kara          2022-12-16  1380  	udf_fiiter_release(&oiter);
28de7948a89676 Cyrill Gorcunov   2007-07-21  1381  
^1da177e4c3f41 Linus Torvalds    2005-04-16  1382  	return retval;
^1da177e4c3f41 Linus Torvalds    2005-04-16 @1383  }
^1da177e4c3f41 Linus Torvalds    2005-04-16  1384
diff mbox series

Patch

diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 7871f7763a9b..81a7197c2109 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -1253,78 +1253,68 @@  static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
 {
 	struct inode *old_inode = d_inode(old_dentry);
 	struct inode *new_inode = d_inode(new_dentry);
-	struct udf_fileident_bh ofibh, nfibh;
-	struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL;
-	struct fileIdentDesc ocfi, ncfi;
-	struct buffer_head *dir_bh = NULL;
-	int retval = -ENOENT;
+	struct udf_fileident_iter oiter, niter, diriter;
+	bool has_diriter = false;
+	int retval;
 	struct kernel_lb_addr tloc;
-	struct udf_inode_info *old_iinfo = UDF_I(old_inode);
 
 	if (flags & ~RENAME_NOREPLACE)
 		return -EINVAL;
 
-	ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
-	if (!ofi || IS_ERR(ofi)) {
-		if (IS_ERR(ofi))
-			retval = PTR_ERR(ofi);
-		goto end_rename;
-	}
-
-	if (ofibh.sbh != ofibh.ebh)
-		brelse(ofibh.ebh);
-
-	brelse(ofibh.sbh);
-	tloc = lelb_to_cpu(ocfi.icb.extLocation);
-	if (udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) != old_inode->i_ino)
-		goto end_rename;
+	retval = udf_fiiter_find_entry(old_dir, &old_dentry->d_name, &oiter);
+	if (retval)
+		return retval;
 
-	nfi = udf_find_entry(new_dir, &new_dentry->d_name, &nfibh, &ncfi);
-	if (IS_ERR(nfi)) {
-		retval = PTR_ERR(nfi);
-		goto end_rename;
+	tloc = lelb_to_cpu(oiter.fi.icb.extLocation);
+	if (udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) != old_inode->i_ino) {
+ 		retval = -ENOENT;
+		goto out_oiter;
 	}
-	if (nfi && !new_inode) {
-		if (nfibh.sbh != nfibh.ebh)
-			brelse(nfibh.ebh);
-		brelse(nfibh.sbh);
-		nfi = NULL;
-	}
-	if (S_ISDIR(old_inode->i_mode)) {
-		int offset = udf_ext0_offset(old_inode);
 
+	if (S_ISDIR(old_inode->i_mode)) {
 		if (new_inode) {
 			retval = -ENOTEMPTY;
 			if (!empty_dir(new_inode))
-				goto end_rename;
+				goto out_oiter;
 		}
-		retval = -EIO;
-		if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
-			dir_fi = udf_get_fileident(
-					old_iinfo->i_data -
-					  (old_iinfo->i_efe ?
-					   sizeof(struct extendedFileEntry) :
-					   sizeof(struct fileEntry)),
-					old_inode->i_sb->s_blocksize, &offset);
-		} else {
-			dir_bh = udf_bread(old_inode, 0, 0, &retval);
-			if (!dir_bh)
-				goto end_rename;
-			dir_fi = udf_get_fileident(dir_bh->b_data,
-					old_inode->i_sb->s_blocksize, &offset);
+		retval = udf_fiiter_find_entry(old_inode, &dotdot_name,
+					       &diriter);
+		if (retval == -ENOENT) {
+			udf_err(old_inode->i_sb,
+				"directory (ino %lu) has no '..' entry\n",
+				old_inode->i_ino);
+			retval = -EFSCORRUPTED;
 		}
-		if (!dir_fi)
-			goto end_rename;
-		tloc = lelb_to_cpu(dir_fi->icb.extLocation);
+		if (retval)
+			goto out_oiter;
+		has_diriter = true;
+		tloc = lelb_to_cpu(diriter.fi.icb.extLocation);
 		if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) !=
-				old_dir->i_ino)
-			goto end_rename;
+				old_dir->i_ino) {
+			retval = -EFSCORRUPTED;
+			udf_err(old_inode->i_sb,
+				"directory (ino %lu) has parent entry pointing to another inode (%lu != %u)\n",
+				old_inode->i_ino, old_dir->i_ino,
+				udf_get_lb_pblock(old_inode->i_sb, &tloc, 0));
+			goto out_oiter;
+		}
 	}
-	if (!nfi) {
-		nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi,
-				    &retval);
-		if (!nfi)
-			goto end_rename;
+
+	retval = udf_fiiter_find_entry(new_dir, &new_dentry->d_name, &niter);
+	if (retval && retval != -ENOENT)
+		goto out_oiter;
+	/* Entry found but not passed by VFS? */
+	if (WARN_ON_ONCE(!retval && !new_inode)) {
+		retval = -EFSCORRUPTED;
+		udf_fiiter_release(&niter);
+		goto out_oiter;
+	}
+	/* Entry not found? Need to add one... */
+	if (retval) {
+		udf_fiiter_release(&niter);
+		retval = udf_fiiter_add_entry(new_dir, new_dentry, &niter);
+		if (retval)
+			goto out_oiter;
 	}
 
 	/*
@@ -1337,14 +1327,26 @@  static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
 	/*
 	 * ok, that's it
 	 */
-	ncfi.fileVersionNum = ocfi.fileVersionNum;
-	ncfi.fileCharacteristics = ocfi.fileCharacteristics;
-	memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(ocfi.icb));
-	udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL);
+	niter.fi.fileVersionNum = oiter.fi.fileVersionNum;
+	niter.fi.fileCharacteristics = oiter.fi.fileCharacteristics;
+	memcpy(&(niter.fi.icb), &(oiter.fi.icb), sizeof(oiter.fi.icb));
+	udf_fiiter_write_fi(&niter, NULL);
+	udf_fiiter_release(&niter);
 
-	/* The old fid may have moved - find it again */
-	ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
-	udf_delete_entry(old_dir, ofi, &ofibh, &ocfi);
+	/*
+	 * The old entry may have moved due to new entry allocation. Find it
+ 	 * again.
+	 */
+	udf_fiiter_release(&oiter);
+	retval = udf_fiiter_find_entry(old_dir, &old_dentry->d_name, &oiter);
+	if (retval) {
+		udf_err(old_dir->i_sb,
+			"failed to find renamed entry again in directory (ino %lu)\n",
+			old_dir->i_ino);
+	} else {
+		udf_fiiter_delete_entry(&oiter);
+		udf_fiiter_release(&oiter);
+	}
 
 	if (new_inode) {
 		new_inode->i_ctime = current_time(new_inode);
@@ -1355,13 +1357,13 @@  static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
 	mark_inode_dirty(old_dir);
 	mark_inode_dirty(new_dir);
 
-	if (dir_fi) {
-		dir_fi->icb.extLocation = cpu_to_lelb(UDF_I(new_dir)->i_location);
-		udf_update_tag((char *)dir_fi, udf_dir_entry_len(dir_fi));
-		if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
-			mark_inode_dirty(old_inode);
-		else
-			mark_buffer_dirty_inode(dir_bh, old_inode);
+	if (has_diriter) {
+		diriter.fi.icb.extLocation =
+					cpu_to_lelb(UDF_I(new_dir)->i_location);
+		udf_update_tag((char *)&diriter.fi,
+			       udf_dir_entry_len(&diriter.fi));
+		udf_fiiter_write_fi(&diriter, NULL);
+		udf_fiiter_release(&diriter);
 
 		inode_dec_link_count(old_dir);
 		if (new_inode)
@@ -1371,22 +1373,11 @@  static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
 			mark_inode_dirty(new_dir);
 		}
 	}
-
-	if (ofi) {
-		if (ofibh.sbh != ofibh.ebh)
-			brelse(ofibh.ebh);
-		brelse(ofibh.sbh);
-	}
-
-	retval = 0;
-
-end_rename:
-	brelse(dir_bh);
-	if (nfi) {
-		if (nfibh.sbh != nfibh.ebh)
-			brelse(nfibh.ebh);
-		brelse(nfibh.sbh);
-	}
+	return 0;
+out_oiter:
+	if (has_diriter)
+		udf_fiiter_release(&diriter);
+	udf_fiiter_release(&oiter);
 
 	return retval;
 }