2020#include "requestqueue.h"
2121#include "recoverd.h"
2222
23+ static int dlm_create_masters_list (struct dlm_ls * ls )
24+ {
25+ struct rb_node * n ;
26+ struct dlm_rsb * r ;
27+ int i , error = 0 ;
28+
29+ write_lock (& ls -> ls_masters_lock );
30+ if (!list_empty (& ls -> ls_masters_list )) {
31+ log_error (ls , "root list not empty" );
32+ error = - EINVAL ;
33+ goto out ;
34+ }
35+
36+ for (i = 0 ; i < ls -> ls_rsbtbl_size ; i ++ ) {
37+ spin_lock_bh (& ls -> ls_rsbtbl [i ].lock );
38+ for (n = rb_first (& ls -> ls_rsbtbl [i ].keep ); n ; n = rb_next (n )) {
39+ r = rb_entry (n , struct dlm_rsb , res_hashnode );
40+ if (r -> res_nodeid )
41+ continue ;
42+
43+ list_add (& r -> res_masters_list , & ls -> ls_masters_list );
44+ dlm_hold_rsb (r );
45+ }
46+ spin_unlock_bh (& ls -> ls_rsbtbl [i ].lock );
47+ }
48+ out :
49+ write_unlock (& ls -> ls_masters_lock );
50+ return error ;
51+ }
52+
53+ static void dlm_release_masters_list (struct dlm_ls * ls )
54+ {
55+ struct dlm_rsb * r , * safe ;
56+
57+ write_lock (& ls -> ls_masters_lock );
58+ list_for_each_entry_safe (r , safe , & ls -> ls_masters_list , res_masters_list ) {
59+ list_del_init (& r -> res_masters_list );
60+ dlm_put_rsb (r );
61+ }
62+ write_unlock (& ls -> ls_masters_lock );
63+ }
64+
2365static void dlm_create_root_list (struct dlm_ls * ls )
2466{
2567 struct rb_node * n ;
@@ -123,6 +165,23 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
123165
124166 dlm_recover_dir_nodeid (ls );
125167
168+ /* Create a snapshot of all active rsbs were we are the master of.
169+ * During the barrier between dlm_recover_members_wait() and
170+ * dlm_recover_directory() other nodes can dump their necessary
171+ * directory dlm_rsb (r->res_dir_nodeid == nodeid) in rcom
172+ * communication dlm_copy_master_names() handling.
173+ *
174+ * TODO We should create a per lockspace list that contains rsbs
175+ * that we are the master of. Instead of creating this list while
176+ * recovery we keep track of those rsbs while locking handling and
177+ * recovery can use it when necessary.
178+ */
179+ error = dlm_create_masters_list (ls );
180+ if (error ) {
181+ log_rinfo (ls , "dlm_create_masters_list error %d" , error );
182+ goto fail ;
183+ }
184+
126185 ls -> ls_recover_dir_sent_res = 0 ;
127186 ls -> ls_recover_dir_sent_msg = 0 ;
128187 ls -> ls_recover_locks_in = 0 ;
@@ -132,6 +191,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
132191 error = dlm_recover_members_wait (ls , rv -> seq );
133192 if (error ) {
134193 log_rinfo (ls , "dlm_recover_members_wait error %d" , error );
194+ dlm_release_masters_list (ls );
135195 goto fail ;
136196 }
137197
@@ -145,6 +205,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
145205 error = dlm_recover_directory (ls , rv -> seq );
146206 if (error ) {
147207 log_rinfo (ls , "dlm_recover_directory error %d" , error );
208+ dlm_release_masters_list (ls );
148209 goto fail ;
149210 }
150211
@@ -153,9 +214,12 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
153214 error = dlm_recover_directory_wait (ls , rv -> seq );
154215 if (error ) {
155216 log_rinfo (ls , "dlm_recover_directory_wait error %d" , error );
217+ dlm_release_masters_list (ls );
156218 goto fail ;
157219 }
158220
221+ dlm_release_masters_list (ls );
222+
159223 log_rinfo (ls , "dlm_recover_directory %u out %u messages" ,
160224 ls -> ls_recover_dir_sent_res , ls -> ls_recover_dir_sent_msg );
161225
0 commit comments