hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/cifs/cifsglob.h
....@@ -22,6 +22,8 @@
2222 #include <linux/in.h>
2323 #include <linux/in6.h>
2424 #include <linux/slab.h>
25
+#include <linux/scatterlist.h>
26
+#include <linux/mm.h>
2527 #include <linux/mempool.h>
2628 #include <linux/workqueue.h>
2729 #include "cifs_fs_sb.h"
....@@ -30,6 +32,7 @@
3032 #include <linux/scatterlist.h>
3133 #include <uapi/linux/cifs/cifs_mount.h>
3234 #include "smb2pdu.h"
35
+#include "smb2glob.h"
3336
3437 #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
3538
....@@ -2046,4 +2049,70 @@
20462049 tcon->share_flags & (SHI1005_FLAGS_DFS | SHI1005_FLAGS_DFS_ROOT);
20472050 }
20482051
2052
+static inline unsigned int cifs_get_num_sgs(const struct smb_rqst *rqst,
2053
+ int num_rqst,
2054
+ const u8 *sig)
2055
+{
2056
+ unsigned int len, skip;
2057
+ unsigned int nents = 0;
2058
+ unsigned long addr;
2059
+ int i, j;
2060
+
2061
+ /* Assumes the first rqst has a transform header as the first iov.
2062
+ * I.e.
2063
+ * rqst[0].rq_iov[0] is transform header
2064
+ * rqst[0].rq_iov[1+] data to be encrypted/decrypted
2065
+ * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
2066
+ */
2067
+ for (i = 0; i < num_rqst; i++) {
2068
+ /*
2069
+ * The first rqst has a transform header where the
2070
+ * first 20 bytes are not part of the encrypted blob.
2071
+ */
2072
+ for (j = 0; j < rqst[i].rq_nvec; j++) {
2073
+ struct kvec *iov = &rqst[i].rq_iov[j];
2074
+
2075
+ skip = (i == 0) && (j == 0) ? 20 : 0;
2076
+ addr = (unsigned long)iov->iov_base + skip;
2077
+ if (unlikely(is_vmalloc_addr((void *)addr))) {
2078
+ len = iov->iov_len - skip;
2079
+ nents += DIV_ROUND_UP(offset_in_page(addr) + len,
2080
+ PAGE_SIZE);
2081
+ } else {
2082
+ nents++;
2083
+ }
2084
+ }
2085
+ nents += rqst[i].rq_npages;
2086
+ }
2087
+ nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
2088
+ return nents;
2089
+}
2090
+
2091
+/* We can not use the normal sg_set_buf() as we will sometimes pass a
2092
+ * stack object as buf.
2093
+ */
2094
+static inline struct scatterlist *cifs_sg_set_buf(struct scatterlist *sg,
2095
+ const void *buf,
2096
+ unsigned int buflen)
2097
+{
2098
+ unsigned long addr = (unsigned long)buf;
2099
+ unsigned int off = offset_in_page(addr);
2100
+
2101
+ addr &= PAGE_MASK;
2102
+ if (unlikely(is_vmalloc_addr((void *)addr))) {
2103
+ do {
2104
+ unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
2105
+
2106
+ sg_set_page(sg++, vmalloc_to_page((void *)addr), len, off);
2107
+
2108
+ off = 0;
2109
+ addr += PAGE_SIZE;
2110
+ buflen -= len;
2111
+ } while (buflen);
2112
+ } else {
2113
+ sg_set_page(sg++, virt_to_page(addr), buflen, off);
2114
+ }
2115
+ return sg;
2116
+}
2117
+
20492118 #endif /* _CIFS_GLOB_H */