diff options
Diffstat (limited to 'fs/cifs/ioctl.c')
-rw-r--r-- | fs/cifs/ioctl.c | 21 |
1 files changed, 5 insertions, 16 deletions
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 45cb59bcc791..8b7898b7670f 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
@@ -86,21 +86,16 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, | |||
86 | } | 86 | } |
87 | 87 | ||
88 | src_inode = file_inode(src_file.file); | 88 | src_inode = file_inode(src_file.file); |
89 | rc = -EINVAL; | ||
90 | if (S_ISDIR(src_inode->i_mode)) | ||
91 | goto out_fput; | ||
89 | 92 | ||
90 | /* | 93 | /* |
91 | * Note: cifs case is easier than btrfs since server responsible for | 94 | * Note: cifs case is easier than btrfs since server responsible for |
92 | * checks for proper open modes and file type and if it wants | 95 | * checks for proper open modes and file type and if it wants |
93 | * server could even support copy of range where source = target | 96 | * server could even support copy of range where source = target |
94 | */ | 97 | */ |
95 | 98 | lock_two_nondirectories(target_inode, src_inode); | |
96 | /* so we do not deadlock racing two ioctls on same files */ | ||
97 | if (target_inode < src_inode) { | ||
98 | mutex_lock_nested(&target_inode->i_mutex, I_MUTEX_PARENT); | ||
99 | mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_CHILD); | ||
100 | } else { | ||
101 | mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_PARENT); | ||
102 | mutex_lock_nested(&target_inode->i_mutex, I_MUTEX_CHILD); | ||
103 | } | ||
104 | 99 | ||
105 | /* determine range to clone */ | 100 | /* determine range to clone */ |
106 | rc = -EINVAL; | 101 | rc = -EINVAL; |
@@ -124,13 +119,7 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, | |||
124 | out_unlock: | 119 | out_unlock: |
125 | /* although unlocking in the reverse order from locking is not | 120 | /* although unlocking in the reverse order from locking is not |
126 | strictly necessary here it is a little cleaner to be consistent */ | 121 | strictly necessary here it is a little cleaner to be consistent */ |
127 | if (target_inode < src_inode) { | 122 | unlock_two_nondirectories(src_inode, target_inode); |
128 | mutex_unlock(&src_inode->i_mutex); | ||
129 | mutex_unlock(&target_inode->i_mutex); | ||
130 | } else { | ||
131 | mutex_unlock(&target_inode->i_mutex); | ||
132 | mutex_unlock(&src_inode->i_mutex); | ||
133 | } | ||
134 | out_fput: | 123 | out_fput: |
135 | fdput(src_file); | 124 | fdput(src_file); |
136 | out_drop_write: | 125 | out_drop_write: |