Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "A couple of fixes - deadlock in CIFS and build breakage in cris serial driver (resurfaced f_dentry in there)" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: VFS: Convert file->f_dentry->d_inode to file_inode() fix deadlock in cifs_ioctl_clone()
This commit is contained in:
commit
80a755545d
|
@ -604,7 +604,7 @@ static ssize_t __sync_serial_read(struct file *file,
|
||||||
struct timespec *ts)
|
struct timespec *ts)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int dev = MINOR(file->f_dentry->d_inode->i_rdev);
|
int dev = MINOR(file_inode(file)->i_rdev);
|
||||||
int avail;
|
int avail;
|
||||||
struct sync_port *port;
|
struct sync_port *port;
|
||||||
unsigned char *start;
|
unsigned char *start;
|
||||||
|
|
|
@ -86,21 +86,16 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
|
||||||
}
|
}
|
||||||
|
|
||||||
src_inode = file_inode(src_file.file);
|
src_inode = file_inode(src_file.file);
|
||||||
|
rc = -EINVAL;
|
||||||
|
if (S_ISDIR(src_inode->i_mode))
|
||||||
|
goto out_fput;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: cifs case is easier than btrfs since server responsible for
|
* Note: cifs case is easier than btrfs since server responsible for
|
||||||
* checks for proper open modes and file type and if it wants
|
* checks for proper open modes and file type and if it wants
|
||||||
* server could even support copy of range where source = target
|
* server could even support copy of range where source = target
|
||||||
*/
|
*/
|
||||||
|
lock_two_nondirectories(target_inode, src_inode);
|
||||||
/* so we do not deadlock racing two ioctls on same files */
|
|
||||||
if (target_inode < src_inode) {
|
|
||||||
mutex_lock_nested(&target_inode->i_mutex, I_MUTEX_PARENT);
|
|
||||||
mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_CHILD);
|
|
||||||
} else {
|
|
||||||
mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_PARENT);
|
|
||||||
mutex_lock_nested(&target_inode->i_mutex, I_MUTEX_CHILD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* determine range to clone */
|
/* determine range to clone */
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
|
@ -124,13 +119,7 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
|
||||||
out_unlock:
|
out_unlock:
|
||||||
/* although unlocking in the reverse order from locking is not
|
/* although unlocking in the reverse order from locking is not
|
||||||
strictly necessary here it is a little cleaner to be consistent */
|
strictly necessary here it is a little cleaner to be consistent */
|
||||||
if (target_inode < src_inode) {
|
unlock_two_nondirectories(src_inode, target_inode);
|
||||||
mutex_unlock(&src_inode->i_mutex);
|
|
||||||
mutex_unlock(&target_inode->i_mutex);
|
|
||||||
} else {
|
|
||||||
mutex_unlock(&target_inode->i_mutex);
|
|
||||||
mutex_unlock(&src_inode->i_mutex);
|
|
||||||
}
|
|
||||||
out_fput:
|
out_fput:
|
||||||
fdput(src_file);
|
fdput(src_file);
|
||||||
out_drop_write:
|
out_drop_write:
|
||||||
|
|
Loading…
Reference in a new issue