@@ -264,7 +264,7 @@ smb2_revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)
264
264
}
265
265
266
266
static 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 )
268
268
{
269
269
struct mid_q_entry * mid ;
270
270
struct smb2_sync_hdr * shdr = (struct smb2_sync_hdr * )buf ;
@@ -281,6 +281,10 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf)
281
281
(mid -> mid_state == MID_REQUEST_SUBMITTED ) &&
282
282
(mid -> command == shdr -> Command )) {
283
283
kref_get (& mid -> refcount );
284
+ if (dequeue ) {
285
+ list_del_init (& mid -> qhead );
286
+ mid -> mid_flags |= MID_DELETED ;
287
+ }
284
288
spin_unlock (& GlobalMid_Lock );
285
289
return mid ;
286
290
}
@@ -289,6 +293,18 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf)
289
293
return NULL ;
290
294
}
291
295
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
+
292
308
static void
293
309
smb2_dump_detail (void * buf , struct TCP_Server_Info * server )
294
310
{
@@ -4356,7 +4372,8 @@ init_read_bvec(struct page **pages, unsigned int npages, unsigned int data_size,
4356
4372
static int
4357
4373
handle_read_data (struct TCP_Server_Info * server , struct mid_q_entry * mid ,
4358
4374
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 )
4360
4377
{
4361
4378
unsigned int data_offset ;
4362
4379
unsigned int data_len ;
@@ -4378,7 +4395,8 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
4378
4395
4379
4396
if (server -> ops -> is_session_expired &&
4380
4397
server -> ops -> is_session_expired (buf )) {
4381
- cifs_reconnect (server );
4398
+ if (!is_offloaded )
4399
+ cifs_reconnect (server );
4382
4400
return -1 ;
4383
4401
}
4384
4402
@@ -4402,7 +4420,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
4402
4420
cifs_dbg (FYI , "%s: server returned error %d\n" ,
4403
4421
__func__ , rdata -> result );
4404
4422
/* 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);
4406
4427
return 0 ;
4407
4428
}
4408
4429
@@ -4426,7 +4447,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
4426
4447
cifs_dbg (FYI , "%s: data offset (%u) beyond end of smallbuf\n" ,
4427
4448
__func__ , data_offset );
4428
4449
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 );
4430
4454
return 0 ;
4431
4455
}
4432
4456
@@ -4442,21 +4466,30 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
4442
4466
cifs_dbg (FYI , "%s: data offset (%u) beyond 1st page of response\n" ,
4443
4467
__func__ , data_offset );
4444
4468
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 );
4446
4473
return 0 ;
4447
4474
}
4448
4475
4449
4476
if (data_len > page_data_size - pad_len ) {
4450
4477
/* data_len is corrupt -- discard frame */
4451
4478
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 );
4453
4483
return 0 ;
4454
4484
}
4455
4485
4456
4486
rdata -> result = init_read_bvec (pages , npages , page_data_size ,
4457
4487
cur_off , & bvec );
4458
4488
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 );
4460
4493
return 0 ;
4461
4494
}
4462
4495
@@ -4471,7 +4504,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
4471
4504
/* read response payload cannot be in both buf and pages */
4472
4505
WARN_ONCE (1 , "buf can not contain only a part of read data" );
4473
4506
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 );
4475
4511
return 0 ;
4476
4512
}
4477
4513
@@ -4482,7 +4518,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
4482
4518
if (length < 0 )
4483
4519
return length ;
4484
4520
4485
- dequeue_mid (mid , false);
4521
+ if (is_offloaded )
4522
+ mid -> mid_state = MID_RESPONSE_RECEIVED ;
4523
+ else
4524
+ dequeue_mid (mid , false);
4486
4525
return length ;
4487
4526
}
4488
4527
@@ -4511,15 +4550,34 @@ static void smb2_decrypt_offload(struct work_struct *work)
4511
4550
}
4512
4551
4513
4552
dw -> server -> lstrp = jiffies ;
4514
- mid = smb2_find_mid (dw -> server , dw -> buf );
4553
+ mid = smb2_find_dequeue_mid (dw -> server , dw -> buf );
4515
4554
if (mid == NULL )
4516
4555
cifs_dbg (FYI , "mid not found\n" );
4517
4556
else {
4518
4557
mid -> decrypted = true;
4519
4558
rc = handle_read_data (dw -> server , mid , dw -> buf ,
4520
4559
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
+ }
4523
4581
cifs_mid_q_entry_release (mid );
4524
4582
}
4525
4583
@@ -4622,7 +4680,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
4622
4680
(* mid )-> decrypted = true;
4623
4681
rc = handle_read_data (server , * mid , buf ,
4624
4682
server -> vals -> read_rsp_size ,
4625
- pages , npages , len );
4683
+ pages , npages , len , false );
4626
4684
}
4627
4685
4628
4686
free_pages :
@@ -4765,7 +4823,7 @@ smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid)
4765
4823
char * buf = server -> large_buf ? server -> bigbuf : server -> smallbuf ;
4766
4824
4767
4825
return handle_read_data (server , mid , buf , server -> pdu_size ,
4768
- NULL , 0 , 0 );
4826
+ NULL , 0 , 0 , false );
4769
4827
}
4770
4828
4771
4829
static int
0 commit comments