diff options
author | Chao Yu <yuchao0@huawei.com> | 2016-08-04 20:13:03 +0800 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2016-08-19 11:15:08 +0900 |
commit | 20a3d61d46e1fb45efa6eb4637c0dcd3f00a14e9 (patch) | |
tree | b31648702d4d9267f5d0f078c5db9ce9aad082f2 | |
parent | fe8494bfc8c2914fca821d4ae994aef039be5cf1 (diff) |
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>
-rw-r--r-- | fs/f2fs/file.c | 9 |
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; } |