@@ -325,6 +325,8 @@ static void queue_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rqmode)
325
325
326
326
static inline void hold_rsb (struct dlm_rsb * r )
327
327
{
328
+ /* rsbs in toss state never get referenced */
329
+ WARN_ON (rsb_flag (r , RSB_TOSS ));
328
330
kref_get (& r -> res_ref );
329
331
}
330
332
@@ -631,6 +633,11 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
631
633
632
634
list_move (& r -> res_rsbs_list , & ls -> ls_keep );
633
635
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 );
634
641
goto out_unlock ;
635
642
636
643
@@ -765,6 +772,11 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
765
772
766
773
list_move (& r -> res_rsbs_list , & ls -> ls_keep );
767
774
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 );
768
780
goto out_unlock ;
769
781
770
782
@@ -1112,8 +1124,6 @@ static void toss_rsb(struct kref *kref)
1112
1124
struct dlm_ls * ls = r -> res_ls ;
1113
1125
1114
1126
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 ));
1117
1127
rsb_set_flag (r , RSB_TOSS );
1118
1128
list_move (& r -> res_rsbs_list , & ls -> ls_toss );
1119
1129
r -> res_toss_time = jiffies ;
@@ -1129,16 +1139,20 @@ static void toss_rsb(struct kref *kref)
1129
1139
static void unhold_rsb (struct dlm_rsb * r )
1130
1140
{
1131
1141
int rv ;
1142
+
1143
+ /* rsbs in toss state never get referenced */
1144
+ WARN_ON (rsb_flag (r , RSB_TOSS ));
1132
1145
rv = kref_put (& r -> res_ref , toss_rsb );
1133
1146
DLM_ASSERT (!rv , dlm_dump_rsb (r ););
1134
1147
}
1135
1148
1136
- static void kill_rsb (struct kref * kref )
1149
+ void free_toss_rsb (struct dlm_rsb * r )
1137
1150
{
1138
- struct dlm_rsb * r = container_of ( kref , struct dlm_rsb , res_ref );
1151
+ WARN_ON_ONCE (! rsb_flag ( r , RSB_TOSS ) );
1139
1152
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
+ */
1142
1156
1143
1157
DLM_ASSERT (list_empty (& r -> res_lookup ), dlm_dump_rsb (r ););
1144
1158
DLM_ASSERT (list_empty (& r -> res_grantqueue ), dlm_dump_rsb (r ););
@@ -1147,6 +1161,8 @@ static void kill_rsb(struct kref *kref)
1147
1161
DLM_ASSERT (list_empty (& r -> res_root_list ), dlm_dump_rsb (r ););
1148
1162
DLM_ASSERT (list_empty (& r -> res_recover_list ), dlm_dump_rsb (r ););
1149
1163
DLM_ASSERT (list_empty (& r -> res_masters_list ), dlm_dump_rsb (r ););
1164
+
1165
+ dlm_free_rsb (r );
1150
1166
}
1151
1167
1152
1168
/* Attaching/detaching lkb's from rsb's is for rsb reference counting.
@@ -1611,15 +1627,10 @@ static void shrink_bucket(struct dlm_ls *ls)
1611
1627
continue ;
1612
1628
}
1613
1629
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
-
1619
1630
list_del (& r -> res_rsbs_list );
1620
1631
rhashtable_remove_fast (& ls -> ls_rsbtbl , & r -> res_node ,
1621
1632
dlm_rhash_rsb_params );
1622
- dlm_free_rsb (r );
1633
+ free_toss_rsb (r );
1623
1634
}
1624
1635
1625
1636
if (need_shrink )
@@ -1680,19 +1691,13 @@ static void shrink_bucket(struct dlm_ls *ls)
1680
1691
continue ;
1681
1692
}
1682
1693
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
-
1689
1694
list_del (& r -> res_rsbs_list );
1690
1695
rhashtable_remove_fast (& ls -> ls_rsbtbl , & r -> res_node ,
1691
1696
dlm_rhash_rsb_params );
1692
1697
send_remove (r );
1693
1698
spin_unlock_bh (& ls -> ls_rsbtbl_lock );
1694
1699
1695
- dlm_free_rsb (r );
1700
+ free_toss_rsb (r );
1696
1701
}
1697
1702
}
1698
1703
@@ -4180,18 +4185,12 @@ static void receive_remove(struct dlm_ls *ls, const struct dlm_message *ms)
4180
4185
return ;
4181
4186
}
4182
4187
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 );
4195
4194
}
4196
4195
4197
4196
static void receive_purge (struct dlm_ls * ls , const struct dlm_message * ms )
0 commit comments