f2fs: avoid potential deadlock in f2fs_move_file_range
authorChao Yu <yuchao0@huawei.com>
Thu, 4 Aug 2016 12:13:03 +0000 (20:13 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 19 Aug 2016 02:15:08 +0000 (11:15 +0900)
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>
fs/f2fs/file.c

index 685e629f768bd961336cc8e1080a07ab44fac462..47abb96098e49d71fcb082b39752be4f89882199 100644 (file)
@@ -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;
 }