@@ -420,6 +420,9 @@ static void del_scan(struct dlm_ls *ls, struct dlm_rsb *r)
420
420
{
421
421
struct dlm_rsb * first ;
422
422
423
+ /* active rsbs should never be on the scan list */
424
+ WARN_ON (!rsb_flag (r , RSB_INACTIVE ));
425
+
423
426
spin_lock_bh (& ls -> ls_scan_lock );
424
427
r -> res_toss_time = 0 ;
425
428
@@ -457,17 +460,16 @@ static void add_scan(struct dlm_ls *ls, struct dlm_rsb *r)
457
460
int our_nodeid = dlm_our_nodeid ();
458
461
struct dlm_rsb * first ;
459
462
460
- /* If we're the directory record for this rsb, and
461
- * we're not the master of it, then we need to wait
462
- * for the master node to send us a dir remove for
463
- * before removing the dir record.
464
- */
465
- if (!dlm_no_directory (ls ) &&
466
- (r -> res_master_nodeid != our_nodeid ) &&
467
- (dlm_dir_nodeid (r ) == our_nodeid )) {
468
- del_scan (ls , r );
469
- return ;
470
- }
463
+ /* A dir record for a remote master rsb should never be on the scan list. */
464
+ WARN_ON (!dlm_no_directory (ls ) &&
465
+ (r -> res_master_nodeid != our_nodeid ) &&
466
+ (dlm_dir_nodeid (r ) == our_nodeid ));
467
+
468
+ /* An active rsb should never be on the scan list. */
469
+ WARN_ON (!rsb_flag (r , RSB_INACTIVE ));
470
+
471
+ /* An rsb should not already be on the scan list. */
472
+ WARN_ON (!list_empty (& r -> res_scan_list ));
471
473
472
474
spin_lock_bh (& ls -> ls_scan_lock );
473
475
/* set the new rsb absolute expire time in the rsb */
@@ -479,12 +481,6 @@ static void add_scan(struct dlm_ls *ls, struct dlm_rsb *r)
479
481
list_add_tail (& r -> res_scan_list , & ls -> ls_scan_list );
480
482
enable_scan_timer (ls , r -> res_toss_time );
481
483
} else {
482
- /* check if the rsb was already queued, if so delete
483
- * it from the toss queue
484
- */
485
- if (!list_empty (& r -> res_scan_list ))
486
- list_del (& r -> res_scan_list );
487
-
488
484
/* try to get the maybe new first element and then add
489
485
* to this rsb with the oldest expire time to the end
490
486
* of the queue. If the list was empty before this
@@ -807,10 +803,12 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
807
803
r -> res_first_lkid = 0 ;
808
804
}
809
805
806
+ /* A dir record will not be on the scan list. */
807
+ if (r -> res_dir_nodeid != our_nodeid )
808
+ del_scan (ls , r );
810
809
list_move (& r -> res_slow_list , & ls -> ls_slow_active );
811
810
rsb_clear_flag (r , RSB_INACTIVE );
812
- kref_init (& r -> res_ref );
813
- del_scan (ls , r );
811
+ kref_init (& r -> res_ref ); /* ref is now used in active state */
814
812
write_unlock_bh (& ls -> ls_rsbtbl_lock );
815
813
816
814
goto out ;
@@ -1272,7 +1270,10 @@ int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *name,
1272
1270
__dlm_master_lookup (ls , r , our_nodeid , from_nodeid , true, flags ,
1273
1271
r_nodeid , result );
1274
1272
1275
- add_scan (ls , r );
1273
+ /* A dir record rsb should never be on scan list. */
1274
+ /* Try to fix this with del_scan? */
1275
+ WARN_ON (!list_empty (& r -> res_scan_list ));
1276
+
1276
1277
write_unlock_bh (& ls -> ls_rsbtbl_lock );
1277
1278
1278
1279
return 0 ;
@@ -1305,7 +1306,6 @@ int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *name,
1305
1306
}
1306
1307
1307
1308
list_add (& r -> res_slow_list , & ls -> ls_slow_inactive );
1308
- add_scan (ls , r );
1309
1309
write_unlock_bh (& ls -> ls_rsbtbl_lock );
1310
1310
1311
1311
if (result )
@@ -1346,11 +1346,24 @@ static void deactivate_rsb(struct kref *kref)
1346
1346
{
1347
1347
struct dlm_rsb * r = container_of (kref , struct dlm_rsb , res_ref );
1348
1348
struct dlm_ls * ls = r -> res_ls ;
1349
+ int our_nodeid = dlm_our_nodeid ();
1349
1350
1350
1351
DLM_ASSERT (list_empty (& r -> res_root_list ), dlm_print_rsb (r ););
1351
1352
rsb_set_flag (r , RSB_INACTIVE );
1352
1353
list_move (& r -> res_slow_list , & ls -> ls_slow_inactive );
1353
- add_scan (ls , r );
1354
+
1355
+ /*
1356
+ * When the rsb becomes unused:
1357
+ * - If it's not a dir record for a remote master rsb,
1358
+ * then it is put on the scan list to be freed.
1359
+ * - If it's a dir record for a remote master rsb,
1360
+ * then it is kept in the inactive state until
1361
+ * receive_remove() from the master node.
1362
+ */
1363
+ if (!dlm_no_directory (ls ) &&
1364
+ (r -> res_master_nodeid != our_nodeid ) &&
1365
+ (dlm_dir_nodeid (r ) != our_nodeid ))
1366
+ add_scan (ls , r );
1354
1367
1355
1368
if (r -> res_lvbptr ) {
1356
1369
dlm_free_lvb (r -> res_lvbptr );
0 commit comments