@@ -508,15 +508,31 @@ cifs_ses_oplock_break(struct work_struct *work)
508
508
kfree (lw );
509
509
}
510
510
511
+ static void
512
+ smb2_queue_pending_open_break (struct tcon_link * tlink , __u8 * lease_key ,
513
+ __le32 new_lease_state )
514
+ {
515
+ struct smb2_lease_break_work * lw ;
516
+
517
+ lw = kmalloc (sizeof (struct smb2_lease_break_work ), GFP_KERNEL );
518
+ if (!lw ) {
519
+ cifs_put_tlink (tlink );
520
+ return ;
521
+ }
522
+
523
+ INIT_WORK (& lw -> lease_break , cifs_ses_oplock_break );
524
+ lw -> tlink = tlink ;
525
+ lw -> lease_state = new_lease_state ;
526
+ memcpy (lw -> lease_key , lease_key , SMB2_LEASE_KEY_SIZE );
527
+ queue_work (cifsiod_wq , & lw -> lease_break );
528
+ }
529
+
511
530
static bool
512
- smb2_tcon_has_lease (struct cifs_tcon * tcon , struct smb2_lease_break * rsp ,
513
- struct smb2_lease_break_work * lw )
531
+ smb2_tcon_has_lease (struct cifs_tcon * tcon , struct smb2_lease_break * rsp )
514
532
{
515
- bool found ;
516
533
__u8 lease_state ;
517
534
struct list_head * tmp ;
518
535
struct cifsFileInfo * cfile ;
519
- struct cifs_pending_open * open ;
520
536
struct cifsInodeInfo * cinode ;
521
537
int ack_req = le32_to_cpu (rsp -> Flags &
522
538
SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED );
@@ -546,22 +562,29 @@ smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp,
546
562
cfile -> oplock_level = lease_state ;
547
563
548
564
cifs_queue_oplock_break (cfile );
549
- kfree (lw );
550
565
return true;
551
566
}
552
567
553
- found = false;
568
+ return false;
569
+ }
570
+
571
+ static struct cifs_pending_open *
572
+ smb2_tcon_find_pending_open_lease (struct cifs_tcon * tcon ,
573
+ struct smb2_lease_break * rsp )
574
+ {
575
+ __u8 lease_state = le32_to_cpu (rsp -> NewLeaseState );
576
+ int ack_req = le32_to_cpu (rsp -> Flags &
577
+ SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED );
578
+ struct cifs_pending_open * open ;
579
+ struct cifs_pending_open * found = NULL ;
580
+
554
581
list_for_each_entry (open , & tcon -> pending_opens , olist ) {
555
582
if (memcmp (open -> lease_key , rsp -> LeaseKey ,
556
583
SMB2_LEASE_KEY_SIZE ))
557
584
continue ;
558
585
559
586
if (!found && ack_req ) {
560
- found = true;
561
- memcpy (lw -> lease_key , open -> lease_key ,
562
- SMB2_LEASE_KEY_SIZE );
563
- lw -> tlink = cifs_get_tlink (open -> tlink );
564
- queue_work (cifsiod_wq , & lw -> lease_break );
587
+ found = open ;
565
588
}
566
589
567
590
cifs_dbg (FYI , "found in the pending open list\n" );
@@ -582,14 +605,7 @@ smb2_is_valid_lease_break(char *buffer)
582
605
struct TCP_Server_Info * server ;
583
606
struct cifs_ses * ses ;
584
607
struct cifs_tcon * tcon ;
585
- struct smb2_lease_break_work * lw ;
586
-
587
- lw = kmalloc (sizeof (struct smb2_lease_break_work ), GFP_KERNEL );
588
- if (!lw )
589
- return false;
590
-
591
- INIT_WORK (& lw -> lease_break , cifs_ses_oplock_break );
592
- lw -> lease_state = rsp -> NewLeaseState ;
608
+ struct cifs_pending_open * open ;
593
609
594
610
cifs_dbg (FYI , "Checking for lease break\n" );
595
611
@@ -607,11 +623,27 @@ smb2_is_valid_lease_break(char *buffer)
607
623
spin_lock (& tcon -> open_file_lock );
608
624
cifs_stats_inc (
609
625
& tcon -> stats .cifs_stats .num_oplock_brks );
610
- if (smb2_tcon_has_lease (tcon , rsp , lw )) {
626
+ if (smb2_tcon_has_lease (tcon , rsp )) {
611
627
spin_unlock (& tcon -> open_file_lock );
612
628
spin_unlock (& cifs_tcp_ses_lock );
613
629
return true;
614
630
}
631
+ open = smb2_tcon_find_pending_open_lease (tcon ,
632
+ rsp );
633
+ if (open ) {
634
+ __u8 lease_key [SMB2_LEASE_KEY_SIZE ];
635
+ struct tcon_link * tlink ;
636
+
637
+ tlink = cifs_get_tlink (open -> tlink );
638
+ memcpy (lease_key , open -> lease_key ,
639
+ SMB2_LEASE_KEY_SIZE );
640
+ spin_unlock (& tcon -> open_file_lock );
641
+ spin_unlock (& cifs_tcp_ses_lock );
642
+ smb2_queue_pending_open_break (tlink ,
643
+ lease_key ,
644
+ rsp -> NewLeaseState );
645
+ return true;
646
+ }
615
647
spin_unlock (& tcon -> open_file_lock );
616
648
617
649
if (tcon -> crfid .is_valid &&
@@ -629,7 +661,6 @@ smb2_is_valid_lease_break(char *buffer)
629
661
}
630
662
}
631
663
spin_unlock (& cifs_tcp_ses_lock );
632
- kfree (lw );
633
664
cifs_dbg (FYI , "Can not process lease break - no lease matched\n" );
634
665
return false;
635
666
}
0 commit comments