@@ -1600,17 +1600,8 @@ smb2_copychunk_range(const unsigned int xid,
1600
1600
int chunks_copied = 0 ;
1601
1601
bool chunk_sizes_updated = false;
1602
1602
ssize_t bytes_written , total_bytes_written = 0 ;
1603
- struct inode * inode ;
1604
1603
1605
1604
pcchunk = kmalloc (sizeof (struct copychunk_ioctl ), GFP_KERNEL );
1606
-
1607
- /*
1608
- * We need to flush all unwritten data before we can send the
1609
- * copychunk ioctl to the server.
1610
- */
1611
- inode = d_inode (trgtfile -> dentry );
1612
- filemap_write_and_wait (inode -> i_mapping );
1613
-
1614
1605
if (pcchunk == NULL )
1615
1606
return - ENOMEM ;
1616
1607
@@ -3678,39 +3669,50 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
3678
3669
{
3679
3670
int rc ;
3680
3671
unsigned int xid ;
3681
- struct inode * inode ;
3672
+ struct inode * inode = file_inode ( file ) ;
3682
3673
struct cifsFileInfo * cfile = file -> private_data ;
3683
- struct cifsInodeInfo * cifsi ;
3674
+ struct cifsInodeInfo * cifsi = CIFS_I ( inode ) ;
3684
3675
__le64 eof ;
3676
+ loff_t old_eof ;
3685
3677
3686
3678
xid = get_xid ();
3687
3679
3688
- inode = d_inode (cfile -> dentry );
3689
- cifsi = CIFS_I (inode );
3680
+ inode_lock (inode );
3690
3681
3691
- if (off >= i_size_read (inode ) ||
3692
- off + len >= i_size_read (inode )) {
3682
+ old_eof = i_size_read (inode );
3683
+ if ((off >= old_eof ) ||
3684
+ off + len >= old_eof ) {
3693
3685
rc = - EINVAL ;
3694
3686
goto out ;
3695
3687
}
3696
3688
3689
+ filemap_invalidate_lock (inode -> i_mapping );
3690
+ rc = filemap_write_and_wait_range (inode -> i_mapping , off , old_eof - 1 );
3691
+ if (rc < 0 )
3692
+ goto out_2 ;
3693
+
3694
+ truncate_pagecache_range (inode , off , old_eof );
3695
+
3697
3696
rc = smb2_copychunk_range (xid , cfile , cfile , off + len ,
3698
- i_size_read ( inode ) - off - len , off );
3697
+ old_eof - off - len , off );
3699
3698
if (rc < 0 )
3700
- goto out ;
3699
+ goto out_2 ;
3701
3700
3702
- eof = cpu_to_le64 (i_size_read ( inode ) - len );
3701
+ eof = cpu_to_le64 (old_eof - len );
3703
3702
rc = SMB2_set_eof (xid , tcon , cfile -> fid .persistent_fid ,
3704
3703
cfile -> fid .volatile_fid , cfile -> pid , & eof );
3705
3704
if (rc < 0 )
3706
- goto out ;
3705
+ goto out_2 ;
3707
3706
3708
3707
rc = 0 ;
3709
3708
3710
3709
cifsi -> server_eof = i_size_read (inode ) - len ;
3711
3710
truncate_setsize (inode , cifsi -> server_eof );
3712
3711
fscache_resize_cookie (cifs_inode_cookie (inode ), cifsi -> server_eof );
3712
+ out_2 :
3713
+ filemap_invalidate_unlock (inode -> i_mapping );
3713
3714
out :
3715
+ inode_unlock (inode );
3714
3716
free_xid (xid );
3715
3717
return rc ;
3716
3718
}
@@ -3721,34 +3723,47 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
3721
3723
int rc ;
3722
3724
unsigned int xid ;
3723
3725
struct cifsFileInfo * cfile = file -> private_data ;
3726
+ struct inode * inode = file_inode (file );
3724
3727
__le64 eof ;
3725
- __u64 count ;
3728
+ __u64 count , old_eof ;
3726
3729
3727
3730
xid = get_xid ();
3728
3731
3729
- if (off >= i_size_read (file -> f_inode )) {
3732
+ inode_lock (inode );
3733
+
3734
+ old_eof = i_size_read (inode );
3735
+ if (off >= old_eof ) {
3730
3736
rc = - EINVAL ;
3731
3737
goto out ;
3732
3738
}
3733
3739
3734
- count = i_size_read (file -> f_inode ) - off ;
3735
- eof = cpu_to_le64 (i_size_read (file -> f_inode ) + len );
3740
+ count = old_eof - off ;
3741
+ eof = cpu_to_le64 (old_eof + len );
3742
+
3743
+ filemap_invalidate_lock (inode -> i_mapping );
3744
+ rc = filemap_write_and_wait_range (inode -> i_mapping , off , old_eof + len - 1 );
3745
+ if (rc < 0 )
3746
+ goto out_2 ;
3747
+ truncate_pagecache_range (inode , off , old_eof );
3736
3748
3737
3749
rc = SMB2_set_eof (xid , tcon , cfile -> fid .persistent_fid ,
3738
3750
cfile -> fid .volatile_fid , cfile -> pid , & eof );
3739
3751
if (rc < 0 )
3740
- goto out ;
3752
+ goto out_2 ;
3741
3753
3742
3754
rc = smb2_copychunk_range (xid , cfile , cfile , off , count , off + len );
3743
3755
if (rc < 0 )
3744
- goto out ;
3756
+ goto out_2 ;
3745
3757
3746
- rc = smb3_zero_range (file , tcon , off , len , 1 );
3758
+ rc = smb3_zero_data (file , tcon , off , len , xid );
3747
3759
if (rc < 0 )
3748
- goto out ;
3760
+ goto out_2 ;
3749
3761
3750
3762
rc = 0 ;
3763
+ out_2 :
3764
+ filemap_invalidate_unlock (inode -> i_mapping );
3751
3765
out :
3766
+ inode_unlock (inode );
3752
3767
free_xid (xid );
3753
3768
return rc ;
3754
3769
}
0 commit comments