@@ -163,13 +163,41 @@ static struct oplock_info *opinfo_get_list(struct ksmbd_inode *ci)
163
163
rcu_read_lock ();
164
164
opinfo = list_first_or_null_rcu (& ci -> m_op_list , struct oplock_info ,
165
165
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
+ opinfo = NULL ;
174
+ }
175
+ }
176
+ }
177
+
168
178
rcu_read_unlock ();
169
179
170
180
return opinfo ;
171
181
}
172
182
183
+ static void opinfo_conn_put (struct oplock_info * opinfo )
184
+ {
185
+ struct ksmbd_conn * conn ;
186
+
187
+ if (!opinfo )
188
+ return ;
189
+
190
+ conn = opinfo -> conn ;
191
+ /*
192
+ * Checking waitqueue to dropping pending requests on
193
+ * disconnection. waitqueue_active is safe because it
194
+ * uses atomic operation for condition.
195
+ */
196
+ if (!atomic_dec_return (& conn -> r_count ) && waitqueue_active (& conn -> r_count_q ))
197
+ wake_up (& conn -> r_count_q );
198
+ opinfo_put (opinfo );
199
+ }
200
+
173
201
void opinfo_put (struct oplock_info * opinfo )
174
202
{
175
203
if (!atomic_dec_and_test (& opinfo -> refcount ))
@@ -763,13 +791,6 @@ static void __smb1_oplock_break_noti(struct work_struct *wk)
763
791
764
792
ksmbd_conn_write (work );
765
793
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 );
773
794
}
774
795
775
796
/**
@@ -791,7 +812,6 @@ static int smb1_oplock_break_noti(struct oplock_info *opinfo)
791
812
work -> request_buf = (char * )opinfo ;
792
813
work -> conn = conn ;
793
814
794
- atomic_inc (& conn -> r_count );
795
815
if (opinfo -> op_state == OPLOCK_ACK_WAIT ) {
796
816
INIT_WORK (& work -> work , __smb1_oplock_break_noti );
797
817
ksmbd_queue_work (work );
@@ -876,13 +896,6 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
876
896
877
897
out :
878
898
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 );
886
899
}
887
900
888
901
/**
@@ -916,7 +929,6 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
916
929
work -> conn = conn ;
917
930
work -> sess = opinfo -> sess ;
918
931
919
- atomic_inc (& conn -> r_count );
920
932
if (opinfo -> op_state == OPLOCK_ACK_WAIT ) {
921
933
INIT_WORK (& work -> work , __smb2_oplock_break_noti );
922
934
ksmbd_queue_work (work );
@@ -986,13 +998,6 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
986
998
987
999
out :
988
1000
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 );
996
1001
}
997
1002
998
1003
/**
@@ -1032,7 +1037,6 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
1032
1037
work -> conn = conn ;
1033
1038
work -> sess = opinfo -> sess ;
1034
1039
1035
- atomic_inc (& conn -> r_count );
1036
1040
if (opinfo -> op_state == OPLOCK_ACK_WAIT ) {
1037
1041
list_for_each_safe (tmp , t , & opinfo -> interim_list ) {
1038
1042
struct ksmbd_work * in_work ;
@@ -1368,28 +1372,30 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
1368
1372
}
1369
1373
prev_opinfo = opinfo_get_list (ci );
1370
1374
if (!prev_opinfo ||
1371
- (prev_opinfo -> level == SMB2_OPLOCK_LEVEL_NONE && lctx ))
1375
+ (prev_opinfo -> level == SMB2_OPLOCK_LEVEL_NONE && lctx )) {
1376
+ opinfo_conn_put (prev_opinfo );
1372
1377
goto set_lev ;
1378
+ }
1373
1379
prev_op_has_lease = prev_opinfo -> is_lease ;
1374
1380
if (prev_op_has_lease )
1375
1381
prev_op_state = prev_opinfo -> o_lease -> state ;
1376
1382
1377
1383
if (share_ret < 0 &&
1378
1384
prev_opinfo -> level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ) {
1379
1385
err = share_ret ;
1380
- opinfo_put (prev_opinfo );
1386
+ opinfo_conn_put (prev_opinfo );
1381
1387
goto err_out ;
1382
1388
}
1383
1389
1384
1390
if (prev_opinfo -> level != SMB2_OPLOCK_LEVEL_BATCH &&
1385
1391
prev_opinfo -> level != SMB2_OPLOCK_LEVEL_EXCLUSIVE ) {
1386
- opinfo_put (prev_opinfo );
1392
+ opinfo_conn_put (prev_opinfo );
1387
1393
goto op_break_not_needed ;
1388
1394
}
1389
1395
1390
1396
list_add (& work -> interim_entry , & prev_opinfo -> interim_list );
1391
1397
err = oplock_break (prev_opinfo , SMB2_OPLOCK_LEVEL_II );
1392
- opinfo_put (prev_opinfo );
1398
+ opinfo_conn_put (prev_opinfo );
1393
1399
if (err == - ENOENT )
1394
1400
goto set_lev ;
1395
1401
/* Check all oplock was freed by close */
@@ -1452,14 +1458,14 @@ static void smb_break_all_write_oplock(struct ksmbd_work *work,
1452
1458
return ;
1453
1459
if (brk_opinfo -> level != SMB2_OPLOCK_LEVEL_BATCH &&
1454
1460
brk_opinfo -> level != SMB2_OPLOCK_LEVEL_EXCLUSIVE ) {
1455
- opinfo_put (brk_opinfo );
1461
+ opinfo_conn_put (brk_opinfo );
1456
1462
return ;
1457
1463
}
1458
1464
1459
1465
brk_opinfo -> open_trunc = is_trunc ;
1460
1466
list_add (& work -> interim_entry , & brk_opinfo -> interim_list );
1461
1467
oplock_break (brk_opinfo , SMB2_OPLOCK_LEVEL_II );
1462
- opinfo_put (brk_opinfo );
1468
+ opinfo_conn_put (brk_opinfo );
1463
1469
}
1464
1470
1465
1471
/**
@@ -1487,6 +1493,13 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
1487
1493
list_for_each_entry_rcu (brk_op , & ci -> m_op_list , op_entry ) {
1488
1494
if (!atomic_inc_not_zero (& brk_op -> refcount ))
1489
1495
continue ;
1496
+
1497
+ atomic_inc (& brk_op -> conn -> r_count );
1498
+ if (ksmbd_conn_releasing (brk_op -> conn )) {
1499
+ atomic_dec (& brk_op -> conn -> r_count );
1500
+ continue ;
1501
+ }
1502
+
1490
1503
rcu_read_unlock ();
1491
1504
1492
1505
#ifdef CONFIG_SMB_INSECURE_SERVER
@@ -1547,7 +1560,7 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
1547
1560
brk_op -> open_trunc = is_trunc ;
1548
1561
oplock_break (brk_op , SMB2_OPLOCK_LEVEL_NONE );
1549
1562
next :
1550
- opinfo_put (brk_op );
1563
+ opinfo_conn_put (brk_op );
1551
1564
rcu_read_lock ();
1552
1565
}
1553
1566
rcu_read_unlock ();
0 commit comments