@@ -264,7 +264,7 @@ smb2_revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)
264264}
265265
266266static struct mid_q_entry *
267- smb2_find_mid (struct TCP_Server_Info * server , char * buf )
267+ __smb2_find_mid (struct TCP_Server_Info * server , char * buf , bool dequeue )
268268{
269269 struct mid_q_entry * mid ;
270270 struct smb2_sync_hdr * shdr = (struct smb2_sync_hdr * )buf ;
@@ -281,6 +281,10 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf)
281281 (mid -> mid_state == MID_REQUEST_SUBMITTED ) &&
282282 (mid -> command == shdr -> Command )) {
283283 kref_get (& mid -> refcount );
284+ if (dequeue ) {
285+ list_del_init (& mid -> qhead );
286+ mid -> mid_flags |= MID_DELETED ;
287+ }
284288 spin_unlock (& GlobalMid_Lock );
285289 return mid ;
286290 }
@@ -289,6 +293,18 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf)
289293 return NULL ;
290294}
291295
296+ static struct mid_q_entry *
297+ smb2_find_mid (struct TCP_Server_Info * server , char * buf )
298+ {
299+ return __smb2_find_mid (server , buf , false);
300+ }
301+
302+ static struct mid_q_entry *
303+ smb2_find_dequeue_mid (struct TCP_Server_Info * server , char * buf )
304+ {
305+ return __smb2_find_mid (server , buf , true);
306+ }
307+
292308static void
293309smb2_dump_detail (void * buf , struct TCP_Server_Info * server )
294310{
@@ -4356,7 +4372,8 @@ init_read_bvec(struct page **pages, unsigned int npages, unsigned int data_size,
43564372static int
43574373handle_read_data (struct TCP_Server_Info * server , struct mid_q_entry * mid ,
43584374 char * buf , unsigned int buf_len , struct page * * pages ,
4359- unsigned int npages , unsigned int page_data_size )
4375+ unsigned int npages , unsigned int page_data_size ,
4376+ bool is_offloaded )
43604377{
43614378 unsigned int data_offset ;
43624379 unsigned int data_len ;
@@ -4378,7 +4395,8 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
43784395
43794396 if (server -> ops -> is_session_expired &&
43804397 server -> ops -> is_session_expired (buf )) {
4381- cifs_reconnect (server );
4398+ if (!is_offloaded )
4399+ cifs_reconnect (server );
43824400 return -1 ;
43834401 }
43844402
@@ -4402,7 +4420,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
44024420 cifs_dbg (FYI , "%s: server returned error %d\n" ,
44034421 __func__ , rdata -> result );
44044422 /* normal error on read response */
4405- dequeue_mid (mid , false);
4423+ if (is_offloaded )
4424+ mid -> mid_state = MID_RESPONSE_RECEIVED ;
4425+ else
4426+ dequeue_mid (mid , false);
44064427 return 0 ;
44074428 }
44084429
@@ -4426,7 +4447,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
44264447 cifs_dbg (FYI , "%s: data offset (%u) beyond end of smallbuf\n" ,
44274448 __func__ , data_offset );
44284449 rdata -> result = - EIO ;
4429- dequeue_mid (mid , rdata -> result );
4450+ if (is_offloaded )
4451+ mid -> mid_state = MID_RESPONSE_MALFORMED ;
4452+ else
4453+ dequeue_mid (mid , rdata -> result );
44304454 return 0 ;
44314455 }
44324456
@@ -4442,21 +4466,30 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
44424466 cifs_dbg (FYI , "%s: data offset (%u) beyond 1st page of response\n" ,
44434467 __func__ , data_offset );
44444468 rdata -> result = - EIO ;
4445- dequeue_mid (mid , rdata -> result );
4469+ if (is_offloaded )
4470+ mid -> mid_state = MID_RESPONSE_MALFORMED ;
4471+ else
4472+ dequeue_mid (mid , rdata -> result );
44464473 return 0 ;
44474474 }
44484475
44494476 if (data_len > page_data_size - pad_len ) {
44504477 /* data_len is corrupt -- discard frame */
44514478 rdata -> result = - EIO ;
4452- dequeue_mid (mid , rdata -> result );
4479+ if (is_offloaded )
4480+ mid -> mid_state = MID_RESPONSE_MALFORMED ;
4481+ else
4482+ dequeue_mid (mid , rdata -> result );
44534483 return 0 ;
44544484 }
44554485
44564486 rdata -> result = init_read_bvec (pages , npages , page_data_size ,
44574487 cur_off , & bvec );
44584488 if (rdata -> result != 0 ) {
4459- dequeue_mid (mid , rdata -> result );
4489+ if (is_offloaded )
4490+ mid -> mid_state = MID_RESPONSE_MALFORMED ;
4491+ else
4492+ dequeue_mid (mid , rdata -> result );
44604493 return 0 ;
44614494 }
44624495
@@ -4471,7 +4504,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
44714504 /* read response payload cannot be in both buf and pages */
44724505 WARN_ONCE (1 , "buf can not contain only a part of read data" );
44734506 rdata -> result = - EIO ;
4474- dequeue_mid (mid , rdata -> result );
4507+ if (is_offloaded )
4508+ mid -> mid_state = MID_RESPONSE_MALFORMED ;
4509+ else
4510+ dequeue_mid (mid , rdata -> result );
44754511 return 0 ;
44764512 }
44774513
@@ -4482,7 +4518,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
44824518 if (length < 0 )
44834519 return length ;
44844520
4485- dequeue_mid (mid , false);
4521+ if (is_offloaded )
4522+ mid -> mid_state = MID_RESPONSE_RECEIVED ;
4523+ else
4524+ dequeue_mid (mid , false);
44864525 return length ;
44874526}
44884527
@@ -4511,15 +4550,34 @@ static void smb2_decrypt_offload(struct work_struct *work)
45114550 }
45124551
45134552 dw -> server -> lstrp = jiffies ;
4514- mid = smb2_find_mid (dw -> server , dw -> buf );
4553+ mid = smb2_find_dequeue_mid (dw -> server , dw -> buf );
45154554 if (mid == NULL )
45164555 cifs_dbg (FYI , "mid not found\n" );
45174556 else {
45184557 mid -> decrypted = true;
45194558 rc = handle_read_data (dw -> server , mid , dw -> buf ,
45204559 dw -> server -> vals -> read_rsp_size ,
4521- dw -> ppages , dw -> npages , dw -> len );
4522- mid -> callback (mid );
4560+ dw -> ppages , dw -> npages , dw -> len ,
4561+ true);
4562+ if (rc >= 0 ) {
4563+ #ifdef CONFIG_CIFS_STATS2
4564+ mid -> when_received = jiffies ;
4565+ #endif
4566+ mid -> callback (mid );
4567+ } else {
4568+ spin_lock (& GlobalMid_Lock );
4569+ if (dw -> server -> tcpStatus == CifsNeedReconnect ) {
4570+ mid -> mid_state = MID_RETRY_NEEDED ;
4571+ spin_unlock (& GlobalMid_Lock );
4572+ mid -> callback (mid );
4573+ } else {
4574+ mid -> mid_state = MID_REQUEST_SUBMITTED ;
4575+ mid -> mid_flags &= ~(MID_DELETED );
4576+ list_add_tail (& mid -> qhead ,
4577+ & dw -> server -> pending_mid_q );
4578+ spin_unlock (& GlobalMid_Lock );
4579+ }
4580+ }
45234581 cifs_mid_q_entry_release (mid );
45244582 }
45254583
@@ -4622,7 +4680,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
46224680 (* mid )-> decrypted = true;
46234681 rc = handle_read_data (server , * mid , buf ,
46244682 server -> vals -> read_rsp_size ,
4625- pages , npages , len );
4683+ pages , npages , len , false );
46264684 }
46274685
46284686free_pages :
@@ -4765,7 +4823,7 @@ smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid)
47654823 char * buf = server -> large_buf ? server -> bigbuf : server -> smallbuf ;
47664824
47674825 return handle_read_data (server , mid , buf , server -> pdu_size ,
4768- NULL , 0 , 0 );
4826+ NULL , 0 , 0 , false );
47694827}
47704828
47714829static int
0 commit comments