@@ -1843,13 +1843,73 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
18431843 return rc ;
18441844}
18451845
1846+ static int
1847+ read_data_into_pages (struct TCP_Server_Info * server , struct page * * pages ,
1848+ unsigned int npages , unsigned int len )
1849+ {
1850+ int i ;
1851+ int length ;
1852+
1853+ for (i = 0 ; i < npages ; i ++ ) {
1854+ struct page * page = pages [i ];
1855+ size_t n ;
1856+
1857+ n = len ;
1858+ if (len >= PAGE_SIZE ) {
1859+ /* enough data to fill the page */
1860+ n = PAGE_SIZE ;
1861+ len -= n ;
1862+ } else {
1863+ zero_user (page , len , PAGE_SIZE - len );
1864+ len = 0 ;
1865+ }
1866+ length = cifs_read_page_from_socket (server , page , n );
1867+ if (length < 0 )
1868+ return length ;
1869+ server -> total_read += length ;
1870+ }
1871+
1872+ return 0 ;
1873+ }
1874+
1875+ static int
1876+ init_read_bvec (struct page * * pages , unsigned int npages , unsigned int data_size ,
1877+ unsigned int cur_off , struct bio_vec * * page_vec )
1878+ {
1879+ struct bio_vec * bvec ;
1880+ int i ;
1881+
1882+ bvec = kcalloc (npages , sizeof (struct bio_vec ), GFP_KERNEL );
1883+ if (!bvec )
1884+ return - ENOMEM ;
1885+
1886+ for (i = 0 ; i < npages ; i ++ ) {
1887+ bvec [i ].bv_page = pages [i ];
1888+ bvec [i ].bv_offset = (i == 0 ) ? cur_off : 0 ;
1889+ bvec [i ].bv_len = min_t (unsigned int , PAGE_SIZE , data_size );
1890+ data_size -= bvec [i ].bv_len ;
1891+ }
1892+
1893+ if (data_size != 0 ) {
1894+ cifs_dbg (VFS , "%s: something went wrong\n" , __func__ );
1895+ kfree (bvec );
1896+ return - EIO ;
1897+ }
1898+
1899+ * page_vec = bvec ;
1900+ return 0 ;
1901+ }
1902+
18461903static int
18471904handle_read_data (struct TCP_Server_Info * server , struct mid_q_entry * mid ,
18481905 char * buf , unsigned int buf_len , struct page * * pages ,
18491906 unsigned int npages , unsigned int page_data_size )
18501907{
18511908 unsigned int data_offset ;
18521909 unsigned int data_len ;
1910+ unsigned int cur_off ;
1911+ unsigned int cur_page_idx ;
1912+ unsigned int pad_len ;
18531913 struct cifs_readdata * rdata = mid -> callback_data ;
18541914 struct smb2_sync_hdr * shdr = get_sync_hdr (buf );
18551915 struct bio_vec * bvec = NULL ;
@@ -1895,9 +1955,37 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
18951955 return 0 ;
18961956 }
18971957
1958+ pad_len = data_offset - server -> vals -> read_rsp_size ;
1959+
18981960 if (buf_len <= data_offset ) {
18991961 /* read response payload is in pages */
1900- /* BB add code to init iter with pages */
1962+ cur_page_idx = pad_len / PAGE_SIZE ;
1963+ cur_off = pad_len % PAGE_SIZE ;
1964+
1965+ if (cur_page_idx != 0 ) {
1966+ /* data offset is beyond the 1st page of response */
1967+ cifs_dbg (FYI , "%s: data offset (%u) beyond 1st page of response\n" ,
1968+ __func__ , data_offset );
1969+ rdata -> result = - EIO ;
1970+ dequeue_mid (mid , rdata -> result );
1971+ return 0 ;
1972+ }
1973+
1974+ if (data_len > page_data_size - pad_len ) {
1975+ /* data_len is corrupt -- discard frame */
1976+ rdata -> result = - EIO ;
1977+ dequeue_mid (mid , rdata -> result );
1978+ return 0 ;
1979+ }
1980+
1981+ rdata -> result = init_read_bvec (pages , npages , page_data_size ,
1982+ cur_off , & bvec );
1983+ if (rdata -> result != 0 ) {
1984+ dequeue_mid (mid , rdata -> result );
1985+ return 0 ;
1986+ }
1987+
1988+ iov_iter_bvec (& iter , WRITE | ITER_BVEC , bvec , npages , data_len );
19011989 } else if (buf_len >= data_offset + data_len ) {
19021990 /* read response payload is in buf */
19031991 WARN_ONCE (npages > 0 , "read data can be either in buf or in pages" );
@@ -1931,6 +2019,79 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
19312019 return length ;
19322020}
19332021
2022+ static int
2023+ receive_encrypted_read (struct TCP_Server_Info * server , struct mid_q_entry * * mid )
2024+ {
2025+ char * buf = server -> smallbuf ;
2026+ struct smb2_transform_hdr * tr_hdr = (struct smb2_transform_hdr * )buf ;
2027+ unsigned int npages ;
2028+ struct page * * pages ;
2029+ unsigned int len ;
2030+ unsigned int buflen = get_rfc1002_length (buf ) + 4 ;
2031+ int rc ;
2032+ int i = 0 ;
2033+
2034+ len = min_t (unsigned int , buflen , server -> vals -> read_rsp_size - 4 +
2035+ sizeof (struct smb2_transform_hdr )) - HEADER_SIZE (server ) + 1 ;
2036+
2037+ rc = cifs_read_from_socket (server , buf + HEADER_SIZE (server ) - 1 , len );
2038+ if (rc < 0 )
2039+ return rc ;
2040+ server -> total_read += rc ;
2041+
2042+ len = le32_to_cpu (tr_hdr -> OriginalMessageSize ) + 4 -
2043+ server -> vals -> read_rsp_size ;
2044+ npages = DIV_ROUND_UP (len , PAGE_SIZE );
2045+
2046+ pages = kmalloc_array (npages , sizeof (struct page * ), GFP_KERNEL );
2047+ if (!pages ) {
2048+ rc = - ENOMEM ;
2049+ goto discard_data ;
2050+ }
2051+
2052+ for (; i < npages ; i ++ ) {
2053+ pages [i ] = alloc_page (GFP_KERNEL |__GFP_HIGHMEM );
2054+ if (!pages [i ]) {
2055+ rc = - ENOMEM ;
2056+ goto discard_data ;
2057+ }
2058+ }
2059+
2060+ /* read read data into pages */
2061+ rc = read_data_into_pages (server , pages , npages , len );
2062+ if (rc )
2063+ goto free_pages ;
2064+
2065+ rc = cifs_discard_remaining_data (server );
2066+ if (rc )
2067+ goto free_pages ;
2068+
2069+ rc = decrypt_raw_data (server , buf , server -> vals -> read_rsp_size - 4 ,
2070+ pages , npages , len );
2071+ if (rc )
2072+ goto free_pages ;
2073+
2074+ * mid = smb2_find_mid (server , buf );
2075+ if (* mid == NULL )
2076+ cifs_dbg (FYI , "mid not found\n" );
2077+ else {
2078+ cifs_dbg (FYI , "mid found\n" );
2079+ (* mid )-> decrypted = true;
2080+ rc = handle_read_data (server , * mid , buf ,
2081+ server -> vals -> read_rsp_size ,
2082+ pages , npages , len );
2083+ }
2084+
2085+ free_pages :
2086+ for (i = i - 1 ; i >= 0 ; i -- )
2087+ put_page (pages [i ]);
2088+ kfree (pages );
2089+ return rc ;
2090+ discard_data :
2091+ cifs_discard_remaining_data (server );
2092+ goto free_pages ;
2093+ }
2094+
19342095static int
19352096receive_encrypted_standard (struct TCP_Server_Info * server ,
19362097 struct mid_q_entry * * mid )
@@ -2000,14 +2161,8 @@ smb3_receive_transform(struct TCP_Server_Info *server, struct mid_q_entry **mid)
20002161 return - ECONNABORTED ;
20012162 }
20022163
2003- if (pdu_length + 4 > CIFSMaxBufSize + MAX_HEADER_SIZE (server )) {
2004- cifs_dbg (VFS , "Decoding responses of big size (%u) is not supported\n" ,
2005- pdu_length );
2006- /* BB add code to allocate and fill highmem pages here */
2007- cifs_reconnect (server );
2008- wake_up (& server -> response_q );
2009- return - ECONNABORTED ;
2010- }
2164+ if (pdu_length + 4 > CIFSMaxBufSize + MAX_HEADER_SIZE (server ))
2165+ return receive_encrypted_read (server , mid );
20112166
20122167 return receive_encrypted_standard (server , mid );
20132168}
0 commit comments