Commit 9c8b7a29 authored by David Howells's avatar David Howells Committed by Steve French
Browse files

smb3: fix temporary data corruption in insert range



insert range doesn't discard the affected cached region
so can risk temporarily corrupting file data.

Also includes some minor cleanup (avoiding rereading
inode size repeatedly unnecessarily) to make it clearer.

Cc: stable@vger.kernel.org
Fixes: 7fe6fe95 ("cifs: add FALLOC_FL_INSERT_RANGE support")
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent fa30a81f
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -3722,35 +3722,43 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
	struct cifsFileInfo *cfile = file->private_data;
	struct inode *inode = file_inode(file);
	__le64 eof;
	__u64  count;
	__u64  count, old_eof;

	xid = get_xid();

	if (off >= i_size_read(inode)) {
	inode_lock(inode);

	old_eof = i_size_read(inode);
	if (off >= old_eof) {
		rc = -EINVAL;
		goto out;
	}

	count = i_size_read(inode) - off;
	eof = cpu_to_le64(i_size_read(inode) + len);
	count = old_eof - off;
	eof = cpu_to_le64(old_eof + len);

	filemap_invalidate_lock(inode->i_mapping);
	filemap_write_and_wait(inode->i_mapping);
	truncate_pagecache_range(inode, off, old_eof);

	rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
			  cfile->fid.volatile_fid, cfile->pid, &eof);
	if (rc < 0)
		goto out;
		goto out_2;

	rc = smb2_copychunk_range(xid, cfile, cfile, off, count, off + len);
	if (rc < 0)
		goto out;
		goto out_2;

	rc = smb3_zero_range(file, tcon, off, len, 1);
	rc = smb3_zero_data(file, tcon, off, len, xid);
	if (rc < 0)
		goto out;
		goto out_2;

	rc = 0;
out_2:
	filemap_invalidate_unlock(inode->i_mapping);
 out:
	inode_unlock(inode);
	free_xid(xid);
	return rc;
}