Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2fc8ce56 authored by zhangyi (F)'s avatar zhangyi (F) Committed by Greg Kroah-Hartman
Browse files

ext4: do not iput inode under running transaction in ext4_rename()



[ Upstream commit 5dccdc5a1916d4266edd251f20bbbb113a5c495f ]

In ext4_rename(), when RENAME_WHITEOUT failed to add new entry into
directory, it ends up dropping new created whiteout inode under the
running transaction. After commit <9b88f9fb0d2> ("ext4: Do not iput inode
under running transaction"), we follow the assumptions that evict() does
not get called from a transaction context but in ext4_rename() it breaks
this suggestion. Although it's not a real problem, better to obey it, so
this patch add inode to orphan list and stop transaction before final
iput().

Signed-off-by: default avatarzhangyi (F) <yi.zhang@huawei.com>
Link: https://lore.kernel.org/r/20210303131703.330415-2-yi.zhang@huawei.com


Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent ce3a1192
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -3554,7 +3554,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
	 */
	retval = -ENOENT;
	if (!old.bh || le32_to_cpu(old.de->inode) != old.inode->i_ino)
		goto end_rename;
		goto release_bh;

	if ((old.dir != new.dir) &&
	    ext4_encrypted_inode(new.dir) &&
@@ -3569,7 +3569,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
	if (IS_ERR(new.bh)) {
		retval = PTR_ERR(new.bh);
		new.bh = NULL;
		goto end_rename;
		goto release_bh;
	}
	if (new.bh) {
		if (!new.inode) {
@@ -3586,15 +3586,13 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
		handle = ext4_journal_start(old.dir, EXT4_HT_DIR, credits);
		if (IS_ERR(handle)) {
			retval = PTR_ERR(handle);
			handle = NULL;
			goto end_rename;
			goto release_bh;
		}
	} else {
		whiteout = ext4_whiteout_for_rename(&old, credits, &handle);
		if (IS_ERR(whiteout)) {
			retval = PTR_ERR(whiteout);
			whiteout = NULL;
			goto end_rename;
			goto release_bh;
		}
	}

@@ -3702,16 +3700,18 @@ end_rename:
			ext4_resetent(handle, &old,
				      old.inode->i_ino, old_file_type);
			drop_nlink(whiteout);
			ext4_orphan_add(handle, whiteout);
		}
		unlock_new_inode(whiteout);
		ext4_journal_stop(handle);
		iput(whiteout);

	} else {
		ext4_journal_stop(handle);
	}
release_bh:
	brelse(old.dir_bh);
	brelse(old.bh);
	brelse(new.bh);
	if (handle)
		ext4_journal_stop(handle);
	return retval;
}