@@ -207,9 +207,9 @@ static void opinfo_add(struct oplock_info *opinfo)
207207{
208208 struct ksmbd_inode * ci = opinfo -> o_fp -> f_ci ;
209209
210- write_lock (& ci -> m_lock );
210+ down_write (& ci -> m_lock );
211211 list_add_rcu (& opinfo -> op_entry , & ci -> m_op_list );
212- write_unlock (& ci -> m_lock );
212+ up_write (& ci -> m_lock );
213213}
214214
215215static void opinfo_del (struct oplock_info * opinfo )
@@ -221,9 +221,9 @@ static void opinfo_del(struct oplock_info *opinfo)
221221 lease_del_list (opinfo );
222222 write_unlock (& lease_list_lock );
223223 }
224- write_lock (& ci -> m_lock );
224+ down_write (& ci -> m_lock );
225225 list_del_rcu (& opinfo -> op_entry );
226- write_unlock (& ci -> m_lock );
226+ up_write (& ci -> m_lock );
227227}
228228
229229static unsigned long opinfo_count (struct ksmbd_file * fp )
@@ -526,21 +526,18 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
526526 * Compare lease key and client_guid to know request from same owner
527527 * of same client
528528 */
529- read_lock (& ci -> m_lock );
529+ down_read (& ci -> m_lock );
530530 list_for_each_entry (opinfo , & ci -> m_op_list , op_entry ) {
531531 if (!opinfo -> is_lease || !opinfo -> conn )
532532 continue ;
533- read_unlock (& ci -> m_lock );
534533 lease = opinfo -> o_lease ;
535534
536535 ret = compare_guid_key (opinfo , client_guid , lctx -> lease_key );
537536 if (ret ) {
538537 m_opinfo = opinfo ;
539538 /* skip upgrading lease about breaking lease */
540- if (atomic_read (& opinfo -> breaking_cnt )) {
541- read_lock (& ci -> m_lock );
539+ if (atomic_read (& opinfo -> breaking_cnt ))
542540 continue ;
543- }
544541
545542 /* upgrading lease */
546543 if ((atomic_read (& ci -> op_count ) +
@@ -570,9 +567,8 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
570567 lease_none_upgrade (opinfo , lctx -> req_state );
571568 }
572569 }
573- read_lock (& ci -> m_lock );
574570 }
575- read_unlock (& ci -> m_lock );
571+ up_read (& ci -> m_lock );
576572
577573 return m_opinfo ;
578574}
@@ -613,13 +609,23 @@ static int oplock_break_pending(struct oplock_info *opinfo, int req_op_level)
613609
614610 if (opinfo -> op_state == OPLOCK_CLOSING )
615611 return - ENOENT ;
616- else if (!opinfo -> is_lease && opinfo -> level <= req_op_level )
617- return 1 ;
612+ else if (opinfo -> level <= req_op_level ) {
613+ if (opinfo -> is_lease &&
614+ opinfo -> o_lease -> state !=
615+ (SMB2_LEASE_HANDLE_CACHING_LE |
616+ SMB2_LEASE_READ_CACHING_LE ))
617+ return 1 ;
618+ }
618619 }
619620
620- if (!opinfo -> is_lease && opinfo -> level <= req_op_level ) {
621- wake_up_oplock_break (opinfo );
622- return 1 ;
621+ if (opinfo -> level <= req_op_level ) {
622+ if (opinfo -> is_lease &&
623+ opinfo -> o_lease -> state !=
624+ (SMB2_LEASE_HANDLE_CACHING_LE |
625+ SMB2_LEASE_READ_CACHING_LE )) {
626+ wake_up_oplock_break (opinfo );
627+ return 1 ;
628+ }
623629 }
624630 return 0 ;
625631}
@@ -887,7 +893,6 @@ static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level)
887893 struct lease * lease = brk_opinfo -> o_lease ;
888894
889895 atomic_inc (& brk_opinfo -> breaking_cnt );
890-
891896 err = oplock_break_pending (brk_opinfo , req_op_level );
892897 if (err )
893898 return err < 0 ? err : 0 ;
@@ -1105,7 +1110,7 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
11051110 if (!p_ci )
11061111 return ;
11071112
1108- read_lock (& p_ci -> m_lock );
1113+ down_read (& p_ci -> m_lock );
11091114 list_for_each_entry (opinfo , & p_ci -> m_op_list , op_entry ) {
11101115 if (opinfo -> conn == NULL || !opinfo -> is_lease )
11111116 continue ;
@@ -1123,13 +1128,11 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
11231128 continue ;
11241129 }
11251130
1126- read_unlock (& p_ci -> m_lock );
11271131 oplock_break (opinfo , SMB2_OPLOCK_LEVEL_NONE );
11281132 opinfo_conn_put (opinfo );
1129- read_lock (& p_ci -> m_lock );
11301133 }
11311134 }
1132- read_unlock (& p_ci -> m_lock );
1135+ up_read (& p_ci -> m_lock );
11331136
11341137 ksmbd_inode_put (p_ci );
11351138}
@@ -1150,7 +1153,7 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
11501153 if (!p_ci )
11511154 return ;
11521155
1153- read_lock (& p_ci -> m_lock );
1156+ down_read (& p_ci -> m_lock );
11541157 list_for_each_entry (opinfo , & p_ci -> m_op_list , op_entry ) {
11551158 if (opinfo -> conn == NULL || !opinfo -> is_lease )
11561159 continue ;
@@ -1164,13 +1167,11 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
11641167 atomic_dec (& opinfo -> conn -> r_count );
11651168 continue ;
11661169 }
1167- read_unlock (& p_ci -> m_lock );
11681170 oplock_break (opinfo , SMB2_OPLOCK_LEVEL_NONE );
11691171 opinfo_conn_put (opinfo );
1170- read_lock (& p_ci -> m_lock );
11711172 }
11721173 }
1173- read_unlock (& p_ci -> m_lock );
1174+ up_read (& p_ci -> m_lock );
11741175
11751176 ksmbd_inode_put (p_ci );
11761177}
@@ -1200,7 +1201,9 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
12001201
12011202 /* Only v2 leases handle the directory */
12021203 if (S_ISDIR (file_inode (fp -> filp )-> i_mode )) {
1203- if (!lctx || lctx -> version != 2 )
1204+ if (!lctx || lctx -> version != 2 ||
1205+ (lctx -> flags != SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE &&
1206+ !lctx -> epoch ))
12041207 return 0 ;
12051208 }
12061209
@@ -1465,8 +1468,9 @@ void create_lease_buf(u8 *rbuf, struct lease *lease)
14651468 buf -> lcontext .LeaseFlags = lease -> flags ;
14661469 buf -> lcontext .Epoch = cpu_to_le16 (lease -> epoch );
14671470 buf -> lcontext .LeaseState = lease -> state ;
1468- memcpy (buf -> lcontext .ParentLeaseKey , lease -> parent_lease_key ,
1469- SMB2_LEASE_KEY_SIZE );
1471+ if (lease -> flags == SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE )
1472+ memcpy (buf -> lcontext .ParentLeaseKey , lease -> parent_lease_key ,
1473+ SMB2_LEASE_KEY_SIZE );
14701474 buf -> ccontext .DataOffset = cpu_to_le16 (offsetof
14711475 (struct create_lease_v2 , lcontext ));
14721476 buf -> ccontext .DataLength = cpu_to_le32 (sizeof (struct lease_context_v2 ));
@@ -1525,8 +1529,9 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
15251529 lreq -> flags = lc -> lcontext .LeaseFlags ;
15261530 lreq -> epoch = lc -> lcontext .Epoch ;
15271531 lreq -> duration = lc -> lcontext .LeaseDuration ;
1528- memcpy (lreq -> parent_lease_key , lc -> lcontext .ParentLeaseKey ,
1529- SMB2_LEASE_KEY_SIZE );
1532+ if (lreq -> flags == SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE )
1533+ memcpy (lreq -> parent_lease_key , lc -> lcontext .ParentLeaseKey ,
1534+ SMB2_LEASE_KEY_SIZE );
15301535 lreq -> version = 2 ;
15311536 } else {
15321537 struct create_lease * lc = (struct create_lease * )cc ;
0 commit comments