smb/client: reduce fallocate zero buffer allocation

The fallocate emulation allocates a 1 MiB zero-filled buffer even
though each SMB2_write request is limited to SMB2_MAX_BUFFER_SIZE,
which is 64 KiB. A high-order 1 MiB allocation is more likely to
fail on a fragmented system.

Allocate only the smaller of the requested range and SMB2_MAX_BUFFER_SIZE,
and reuse that zero-filled buffer for every write request. Also reject
a successful write that makes no progress to avoid looping indefinitely.

This reduces the contiguous allocation required by fallocate emulation
without changing the written data or range semantics.

Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
Huiwen He
2026-07-03 13:32:57 +08:00
committed by Steve French
parent b09ae45d85
commit 9e4ec3be67

View File

@@ -3573,7 +3573,7 @@ static int smb3_simple_fallocate_write_range(unsigned int xid,
char *buf)
{
struct cifs_io_parms io_parms = {0};
int nbytes;
unsigned int nbytes;
int rc = 0;
struct kvec iov[2];
@@ -3594,9 +3594,10 @@ static int smb3_simple_fallocate_write_range(unsigned int xid,
rc = SMB2_write(xid, &io_parms, &nbytes, iov, 1);
if (rc)
break;
if (!nbytes)
return -EIO;
if (nbytes > len)
return -EINVAL;
buf += nbytes;
off += nbytes;
len -= nbytes;
}
@@ -3626,7 +3627,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,
if (rc)
goto out;
buf = kvzalloc(1024 * 1024, GFP_KERNEL);
buf = kvzalloc(min_t(loff_t, len, SMB2_MAX_BUFFER_SIZE), GFP_KERNEL);
if (buf == NULL) {
rc = -ENOMEM;
goto out;