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

Commit 764aa3e9 authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: avoid double lock in truncate_blocks



The init_inode_metadata calls truncate_blocks when error is occurred.
The callers holds f2fs_lock_op, so we should not call it again in
truncate_blocks.

Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 14f4e690
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -936,7 +936,7 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to)


	if (to > inode->i_size) {
	if (to > inode->i_size) {
		truncate_pagecache(inode, inode->i_size);
		truncate_pagecache(inode, inode->i_size);
		truncate_blocks(inode, inode->i_size);
		truncate_blocks(inode, inode->i_size, true);
	}
	}
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -391,7 +391,7 @@ put_error:
error:
error:
	/* once the failed inode becomes a bad inode, i_mode is S_IFREG */
	/* once the failed inode becomes a bad inode, i_mode is S_IFREG */
	truncate_inode_pages(&inode->i_data, 0);
	truncate_inode_pages(&inode->i_data, 0);
	truncate_blocks(inode, 0);
	truncate_blocks(inode, 0, false);
	remove_dirty_dir_inode(inode);
	remove_dirty_dir_inode(inode);
	remove_inode_page(inode);
	remove_inode_page(inode);
	return ERR_PTR(err);
	return ERR_PTR(err);
+1 −1
Original line number Original line Diff line number Diff line
@@ -1122,7 +1122,7 @@ static inline void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi)
 */
 */
int f2fs_sync_file(struct file *, loff_t, loff_t, int);
int f2fs_sync_file(struct file *, loff_t, loff_t, int);
void truncate_data_blocks(struct dnode_of_data *);
void truncate_data_blocks(struct dnode_of_data *);
int truncate_blocks(struct inode *, u64);
int truncate_blocks(struct inode *, u64, bool);
void f2fs_truncate(struct inode *);
void f2fs_truncate(struct inode *);
int f2fs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
int f2fs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
int f2fs_setattr(struct dentry *, struct iattr *);
int f2fs_setattr(struct dentry *, struct iattr *);
+8 −5
Original line number Original line Diff line number Diff line
@@ -422,7 +422,7 @@ out:
	f2fs_put_page(page, 1);
	f2fs_put_page(page, 1);
}
}


int truncate_blocks(struct inode *inode, u64 from)
int truncate_blocks(struct inode *inode, u64 from, bool lock)
{
{
	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
	unsigned int blocksize = inode->i_sb->s_blocksize;
	unsigned int blocksize = inode->i_sb->s_blocksize;
@@ -438,6 +438,7 @@ int truncate_blocks(struct inode *inode, u64 from)
	free_from = (pgoff_t)
	free_from = (pgoff_t)
			((from + blocksize - 1) >> (sbi->log_blocksize));
			((from + blocksize - 1) >> (sbi->log_blocksize));


	if (lock)
		f2fs_lock_op(sbi);
		f2fs_lock_op(sbi);


	set_new_dnode(&dn, inode, NULL, NULL, 0);
	set_new_dnode(&dn, inode, NULL, NULL, 0);
@@ -445,6 +446,7 @@ int truncate_blocks(struct inode *inode, u64 from)
	if (err) {
	if (err) {
		if (err == -ENOENT)
		if (err == -ENOENT)
			goto free_next;
			goto free_next;
		if (lock)
			f2fs_unlock_op(sbi);
			f2fs_unlock_op(sbi);
		trace_f2fs_truncate_blocks_exit(inode, err);
		trace_f2fs_truncate_blocks_exit(inode, err);
		return err;
		return err;
@@ -463,6 +465,7 @@ int truncate_blocks(struct inode *inode, u64 from)
	f2fs_put_dnode(&dn);
	f2fs_put_dnode(&dn);
free_next:
free_next:
	err = truncate_inode_blocks(inode, free_from);
	err = truncate_inode_blocks(inode, free_from);
	if (lock)
		f2fs_unlock_op(sbi);
		f2fs_unlock_op(sbi);
done:
done:
	/* lastly zero out the first data page */
	/* lastly zero out the first data page */
@@ -480,7 +483,7 @@ void f2fs_truncate(struct inode *inode)


	trace_f2fs_truncate(inode);
	trace_f2fs_truncate(inode);


	if (!truncate_blocks(inode, i_size_read(inode))) {
	if (!truncate_blocks(inode, i_size_read(inode), true)) {
		inode->i_mtime = inode->i_ctime = CURRENT_TIME;
		inode->i_mtime = inode->i_ctime = CURRENT_TIME;
		mark_inode_dirty(inode);
		mark_inode_dirty(inode);
	}
	}
+1 −1
Original line number Original line Diff line number Diff line
@@ -247,7 +247,7 @@ process_inline:
		update_inode(inode, ipage);
		update_inode(inode, ipage);
		f2fs_put_page(ipage, 1);
		f2fs_put_page(ipage, 1);
	} else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) {
	} else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) {
		truncate_blocks(inode, 0);
		truncate_blocks(inode, 0, false);
		set_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
		set_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
		goto process_inline;
		goto process_inline;
	}
	}