From: Ross Lagerwall <[email protected]>

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 <[email protected]>
Signed-off-by: Steve French <[email protected]>
(cherry picked from commit 92a8109e4d3a34fb6b115c9098b51767dc933444)
https://jira.sw.ru/browse/PSBM-130341
Signed-off-by: Vasily Averin <[email protected]>
---
 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 32b147dff4f4..c11d83ca4e85 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 885d7c31d76c..56b953010b02 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) {
-- 
2.25.1

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to