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 <[email protected]>
---
 fs/f2fs/file.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 409f0ec..ebf2703 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2169,8 +2169,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)
@@ -2228,6 +2232,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;
 }
-- 
2.8.2.311.gee88674


------------------------------------------------------------------------------
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to