[Devel] [PATCH RHEL7 COMMIT] ms/cifs: Limit memory used by lock request calls to a page

Vasily Averin vvs at virtuozzo.com
Fri Jun 4 13:23:38 MSK 2021


The commit is pushed to "branch-rh7-3.10.0-1160.25.1.vz7.180.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.25.1.vz7.180.11
------>
commit e10f10d7758f6a0f8f092b8921f905dc2d20b142
Author: Ross Lagerwall <ross.lagerwall at citrix.com>
Date:   Fri Jun 4 13:23:38 2021 +0300

    ms/cifs: Limit memory used by lock request calls to a page
    
    The code tries to allocate a contiguous buffer with a size supplied by
    the server (maxBuf). This could fail if memory is fragmented since it
    results in high order allocations for commonly used server
    implementations. It is also wasteful since there are probably
    few locks in the usual case. Limit the buffer to be no larger than a
    page to avoid memory allocation failures due to fragmentation.
    
    Signed-off-by: Ross Lagerwall <ross.lagerwall at citrix.com>
    Signed-off-by: Steve French <stfrench at microsoft.com>
    (cherry picked from commit 92a8109e4d3a34fb6b115c9098b51767dc933444)
    https://jira.sw.ru/browse/PSBM-130341
    Signed-off-by: Vasily Averin <vvs at virtuozzo.com>
---
 fs/cifs/file.c     | 8 ++++++++
 fs/cifs/smb2file.c | 4 ++++
 2 files changed, 12 insertions(+)

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 32b147d..c11d83c 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1164,6 +1164,10 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
 		return -EINVAL;
 	}
 
+	BUILD_BUG_ON(sizeof(struct smb_hdr) + sizeof(LOCKING_ANDX_RANGE) >
+		     PAGE_SIZE);
+	max_buf = min_t(unsigned int, max_buf - sizeof(struct smb_hdr),
+			PAGE_SIZE);
 	max_num = (max_buf - sizeof(struct smb_hdr)) /
 						sizeof(LOCKING_ANDX_RANGE);
 	buf = kcalloc(max_num, sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
@@ -1508,6 +1512,10 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
 	if (!max_buf)
 		return -EINVAL;
 
+	BUILD_BUG_ON(sizeof(struct smb_hdr) + sizeof(LOCKING_ANDX_RANGE) >
+		     PAGE_SIZE);
+	max_buf = min_t(unsigned int, max_buf - sizeof(struct smb_hdr),
+			PAGE_SIZE);
 	max_num = (max_buf - sizeof(struct smb_hdr)) /
 						sizeof(LOCKING_ANDX_RANGE);
 	buf = kcalloc(max_num, sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
index 885d7c3..56b9530 100644
--- a/fs/cifs/smb2file.c
+++ b/fs/cifs/smb2file.c
@@ -127,6 +127,8 @@ smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
 	if (!max_buf)
 		return -EINVAL;
 
+	BUILD_BUG_ON(sizeof(struct smb2_lock_element) > PAGE_SIZE);
+	max_buf = min_t(unsigned int, max_buf, PAGE_SIZE);
 	max_num = max_buf / sizeof(struct smb2_lock_element);
 	buf = kcalloc(max_num, sizeof(struct smb2_lock_element), GFP_KERNEL);
 	if (!buf)
@@ -263,6 +265,8 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
 		return -EINVAL;
 	}
 
+	BUILD_BUG_ON(sizeof(struct smb2_lock_element) > PAGE_SIZE);
+	max_buf = min_t(unsigned int, max_buf, PAGE_SIZE);
 	max_num = max_buf / sizeof(struct smb2_lock_element);
 	buf = kcalloc(max_num, sizeof(struct smb2_lock_element), GFP_KERNEL);
 	if (!buf) {


More information about the Devel mailing list