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: |
