fs/ntfs3: Changing locking in ntfs_rename
authorKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Fri, 7 Oct 2022 17:16:15 +0000 (20:16 +0300)
committerKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Mon, 14 Nov 2022 16:50:45 +0000 (19:50 +0300)
In some cases we can be in deadlock
because we tried to lock the same dir.

Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
fs/ntfs3/namei.c
fs/ntfs3/ntfs_fs.h

index daff8d0cd63dcec0d680411bbedfef7e74f2ef5d..0e72d2067804f743614dd7fbfcf46b9b26115162 100644 (file)
@@ -305,6 +305,8 @@ static int ntfs_rename(struct user_namespace *mnt_userns, struct inode *dir,
 
        ni_lock_dir(dir_ni);
        ni_lock(ni);
+       if (dir_ni != new_dir_ni)
+               ni_lock_dir2(new_dir_ni);
 
        is_bad = false;
        err = ni_rename(dir_ni, new_dir_ni, ni, de, new_de, &is_bad);
@@ -328,6 +330,8 @@ static int ntfs_rename(struct user_namespace *mnt_userns, struct inode *dir,
                        ntfs_sync_inode(inode);
        }
 
+       if (dir_ni != new_dir_ni)
+               ni_unlock(new_dir_ni);
        ni_unlock(ni);
        ni_unlock(dir_ni);
 out:
index 5269d4e66685b1563e38b6b755ef178fa9351cf0..776993ae498b27ec70ce11423a34295e03095232 100644 (file)
@@ -334,6 +334,7 @@ enum ntfs_inode_mutex_lock_class {
        NTFS_INODE_MUTEX_REPARSE,
        NTFS_INODE_MUTEX_NORMAL,
        NTFS_INODE_MUTEX_PARENT,
+       NTFS_INODE_MUTEX_PARENT2,
 };
 
 /*
@@ -1121,6 +1122,11 @@ static inline void ni_lock_dir(struct ntfs_inode *ni)
        mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_PARENT);
 }
 
+static inline void ni_lock_dir2(struct ntfs_inode *ni)
+{
+       mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_PARENT2);
+}
+
 static inline void ni_unlock(struct ntfs_inode *ni)
 {
        mutex_unlock(&ni->ni_lock);