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

Commit c643e2b9 authored by Jaegeuk Kim's avatar Jaegeuk Kim Committed by Jaegeuk Kim
Browse files

f2fs: set I_LINKABLE early to avoid wrong access by vfs



This patch moves setting I_LINKABLE early in rename2(whiteout) to avoid the
below warning.

[ 3189.163385] WARNING: CPU: 3 PID: 59523 at fs/inode.c:358 inc_nlink+0x32/0x40
[ 3189.246979] Call Trace:
[ 3189.248707]  f2fs_init_inode_metadata+0x2d6/0x440 [f2fs]
[ 3189.251399]  f2fs_add_inline_entry+0x162/0x8c0 [f2fs]
[ 3189.254010]  f2fs_add_dentry+0x69/0xe0 [f2fs]
[ 3189.256353]  f2fs_do_add_link+0xc5/0x100 [f2fs]
[ 3189.258774]  f2fs_rename2+0xabf/0x1010 [f2fs]
[ 3189.261079]  vfs_rename+0x3f8/0xaa0
[ 3189.263056]  ? tomoyo_path_rename+0x44/0x60
[ 3189.265283]  ? do_renameat2+0x49b/0x550
[ 3189.267324]  do_renameat2+0x49b/0x550
[ 3189.269316]  __x64_sys_renameat2+0x20/0x30
[ 3189.271441]  do_syscall_64+0x5a/0x230
[ 3189.273410]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
[ 3189.275848] RIP: 0033:0x7f270b4d9a49

Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent ff032520
Loading
Loading
Loading
Loading
+13 −14
Original line number Diff line number Diff line
@@ -801,6 +801,7 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry,

	if (whiteout) {
		f2fs_i_links_write(inode, false);
		inode->i_state |= I_LINKABLE;
		*whiteout = inode;
	} else {
		d_tmpfile(dentry, inode);
@@ -871,6 +872,12 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
			F2FS_I(old_dentry->d_inode)->i_projid)))
		return -EXDEV;

	if (flags & RENAME_WHITEOUT) {
		err = f2fs_create_whiteout(old_dir, &whiteout);
		if (err)
			return err;
	}

	err = dquot_initialize(old_dir);
	if (err)
		goto out;
@@ -902,17 +909,11 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
		}
	}

	if (flags & RENAME_WHITEOUT) {
		err = f2fs_create_whiteout(old_dir, &whiteout);
		if (err)
			goto out_dir;
	}

	if (new_inode) {

		err = -ENOTEMPTY;
		if (old_dir_entry && !f2fs_empty_dir(new_inode))
			goto out_whiteout;
			goto out_dir;

		err = -ENOENT;
		new_entry = f2fs_find_entry(new_dir, &new_dentry->d_name,
@@ -920,7 +921,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
		if (!new_entry) {
			if (IS_ERR(new_page))
				err = PTR_ERR(new_page);
			goto out_whiteout;
			goto out_dir;
		}

		f2fs_balance_fs(sbi, true);
@@ -952,7 +953,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
		err = f2fs_add_link(new_dentry, old_inode);
		if (err) {
			f2fs_unlock_op(sbi);
			goto out_whiteout;
			goto out_dir;
		}

		if (old_dir_entry)
@@ -976,7 +977,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
				if (IS_ERR(old_page))
					err = PTR_ERR(old_page);
				f2fs_unlock_op(sbi);
				goto out_whiteout;
				goto out_dir;
			}
		}
	}
@@ -995,7 +996,6 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
	f2fs_delete_entry(old_entry, old_page, old_dir, NULL);

	if (whiteout) {
		whiteout->i_state |= I_LINKABLE;
		set_inode_flag(whiteout, FI_INC_LINK);
		err = f2fs_add_link(old_dentry, whiteout);
		if (err)
@@ -1031,15 +1031,14 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
	f2fs_unlock_op(sbi);
	if (new_page)
		f2fs_put_page(new_page, 0);
out_whiteout:
	if (whiteout)
		iput(whiteout);
out_dir:
	if (old_dir_entry)
		f2fs_put_page(old_dir_page, 0);
out_old:
	f2fs_put_page(old_page, 0);
out:
	if (whiteout)
		iput(whiteout);
	return err;
}