@@ -420,6 +420,9 @@ static void del_scan(struct dlm_ls *ls, struct dlm_rsb *r)
420420{
421421 struct dlm_rsb * first ;
422422
423+ /* active rsbs should never be on the scan list */
424+ WARN_ON (!rsb_flag (r , RSB_INACTIVE ));
425+
423426 spin_lock_bh (& ls -> ls_scan_lock );
424427 r -> res_toss_time = 0 ;
425428
@@ -457,17 +460,16 @@ static void add_scan(struct dlm_ls *ls, struct dlm_rsb *r)
457460 int our_nodeid = dlm_our_nodeid ();
458461 struct dlm_rsb * first ;
459462
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 ));
471473
472474 spin_lock_bh (& ls -> ls_scan_lock );
473475 /* 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)
479481 list_add_tail (& r -> res_scan_list , & ls -> ls_scan_list );
480482 enable_scan_timer (ls , r -> res_toss_time );
481483 } 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-
488484 /* try to get the maybe new first element and then add
489485 * to this rsb with the oldest expire time to the end
490486 * 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,
807803 r -> res_first_lkid = 0 ;
808804 }
809805
806+ /* A dir record will not be on the scan list. */
807+ if (r -> res_dir_nodeid != our_nodeid )
808+ del_scan (ls , r );
810809 list_move (& r -> res_slow_list , & ls -> ls_slow_active );
811810 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 */
814812 write_unlock_bh (& ls -> ls_rsbtbl_lock );
815813
816814 goto out ;
@@ -1272,7 +1270,10 @@ int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *name,
12721270 __dlm_master_lookup (ls , r , our_nodeid , from_nodeid , true, flags ,
12731271 r_nodeid , result );
12741272
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+
12761277 write_unlock_bh (& ls -> ls_rsbtbl_lock );
12771278
12781279 return 0 ;
@@ -1305,7 +1306,6 @@ int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *name,
13051306 }
13061307
13071308 list_add (& r -> res_slow_list , & ls -> ls_slow_inactive );
1308- add_scan (ls , r );
13091309 write_unlock_bh (& ls -> ls_rsbtbl_lock );
13101310
13111311 if (result )
@@ -1346,11 +1346,24 @@ static void deactivate_rsb(struct kref *kref)
13461346{
13471347 struct dlm_rsb * r = container_of (kref , struct dlm_rsb , res_ref );
13481348 struct dlm_ls * ls = r -> res_ls ;
1349+ int our_nodeid = dlm_our_nodeid ();
13491350
13501351 DLM_ASSERT (list_empty (& r -> res_root_list ), dlm_print_rsb (r ););
13511352 rsb_set_flag (r , RSB_INACTIVE );
13521353 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 );
13541367
13551368 if (r -> res_lvbptr ) {
13561369 dlm_free_lvb (r -> res_lvbptr );
0 commit comments