@@ -325,6 +325,8 @@ static void queue_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rqmode)
325325
326326static inline void hold_rsb (struct dlm_rsb * r )
327327{
328+ /* rsbs in toss state never get referenced */
329+ WARN_ON (rsb_flag (r , RSB_TOSS ));
328330 kref_get (& r -> res_ref );
329331}
330332
@@ -631,6 +633,11 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
631633
632634 list_move (& r -> res_rsbs_list , & ls -> ls_keep );
633635 rsb_clear_flag (r , RSB_TOSS );
636+ /* rsb got out of toss state, it becomes alive again
637+ * and we reinit the reference counter that is only
638+ * valid for keep state rsbs
639+ */
640+ kref_init (& r -> res_ref );
634641 goto out_unlock ;
635642
636643
@@ -765,6 +772,11 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
765772
766773 list_move (& r -> res_rsbs_list , & ls -> ls_keep );
767774 rsb_clear_flag (r , RSB_TOSS );
775+ /* rsb got out of toss state, it becomes alive again
776+ * and we reinit the reference counter that is only
777+ * valid for keep state rsbs
778+ */
779+ kref_init (& r -> res_ref );
768780 goto out_unlock ;
769781
770782
@@ -1112,8 +1124,6 @@ static void toss_rsb(struct kref *kref)
11121124 struct dlm_ls * ls = r -> res_ls ;
11131125
11141126 DLM_ASSERT (list_empty (& r -> res_root_list ), dlm_print_rsb (r ););
1115- kref_init (& r -> res_ref );
1116- WARN_ON (rsb_flag (r , RSB_TOSS ));
11171127 rsb_set_flag (r , RSB_TOSS );
11181128 list_move (& r -> res_rsbs_list , & ls -> ls_toss );
11191129 r -> res_toss_time = jiffies ;
@@ -1129,16 +1139,20 @@ static void toss_rsb(struct kref *kref)
11291139static void unhold_rsb (struct dlm_rsb * r )
11301140{
11311141 int rv ;
1142+
1143+ /* rsbs in toss state never get referenced */
1144+ WARN_ON (rsb_flag (r , RSB_TOSS ));
11321145 rv = kref_put (& r -> res_ref , toss_rsb );
11331146 DLM_ASSERT (!rv , dlm_dump_rsb (r ););
11341147}
11351148
1136- static void kill_rsb (struct kref * kref )
1149+ void free_toss_rsb (struct dlm_rsb * r )
11371150{
1138- struct dlm_rsb * r = container_of ( kref , struct dlm_rsb , res_ref );
1151+ WARN_ON_ONCE (! rsb_flag ( r , RSB_TOSS ) );
11391152
1140- /* All work is done after the return from kref_put() so we
1141- can release the write_lock before the remove and free. */
1153+ /* check if all work is done after the rsb is on toss list
1154+ * and it can be freed.
1155+ */
11421156
11431157 DLM_ASSERT (list_empty (& r -> res_lookup ), dlm_dump_rsb (r ););
11441158 DLM_ASSERT (list_empty (& r -> res_grantqueue ), dlm_dump_rsb (r ););
@@ -1147,6 +1161,8 @@ static void kill_rsb(struct kref *kref)
11471161 DLM_ASSERT (list_empty (& r -> res_root_list ), dlm_dump_rsb (r ););
11481162 DLM_ASSERT (list_empty (& r -> res_recover_list ), dlm_dump_rsb (r ););
11491163 DLM_ASSERT (list_empty (& r -> res_masters_list ), dlm_dump_rsb (r ););
1164+
1165+ dlm_free_rsb (r );
11501166}
11511167
11521168/* Attaching/detaching lkb's from rsb's is for rsb reference counting.
@@ -1611,15 +1627,10 @@ static void shrink_bucket(struct dlm_ls *ls)
16111627 continue ;
16121628 }
16131629
1614- if (!kref_put (& r -> res_ref , kill_rsb )) {
1615- log_error (ls , "tossed rsb in use %s" , r -> res_name );
1616- continue ;
1617- }
1618-
16191630 list_del (& r -> res_rsbs_list );
16201631 rhashtable_remove_fast (& ls -> ls_rsbtbl , & r -> res_node ,
16211632 dlm_rhash_rsb_params );
1622- dlm_free_rsb (r );
1633+ free_toss_rsb (r );
16231634 }
16241635
16251636 if (need_shrink )
@@ -1680,19 +1691,13 @@ static void shrink_bucket(struct dlm_ls *ls)
16801691 continue ;
16811692 }
16821693
1683- if (!kref_put (& r -> res_ref , kill_rsb )) {
1684- spin_unlock_bh (& ls -> ls_rsbtbl_lock );
1685- log_error (ls , "remove_name in use %s" , name );
1686- continue ;
1687- }
1688-
16891694 list_del (& r -> res_rsbs_list );
16901695 rhashtable_remove_fast (& ls -> ls_rsbtbl , & r -> res_node ,
16911696 dlm_rhash_rsb_params );
16921697 send_remove (r );
16931698 spin_unlock_bh (& ls -> ls_rsbtbl_lock );
16941699
1695- dlm_free_rsb (r );
1700+ free_toss_rsb (r );
16961701 }
16971702}
16981703
@@ -4180,18 +4185,12 @@ static void receive_remove(struct dlm_ls *ls, const struct dlm_message *ms)
41804185 return ;
41814186 }
41824187
4183- if (kref_put (& r -> res_ref , kill_rsb )) {
4184- list_del (& r -> res_rsbs_list );
4185- rhashtable_remove_fast (& ls -> ls_rsbtbl , & r -> res_node ,
4186- dlm_rhash_rsb_params );
4187- spin_unlock_bh (& ls -> ls_rsbtbl_lock );
4188- dlm_free_rsb (r );
4189- } else {
4190- log_error (ls , "receive_remove from %d rsb ref error" ,
4191- from_nodeid );
4192- dlm_print_rsb (r );
4193- spin_unlock_bh (& ls -> ls_rsbtbl_lock );
4194- }
4188+ list_del (& r -> res_rsbs_list );
4189+ rhashtable_remove_fast (& ls -> ls_rsbtbl , & r -> res_node ,
4190+ dlm_rhash_rsb_params );
4191+ spin_unlock_bh (& ls -> ls_rsbtbl_lock );
4192+
4193+ free_toss_rsb (r );
41954194}
41964195
41974196static void receive_purge (struct dlm_ls * ls , const struct dlm_message * ms )
0 commit comments