Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

cifs: smbd: Avoid allocating iov on the stack

It's not necessary to allocate another iov when going through the buffers
in smbd_send() through RDMA send.

Remove it to reduce stack size.

Thanks to Matt for spotting a printk typo in the earlier version of this.

CC: Matt Redfearn <matt.redfearn@mips.com>
Signed-off-by: Long Li <longli@microsoft.com>
Acked-by: Ronnie Sahlberg <lsahlber@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Steve French <smfrench@gmail.com>

authored by

Long Li and committed by
Steve French
8bcda1d2 bb4c0419

+12 -24
+12 -24
fs/cifs/smbdirect.c
··· 2086 2086 int start, i, j; 2087 2087 int max_iov_size = 2088 2088 info->max_send_size - sizeof(struct smbd_data_transfer); 2089 - struct kvec iov[SMBDIRECT_MAX_SGE]; 2089 + struct kvec *iov; 2090 2090 int rc; 2091 2091 2092 2092 info->smbd_send_pending++; ··· 2096 2096 } 2097 2097 2098 2098 /* 2099 - * This usually means a configuration error 2100 - * We use RDMA read/write for packet size > rdma_readwrite_threshold 2101 - * as long as it's properly configured we should never get into this 2102 - * situation 2103 - */ 2104 - if (rqst->rq_nvec + rqst->rq_npages > SMBDIRECT_MAX_SGE) { 2105 - log_write(ERR, "maximum send segment %x exceeding %x\n", 2106 - rqst->rq_nvec + rqst->rq_npages, SMBDIRECT_MAX_SGE); 2107 - rc = -EINVAL; 2108 - goto done; 2109 - } 2110 - 2111 - /* 2112 - * Remove the RFC1002 length defined in MS-SMB2 section 2.1 2113 - * It is used only for TCP transport 2099 + * Skip the RFC1002 length defined in MS-SMB2 section 2.1 2100 + * It is used only for TCP transport in the iov[0] 2114 2101 * In future we may want to add a transport layer under protocol 2115 2102 * layer so this will only be issued to TCP transport 2116 2103 */ 2117 - iov[0].iov_base = (char *)rqst->rq_iov[0].iov_base + 4; 2118 - iov[0].iov_len = rqst->rq_iov[0].iov_len - 4; 2119 - buflen += iov[0].iov_len; 2104 + 2105 + if (rqst->rq_iov[0].iov_len != 4) { 2106 + log_write(ERR, "expected the pdu length in 1st iov, but got %zu\n", rqst->rq_iov[0].iov_len); 2107 + return -EINVAL; 2108 + } 2109 + iov = &rqst->rq_iov[1]; 2120 2110 2121 2111 /* total up iov array first */ 2122 - for (i = 1; i < rqst->rq_nvec; i++) { 2123 - iov[i].iov_base = rqst->rq_iov[i].iov_base; 2124 - iov[i].iov_len = rqst->rq_iov[i].iov_len; 2112 + for (i = 0; i < rqst->rq_nvec-1; i++) { 2125 2113 buflen += iov[i].iov_len; 2126 2114 } 2127 2115 ··· 2186 2198 goto done; 2187 2199 } 2188 2200 i++; 2189 - if (i == rqst->rq_nvec) 2201 + if (i == rqst->rq_nvec-1) 2190 2202 break; 2191 2203 } 2192 2204 start = i; 2193 2205 buflen = 0; 2194 2206 } else { 2195 2207 i++; 2196 - if (i == rqst->rq_nvec) { 2208 + if (i == rqst->rq_nvec-1) { 2197 2209 /* send out all remaining vecs */ 2198 2210 remaining_data_length -= buflen; 2199 2211 log_write(INFO,