@@ -163,13 +163,42 @@ static struct oplock_info *opinfo_get_list(struct ksmbd_inode *ci)
163163 rcu_read_lock ();
164164 opinfo = list_first_or_null_rcu (& ci -> m_op_list , struct oplock_info ,
165165 op_entry );
166- if (opinfo && !atomic_inc_not_zero (& opinfo -> refcount ))
167- opinfo = NULL ;
166+ if (opinfo ) {
167+ if (!atomic_inc_not_zero (& opinfo -> refcount ))
168+ opinfo = NULL ;
169+ else {
170+ atomic_inc (& opinfo -> conn -> r_count );
171+ if (ksmbd_conn_releasing (opinfo -> conn )) {
172+ atomic_dec (& opinfo -> conn -> r_count );
173+ atomic_dec (& opinfo -> refcount );
174+ opinfo = NULL ;
175+ }
176+ }
177+ }
178+
168179 rcu_read_unlock ();
169180
170181 return opinfo ;
171182}
172183
184+ static void opinfo_conn_put (struct oplock_info * opinfo )
185+ {
186+ struct ksmbd_conn * conn ;
187+
188+ if (!opinfo )
189+ return ;
190+
191+ conn = opinfo -> conn ;
192+ /*
193+ * Checking waitqueue to dropping pending requests on
194+ * disconnection. waitqueue_active is safe because it
195+ * uses atomic operation for condition.
196+ */
197+ if (!atomic_dec_return (& conn -> r_count ) && waitqueue_active (& conn -> r_count_q ))
198+ wake_up (& conn -> r_count_q );
199+ opinfo_put (opinfo );
200+ }
201+
173202void opinfo_put (struct oplock_info * opinfo )
174203{
175204 if (!atomic_dec_and_test (& opinfo -> refcount ))
@@ -763,13 +792,6 @@ static void __smb1_oplock_break_noti(struct work_struct *wk)
763792
764793 ksmbd_conn_write (work );
765794 ksmbd_free_work_struct (work );
766- /*
767- * Checking waitqueue to dropping pending requests on
768- * disconnection. waitqueue_active is safe because it
769- * uses atomic operation for condition.
770- */
771- if (!atomic_dec_return (& conn -> r_count ) && waitqueue_active (& conn -> r_count_q ))
772- wake_up (& conn -> r_count_q );
773795}
774796
775797/**
@@ -791,7 +813,6 @@ static int smb1_oplock_break_noti(struct oplock_info *opinfo)
791813 work -> request_buf = (char * )opinfo ;
792814 work -> conn = conn ;
793815
794- atomic_inc (& conn -> r_count );
795816 if (opinfo -> op_state == OPLOCK_ACK_WAIT ) {
796817 INIT_WORK (& work -> work , __smb1_oplock_break_noti );
797818 ksmbd_queue_work (work );
@@ -876,13 +897,6 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
876897
877898out :
878899 ksmbd_free_work_struct (work );
879- /*
880- * Checking waitqueue to dropping pending requests on
881- * disconnection. waitqueue_active is safe because it
882- * uses atomic operation for condition.
883- */
884- if (!atomic_dec_return (& conn -> r_count ) && waitqueue_active (& conn -> r_count_q ))
885- wake_up (& conn -> r_count_q );
886900}
887901
888902/**
@@ -916,7 +930,6 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
916930 work -> conn = conn ;
917931 work -> sess = opinfo -> sess ;
918932
919- atomic_inc (& conn -> r_count );
920933 if (opinfo -> op_state == OPLOCK_ACK_WAIT ) {
921934 INIT_WORK (& work -> work , __smb2_oplock_break_noti );
922935 ksmbd_queue_work (work );
@@ -986,13 +999,6 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
986999
9871000out :
9881001 ksmbd_free_work_struct (work );
989- /*
990- * Checking waitqueue to dropping pending requests on
991- * disconnection. waitqueue_active is safe because it
992- * uses atomic operation for condition.
993- */
994- if (!atomic_dec_return (& conn -> r_count ) && waitqueue_active (& conn -> r_count_q ))
995- wake_up (& conn -> r_count_q );
9961002}
9971003
9981004/**
@@ -1032,7 +1038,6 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
10321038 work -> conn = conn ;
10331039 work -> sess = opinfo -> sess ;
10341040
1035- atomic_inc (& conn -> r_count );
10361041 if (opinfo -> op_state == OPLOCK_ACK_WAIT ) {
10371042 list_for_each_safe (tmp , t , & opinfo -> interim_list ) {
10381043 struct ksmbd_work * in_work ;
@@ -1368,28 +1373,30 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
13681373 }
13691374 prev_opinfo = opinfo_get_list (ci );
13701375 if (!prev_opinfo ||
1371- (prev_opinfo -> level == SMB2_OPLOCK_LEVEL_NONE && lctx ))
1376+ (prev_opinfo -> level == SMB2_OPLOCK_LEVEL_NONE && lctx )) {
1377+ opinfo_conn_put (prev_opinfo );
13721378 goto set_lev ;
1379+ }
13731380 prev_op_has_lease = prev_opinfo -> is_lease ;
13741381 if (prev_op_has_lease )
13751382 prev_op_state = prev_opinfo -> o_lease -> state ;
13761383
13771384 if (share_ret < 0 &&
13781385 prev_opinfo -> level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ) {
13791386 err = share_ret ;
1380- opinfo_put (prev_opinfo );
1387+ opinfo_conn_put (prev_opinfo );
13811388 goto err_out ;
13821389 }
13831390
13841391 if (prev_opinfo -> level != SMB2_OPLOCK_LEVEL_BATCH &&
13851392 prev_opinfo -> level != SMB2_OPLOCK_LEVEL_EXCLUSIVE ) {
1386- opinfo_put (prev_opinfo );
1393+ opinfo_conn_put (prev_opinfo );
13871394 goto op_break_not_needed ;
13881395 }
13891396
13901397 list_add (& work -> interim_entry , & prev_opinfo -> interim_list );
13911398 err = oplock_break (prev_opinfo , SMB2_OPLOCK_LEVEL_II );
1392- opinfo_put (prev_opinfo );
1399+ opinfo_conn_put (prev_opinfo );
13931400 if (err == - ENOENT )
13941401 goto set_lev ;
13951402 /* Check all oplock was freed by close */
@@ -1452,14 +1459,14 @@ static void smb_break_all_write_oplock(struct ksmbd_work *work,
14521459 return ;
14531460 if (brk_opinfo -> level != SMB2_OPLOCK_LEVEL_BATCH &&
14541461 brk_opinfo -> level != SMB2_OPLOCK_LEVEL_EXCLUSIVE ) {
1455- opinfo_put (brk_opinfo );
1462+ opinfo_conn_put (brk_opinfo );
14561463 return ;
14571464 }
14581465
14591466 brk_opinfo -> open_trunc = is_trunc ;
14601467 list_add (& work -> interim_entry , & brk_opinfo -> interim_list );
14611468 oplock_break (brk_opinfo , SMB2_OPLOCK_LEVEL_II );
1462- opinfo_put (brk_opinfo );
1469+ opinfo_conn_put (brk_opinfo );
14631470}
14641471
14651472/**
@@ -1487,6 +1494,13 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
14871494 list_for_each_entry_rcu (brk_op , & ci -> m_op_list , op_entry ) {
14881495 if (!atomic_inc_not_zero (& brk_op -> refcount ))
14891496 continue ;
1497+
1498+ atomic_inc (& brk_op -> conn -> r_count );
1499+ if (ksmbd_conn_releasing (brk_op -> conn )) {
1500+ atomic_dec (& brk_op -> conn -> r_count );
1501+ continue ;
1502+ }
1503+
14901504 rcu_read_unlock ();
14911505
14921506#ifdef CONFIG_SMB_INSECURE_SERVER
@@ -1547,7 +1561,7 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
15471561 brk_op -> open_trunc = is_trunc ;
15481562 oplock_break (brk_op , SMB2_OPLOCK_LEVEL_NONE );
15491563next :
1550- opinfo_put (brk_op );
1564+ opinfo_conn_put (brk_op );
15511565 rcu_read_lock ();
15521566 }
15531567 rcu_read_unlock ();
0 commit comments