summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorRonnie Sahlberg <lsahlber@redhat.com>2021-07-22 14:53:32 +1000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-07-28 14:35:41 +0200
commitc26372b8a8c301d56204cddb9aedfa2c67adac17 (patch)
tree37859d232f3757e9744b48f114fee6ecf99f4132 /fs/cifs
parentb91e5b63470d7a2f5225540e8093b06426d00bf9 (diff)
downloadlinux-stable-c26372b8a8c301d56204cddb9aedfa2c67adac17.tar.gz
linux-stable-c26372b8a8c301d56204cddb9aedfa2c67adac17.tar.bz2
linux-stable-c26372b8a8c301d56204cddb9aedfa2c67adac17.zip
cifs: only write 64kb at a time when fallocating a small region of a file
[ Upstream commit 2485bd7557a7edb4520b4072af464f0a08c8efe0 ] We only allow sending single credit writes through the SMB2_write() synchronous api so split this into smaller chunks. Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation") Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Reported-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/smb2ops.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index f6ceb79a995d..442bf422aa01 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -3466,7 +3466,7 @@ static int smb3_simple_fallocate_write_range(unsigned int xid,
char *buf)
{
struct cifs_io_parms io_parms = {0};
- int nbytes;
+ int rc, nbytes;
struct kvec iov[2];
io_parms.netfid = cfile->fid.netfid;
@@ -3474,13 +3474,25 @@ static int smb3_simple_fallocate_write_range(unsigned int xid,
io_parms.tcon = tcon;
io_parms.persistent_fid = cfile->fid.persistent_fid;
io_parms.volatile_fid = cfile->fid.volatile_fid;
- io_parms.offset = off;
- io_parms.length = len;
- /* iov[0] is reserved for smb header */
- iov[1].iov_base = buf;
- iov[1].iov_len = io_parms.length;
- return SMB2_write(xid, &io_parms, &nbytes, iov, 1);
+ while (len) {
+ io_parms.offset = off;
+ io_parms.length = len;
+ if (io_parms.length > SMB2_MAX_BUFFER_SIZE)
+ io_parms.length = SMB2_MAX_BUFFER_SIZE;
+ /* iov[0] is reserved for smb header */
+ iov[1].iov_base = buf;
+ iov[1].iov_len = io_parms.length;
+ rc = SMB2_write(xid, &io_parms, &nbytes, iov, 1);
+ if (rc)
+ break;
+ if (nbytes > len)
+ return -EINVAL;
+ buf += nbytes;
+ off += nbytes;
+ len -= nbytes;
+ }
+ return rc;
}
static int smb3_simple_fallocate_range(unsigned int xid,