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

Commit 44c16156 authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: call f2fs_unlock_op after error was handled



This patch relocates f2fs_unlock_op in every directory operations to be called
after any error was processed.
Otherwise, the checkpoint can be entered with valid node ids without its
dentry when -ENOSPC is occurred.

Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 7cd8558b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1194,6 +1194,7 @@ void update_inode(struct inode *, struct page *);
void update_inode_page(struct inode *);
int f2fs_write_inode(struct inode *, struct writeback_control *);
void f2fs_evict_inode(struct inode *);
void handle_failed_inode(struct inode *);

/*
 * namei.c
+23 −0
Original line number Diff line number Diff line
@@ -306,3 +306,26 @@ void f2fs_evict_inode(struct inode *inode)
out_clear:
	clear_inode(inode);
}

/* caller should call f2fs_lock_op() */
void handle_failed_inode(struct inode *inode)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);

	clear_nlink(inode);
	make_bad_inode(inode);
	unlock_new_inode(inode);

	i_size_write(inode, 0);
	if (F2FS_HAS_BLOCKS(inode))
		f2fs_truncate(inode);

	remove_inode_page(inode);
	stat_dec_inline_inode(inode);

	alloc_nid_failed(sbi, inode->i_ino);
	f2fs_unlock_op(sbi);

	/* iput will drop the inode object */
	iput(inode);
}
+11 −21
Original line number Diff line number Diff line
@@ -123,9 +123,9 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,

	f2fs_lock_op(sbi);
	err = f2fs_add_link(dentry, inode);
	f2fs_unlock_op(sbi);
	if (err)
		goto out;
	f2fs_unlock_op(sbi);

	alloc_nid_done(sbi, ino);

@@ -133,9 +133,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
	unlock_new_inode(inode);
	return 0;
out:
	clear_nlink(inode);
	iget_failed(inode);
	alloc_nid_failed(sbi, ino);
	handle_failed_inode(inode);
	return err;
}

@@ -154,15 +152,16 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
	set_inode_flag(F2FS_I(inode), FI_INC_LINK);
	f2fs_lock_op(sbi);
	err = f2fs_add_link(dentry, inode);
	f2fs_unlock_op(sbi);
	if (err)
		goto out;
	f2fs_unlock_op(sbi);

	d_instantiate(dentry, inode);
	return 0;
out:
	clear_inode_flag(F2FS_I(inode), FI_INC_LINK);
	iput(inode);
	f2fs_unlock_op(sbi);
	return err;
}

@@ -253,9 +252,9 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,

	f2fs_lock_op(sbi);
	err = f2fs_add_link(dentry, inode);
	f2fs_unlock_op(sbi);
	if (err)
		goto out;
	f2fs_unlock_op(sbi);

	err = page_symlink(inode, symname, symlen);
	alloc_nid_done(sbi, inode->i_ino);
@@ -264,9 +263,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
	unlock_new_inode(inode);
	return err;
out:
	clear_nlink(inode);
	iget_failed(inode);
	alloc_nid_failed(sbi, inode->i_ino);
	handle_failed_inode(inode);
	return err;
}

@@ -290,9 +287,9 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
	set_inode_flag(F2FS_I(inode), FI_INC_LINK);
	f2fs_lock_op(sbi);
	err = f2fs_add_link(dentry, inode);
	f2fs_unlock_op(sbi);
	if (err)
		goto out_fail;
	f2fs_unlock_op(sbi);

	alloc_nid_done(sbi, inode->i_ino);

@@ -303,9 +300,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)

out_fail:
	clear_inode_flag(F2FS_I(inode), FI_INC_LINK);
	clear_nlink(inode);
	iget_failed(inode);
	alloc_nid_failed(sbi, inode->i_ino);
	handle_failed_inode(inode);
	return err;
}

@@ -338,18 +333,16 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry,

	f2fs_lock_op(sbi);
	err = f2fs_add_link(dentry, inode);
	f2fs_unlock_op(sbi);
	if (err)
		goto out;
	f2fs_unlock_op(sbi);

	alloc_nid_done(sbi, inode->i_ino);
	d_instantiate(dentry, inode);
	unlock_new_inode(inode);
	return 0;
out:
	clear_nlink(inode);
	iget_failed(inode);
	alloc_nid_failed(sbi, inode->i_ino);
	handle_failed_inode(inode);
	return err;
}

@@ -677,10 +670,7 @@ static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
release_out:
	release_orphan_inode(sbi);
out:
	f2fs_unlock_op(sbi);
	clear_nlink(inode);
	iget_failed(inode);
	alloc_nid_failed(sbi, inode->i_ino);
	handle_failed_inode(inode);
	return err;
}