Skip to content

Commit 1341295

Browse files
Alexander Aringteigland
authored andcommitted
dlm: fix removal of rsb struct that is master and dir record
An rsb struct was not being removed in the case where it was both the master and the dir record. This case (master and dir node) was missed in the condition for doing add_scan() from deactivate_rsb(). Fixing this triggers a related WARN_ON that needs to be fixed, and requires adjusting where two del_scan() calls are made. Fixes: c217adf ("dlm: fix add_scan and del_scan usage") Signed-off-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
1 parent 78d4f34 commit 1341295

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

fs/dlm/lock.c

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -824,9 +824,12 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
824824
r->res_first_lkid = 0;
825825
}
826826

827-
/* A dir record will not be on the scan list. */
828-
if (r->res_dir_nodeid != our_nodeid)
829-
del_scan(ls, r);
827+
/* we always deactivate scan timer for the rsb, when
828+
* we move it out of the inactive state as rsb state
829+
* can be changed and scan timers are only for inactive
830+
* rsbs.
831+
*/
832+
del_scan(ls, r);
830833
list_move(&r->res_slow_list, &ls->ls_slow_active);
831834
rsb_clear_flag(r, RSB_INACTIVE);
832835
kref_init(&r->res_ref); /* ref is now used in active state */
@@ -989,10 +992,10 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
989992
r->res_nodeid = 0;
990993
}
991994

995+
del_scan(ls, r);
992996
list_move(&r->res_slow_list, &ls->ls_slow_active);
993997
rsb_clear_flag(r, RSB_INACTIVE);
994998
kref_init(&r->res_ref);
995-
del_scan(ls, r);
996999
write_unlock_bh(&ls->ls_rsbtbl_lock);
9971000

9981001
goto out;
@@ -1337,9 +1340,13 @@ static int _dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *na
13371340
__dlm_master_lookup(ls, r, our_nodeid, from_nodeid, true, flags,
13381341
r_nodeid, result);
13391342

1340-
/* A dir record rsb should never be on scan list. */
1341-
/* Try to fix this with del_scan? */
1342-
WARN_ON(!list_empty(&r->res_scan_list));
1343+
/* A dir record rsb should never be on scan list.
1344+
* Except when we are the dir and master node.
1345+
* This function should only be called by the dir
1346+
* node.
1347+
*/
1348+
WARN_ON(!list_empty(&r->res_scan_list) &&
1349+
r->res_master_nodeid != our_nodeid);
13431350

13441351
write_unlock_bh(&ls->ls_rsbtbl_lock);
13451352

@@ -1430,16 +1437,23 @@ static void deactivate_rsb(struct kref *kref)
14301437
list_move(&r->res_slow_list, &ls->ls_slow_inactive);
14311438

14321439
/*
1433-
* When the rsb becomes unused:
1434-
* - If it's not a dir record for a remote master rsb,
1435-
* then it is put on the scan list to be freed.
1436-
* - If it's a dir record for a remote master rsb,
1437-
* then it is kept in the inactive state until
1438-
* receive_remove() from the master node.
1440+
* When the rsb becomes unused, there are two possibilities:
1441+
* 1. Leave the inactive rsb in place (don't remove it).
1442+
* 2. Add it to the scan list to be removed.
1443+
*
1444+
* 1 is done when the rsb is acting as the dir record
1445+
* for a remotely mastered rsb. The rsb must be left
1446+
* in place as an inactive rsb to act as the dir record.
1447+
*
1448+
* 2 is done when a) the rsb is not the master and not the
1449+
* dir record, b) when the rsb is both the master and the
1450+
* dir record, c) when the rsb is master but not dir record.
1451+
*
1452+
* (If no directory is used, the rsb can always be removed.)
14391453
*/
1440-
if (!dlm_no_directory(ls) &&
1441-
(r->res_master_nodeid != our_nodeid) &&
1442-
(dlm_dir_nodeid(r) != our_nodeid))
1454+
if (dlm_no_directory(ls) ||
1455+
(r->res_master_nodeid == our_nodeid ||
1456+
dlm_dir_nodeid(r) != our_nodeid))
14431457
add_scan(ls, r);
14441458

14451459
if (r->res_lvbptr) {

0 commit comments

Comments
 (0)