summary refs log tree commit diff
path: root/fs
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2016-08-04 20:13:03 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2016-08-19 11:15:08 +0900
commit20a3d61d46e1fb45efa6eb4637c0dcd3f00a14e9 (patch)
treeb31648702d4d9267f5d0f078c5db9ce9aad082f2 /fs
parentfe8494bfc8c2914fca821d4ae994aef039be5cf1 (diff)
downloadlinux-20a3d61d46e1fb45efa6eb4637c0dcd3f00a14e9.tar.gz
f2fs: avoid potential deadlock in f2fs_move_file_range
Thread A			Thread B
- inode_lock fileA
				- inode_lock fileB
				 - inode_lock fileA
 - inode_lock fileB

We may encounter above potential deadlock during moving file range in
concurrent scenario. This patch fixes the issue by using inode_trylock
instead.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/file.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 685e629f768b..47abb96098e4 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2093,8 +2093,12 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
 		return -EOPNOTSUPP;
 
 	inode_lock(src);
-	if (src != dst)
-		inode_lock(dst);
+	if (src != dst) {
+		if (!inode_trylock(dst)) {
+			ret = -EBUSY;
+			goto out;
+		}
+	}
 
 	ret = -EINVAL;
 	if (pos_in + len > src->i_size || pos_in + len < pos_in)
@@ -2152,6 +2156,7 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
 out_unlock:
 	if (src != dst)
 		inode_unlock(dst);
+out:
 	inode_unlock(src);
 	return ret;
 }