Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag '6.0-rc3-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
"Five fixes, all also marked for stable:

- fixes for collapse range and insert range (also fixes xfstest
generic/031)

- memory leak fix"

* tag '6.0-rc3-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
cifs: fix small mempool leak in SMB2_negotiate()
smb3: use filemap_write_and_wait_range instead of filemap_write_and_wait
smb3: fix temporary data corruption in insert range
smb3: fix temporary data corruption in collapse range
smb3: Move the flush out of smb2_copychunk_range() into its callers

+56 -33
+6
fs/cifs/cifsfs.c
··· 1248 1248 lock_two_nondirectories(target_inode, src_inode); 1249 1249 1250 1250 cifs_dbg(FYI, "about to flush pages\n"); 1251 + 1252 + rc = filemap_write_and_wait_range(src_inode->i_mapping, off, 1253 + off + len - 1); 1254 + if (rc) 1255 + goto out; 1256 + 1251 1257 /* should we flush first and last page first */ 1252 1258 truncate_inode_pages(&target_inode->i_data, 0); 1253 1259
+43 -28
fs/cifs/smb2ops.c
··· 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 ··· 3669 3678 { 3670 3679 int rc; 3671 3680 unsigned int xid; 3672 - struct inode *inode; 3681 + struct inode *inode = file_inode(file); 3673 3682 struct cifsFileInfo *cfile = file->private_data; 3674 - struct cifsInodeInfo *cifsi; 3683 + struct cifsInodeInfo *cifsi = CIFS_I(inode); 3675 3684 __le64 eof; 3685 + loff_t old_eof; 3676 3686 3677 3687 xid = get_xid(); 3678 3688 3679 - inode = d_inode(cfile->dentry); 3680 - cifsi = CIFS_I(inode); 3689 + inode_lock(inode); 3681 3690 3682 - if (off >= i_size_read(inode) || 3683 - off + len >= i_size_read(inode)) { 3691 + old_eof = i_size_read(inode); 3692 + if ((off >= old_eof) || 3693 + off + len >= old_eof) { 3684 3694 rc = -EINVAL; 3685 3695 goto out; 3686 3696 } 3687 3697 3688 - rc = smb2_copychunk_range(xid, cfile, cfile, off + len, 3689 - i_size_read(inode) - off - len, off); 3698 + filemap_invalidate_lock(inode->i_mapping); 3699 + rc = filemap_write_and_wait_range(inode->i_mapping, off, old_eof - 1); 3690 3700 if (rc < 0) 3691 - goto out; 3701 + goto out_2; 3692 3702 3693 - eof = cpu_to_le64(i_size_read(inode) - len); 3703 + truncate_pagecache_range(inode, off, old_eof); 3704 + 3705 + rc = smb2_copychunk_range(xid, cfile, cfile, off + len, 3706 + old_eof - off - len, off); 3707 + if (rc < 0) 3708 + goto out_2; 3709 + 3710 + eof = cpu_to_le64(old_eof - len); 3694 3711 rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid, 3695 3712 cfile->fid.volatile_fid, cfile->pid, &eof); 3696 3713 if (rc < 0) 3697 - goto out; 3714 + goto out_2; 3698 3715 3699 3716 rc = 0; 3700 3717 3701 3718 cifsi->server_eof = i_size_read(inode) - len; 3702 3719 truncate_setsize(inode, cifsi->server_eof); 3703 3720 fscache_resize_cookie(cifs_inode_cookie(inode), cifsi->server_eof); 3721 + out_2: 3722 + filemap_invalidate_unlock(inode->i_mapping); 3704 3723 out: 3724 + inode_unlock(inode); 3705 3725 free_xid(xid); 3706 3726 return rc; 3707 3727 } ··· 3723 3721 int rc; 3724 3722 unsigned int xid; 3725 3723 struct cifsFileInfo *cfile = file->private_data; 3724 + struct inode *inode = file_inode(file); 3726 3725 __le64 eof; 3727 - __u64 count; 3726 + __u64 count, old_eof; 3728 3727 3729 3728 xid = get_xid(); 3730 3729 3731 - if (off >= i_size_read(file->f_inode)) { 3730 + inode_lock(inode); 3731 + 3732 + old_eof = i_size_read(inode); 3733 + if (off >= old_eof) { 3732 3734 rc = -EINVAL; 3733 3735 goto out; 3734 3736 } 3735 3737 3736 - count = i_size_read(file->f_inode) - off; 3737 - eof = cpu_to_le64(i_size_read(file->f_inode) + len); 3738 + count = old_eof - off; 3739 + eof = cpu_to_le64(old_eof + len); 3740 + 3741 + filemap_invalidate_lock(inode->i_mapping); 3742 + rc = filemap_write_and_wait_range(inode->i_mapping, off, old_eof + len - 1); 3743 + if (rc < 0) 3744 + goto out_2; 3745 + truncate_pagecache_range(inode, off, old_eof); 3738 3746 3739 3747 rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid, 3740 3748 cfile->fid.volatile_fid, cfile->pid, &eof); 3741 3749 if (rc < 0) 3742 - goto out; 3750 + goto out_2; 3743 3751 3744 3752 rc = smb2_copychunk_range(xid, cfile, cfile, off, count, off + len); 3745 3753 if (rc < 0) 3746 - goto out; 3754 + goto out_2; 3747 3755 3748 - rc = smb3_zero_range(file, tcon, off, len, 1); 3756 + rc = smb3_zero_data(file, tcon, off, len, xid); 3749 3757 if (rc < 0) 3750 - goto out; 3758 + goto out_2; 3751 3759 3752 3760 rc = 0; 3761 + out_2: 3762 + filemap_invalidate_unlock(inode->i_mapping); 3753 3763 out: 3764 + inode_unlock(inode); 3754 3765 free_xid(xid); 3755 3766 return rc; 3756 3767 }
+7 -5
fs/cifs/smb2pdu.c
··· 965 965 } else if (rc != 0) 966 966 goto neg_exit; 967 967 968 + rc = -EIO; 968 969 if (strcmp(server->vals->version_string, 969 970 SMB3ANY_VERSION_STRING) == 0) { 970 971 if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) { 971 972 cifs_server_dbg(VFS, 972 973 "SMB2 dialect returned but not requested\n"); 973 - return -EIO; 974 + goto neg_exit; 974 975 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { 975 976 cifs_server_dbg(VFS, 976 977 "SMB2.1 dialect returned but not requested\n"); 977 - return -EIO; 978 + goto neg_exit; 978 979 } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) { 979 980 /* ops set to 3.0 by default for default so update */ 980 981 server->ops = &smb311_operations; ··· 986 985 if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) { 987 986 cifs_server_dbg(VFS, 988 987 "SMB2 dialect returned but not requested\n"); 989 - return -EIO; 988 + goto neg_exit; 990 989 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { 991 990 /* ops set to 3.0 by default for default so update */ 992 991 server->ops = &smb21_operations; ··· 1000 999 /* if requested single dialect ensure returned dialect matched */ 1001 1000 cifs_server_dbg(VFS, "Invalid 0x%x dialect returned: not requested\n", 1002 1001 le16_to_cpu(rsp->DialectRevision)); 1003 - return -EIO; 1002 + goto neg_exit; 1004 1003 } 1005 1004 1006 1005 cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode); ··· 1018 1017 else { 1019 1018 cifs_server_dbg(VFS, "Invalid dialect returned by server 0x%x\n", 1020 1019 le16_to_cpu(rsp->DialectRevision)); 1021 - rc = -EIO; 1022 1020 goto neg_exit; 1023 1021 } 1022 + 1023 + rc = 0; 1024 1024 server->dialect = le16_to_cpu(rsp->DialectRevision); 1025 1025 1026 1026 /*