diff options
-rw-r--r-- | fs/dlm/dir.c | 66 | ||||
-rw-r--r-- | fs/dlm/lock.c | 6 | ||||
-rw-r--r-- | fs/dlm/lock.h | 2 | ||||
-rw-r--r-- | fs/dlm/recover.c | 25 | ||||
-rw-r--r-- | fs/dlm/recoverd.c | 11 |
5 files changed, 61 insertions, 49 deletions
diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c index 600bb1d1a9b6..ff97ba924333 100644 --- a/fs/dlm/dir.c +++ b/fs/dlm/dir.c | |||
@@ -329,49 +329,47 @@ int dlm_dir_lookup(struct dlm_ls *ls, int nodeid, char *name, int namelen, | |||
329 | return get_entry(ls, nodeid, name, namelen, r_nodeid); | 329 | return get_entry(ls, nodeid, name, namelen, r_nodeid); |
330 | } | 330 | } |
331 | 331 | ||
332 | /* Copy the names of master rsb's into the buffer provided. | 332 | static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len) |
333 | Only select names whose dir node is the given nodeid. */ | 333 | { |
334 | struct dlm_rsb *r; | ||
335 | |||
336 | down_read(&ls->ls_root_sem); | ||
337 | list_for_each_entry(r, &ls->ls_root_list, res_root_list) { | ||
338 | if (len == r->res_length && !memcmp(name, r->res_name, len)) { | ||
339 | up_read(&ls->ls_root_sem); | ||
340 | return r; | ||
341 | } | ||
342 | } | ||
343 | up_read(&ls->ls_root_sem); | ||
344 | return NULL; | ||
345 | } | ||
346 | |||
347 | /* Find the rsb where we left off (or start again), then send rsb names | ||
348 | for rsb's we're master of and whose directory node matches the requesting | ||
349 | node. inbuf is the rsb name last sent, inlen is the name's length */ | ||
334 | 350 | ||
335 | void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen, | 351 | void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen, |
336 | char *outbuf, int outlen, int nodeid) | 352 | char *outbuf, int outlen, int nodeid) |
337 | { | 353 | { |
338 | struct list_head *list; | 354 | struct list_head *list; |
339 | struct dlm_rsb *start_r = NULL, *r = NULL; | 355 | struct dlm_rsb *r; |
340 | int offset = 0, start_namelen, error, dir_nodeid; | 356 | int offset = 0, dir_nodeid; |
341 | char *start_name; | ||
342 | uint16_t be_namelen; | 357 | uint16_t be_namelen; |
343 | 358 | ||
344 | /* | ||
345 | * Find the rsb where we left off (or start again) | ||
346 | */ | ||
347 | |||
348 | start_namelen = inlen; | ||
349 | start_name = inbuf; | ||
350 | |||
351 | if (start_namelen > 1) { | ||
352 | /* | ||
353 | * We could also use a find_rsb_root() function here that | ||
354 | * searched the ls_root_list. | ||
355 | */ | ||
356 | error = dlm_find_rsb(ls, start_name, start_namelen, R_MASTER, | ||
357 | &start_r); | ||
358 | DLM_ASSERT(!error && start_r, | ||
359 | printk("error %d\n", error);); | ||
360 | DLM_ASSERT(!list_empty(&start_r->res_root_list), | ||
361 | dlm_print_rsb(start_r);); | ||
362 | dlm_put_rsb(start_r); | ||
363 | } | ||
364 | |||
365 | /* | ||
366 | * Send rsb names for rsb's we're master of and whose directory node | ||
367 | * matches the requesting node. | ||
368 | */ | ||
369 | |||
370 | down_read(&ls->ls_root_sem); | 359 | down_read(&ls->ls_root_sem); |
371 | if (start_r) | 360 | |
372 | list = start_r->res_root_list.next; | 361 | if (inlen > 1) { |
373 | else | 362 | r = find_rsb_root(ls, inbuf, inlen); |
363 | if (!r) { | ||
364 | inbuf[inlen - 1] = '\0'; | ||
365 | log_error(ls, "copy_master_names from %d start %d %s", | ||
366 | nodeid, inlen, inbuf); | ||
367 | goto out; | ||
368 | } | ||
369 | list = r->res_root_list.next; | ||
370 | } else { | ||
374 | list = ls->ls_root_list.next; | 371 | list = ls->ls_root_list.next; |
372 | } | ||
375 | 373 | ||
376 | for (offset = 0; list != &ls->ls_root_list; list = list->next) { | 374 | for (offset = 0; list != &ls->ls_root_list; list = list->next) { |
377 | r = list_entry(list, struct dlm_rsb, res_root_list); | 375 | r = list_entry(list, struct dlm_rsb, res_root_list); |
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 7ee7c7c55453..ff4a198fa677 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -489,12 +489,6 @@ static int find_rsb(struct dlm_ls *ls, char *name, int namelen, | |||
489 | return error; | 489 | return error; |
490 | } | 490 | } |
491 | 491 | ||
492 | int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen, | ||
493 | unsigned int flags, struct dlm_rsb **r_ret) | ||
494 | { | ||
495 | return find_rsb(ls, name, namelen, flags, r_ret); | ||
496 | } | ||
497 | |||
498 | /* This is only called to add a reference when the code already holds | 492 | /* This is only called to add a reference when the code already holds |
499 | a valid reference to the rsb, so there's no need for locking. */ | 493 | a valid reference to the rsb, so there's no need for locking. */ |
500 | 494 | ||
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h index ada04680a1e5..27b6ed302911 100644 --- a/fs/dlm/lock.h +++ b/fs/dlm/lock.h | |||
@@ -19,8 +19,6 @@ void dlm_print_lkb(struct dlm_lkb *lkb); | |||
19 | void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); | 19 | void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); |
20 | void dlm_receive_buffer(struct dlm_header *hd, int nodeid); | 20 | void dlm_receive_buffer(struct dlm_header *hd, int nodeid); |
21 | int dlm_modes_compat(int mode1, int mode2); | 21 | int dlm_modes_compat(int mode1, int mode2); |
22 | int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen, | ||
23 | unsigned int flags, struct dlm_rsb **r_ret); | ||
24 | void dlm_put_rsb(struct dlm_rsb *r); | 22 | void dlm_put_rsb(struct dlm_rsb *r); |
25 | void dlm_hold_rsb(struct dlm_rsb *r); | 23 | void dlm_hold_rsb(struct dlm_rsb *r); |
26 | int dlm_put_lkb(struct dlm_lkb *lkb); | 24 | int dlm_put_lkb(struct dlm_lkb *lkb); |
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c index 2f9d9a30df97..df075dc300fa 100644 --- a/fs/dlm/recover.c +++ b/fs/dlm/recover.c | |||
@@ -731,6 +731,20 @@ int dlm_create_root_list(struct dlm_ls *ls) | |||
731 | list_add(&r->res_root_list, &ls->ls_root_list); | 731 | list_add(&r->res_root_list, &ls->ls_root_list); |
732 | dlm_hold_rsb(r); | 732 | dlm_hold_rsb(r); |
733 | } | 733 | } |
734 | |||
735 | /* If we're using a directory, add tossed rsbs to the root | ||
736 | list; they'll have entries created in the new directory, | ||
737 | but no other recovery steps should do anything with them. */ | ||
738 | |||
739 | if (dlm_no_directory(ls)) { | ||
740 | read_unlock(&ls->ls_rsbtbl[i].lock); | ||
741 | continue; | ||
742 | } | ||
743 | |||
744 | list_for_each_entry(r, &ls->ls_rsbtbl[i].toss, res_hashchain) { | ||
745 | list_add(&r->res_root_list, &ls->ls_root_list); | ||
746 | dlm_hold_rsb(r); | ||
747 | } | ||
734 | read_unlock(&ls->ls_rsbtbl[i].lock); | 748 | read_unlock(&ls->ls_rsbtbl[i].lock); |
735 | } | 749 | } |
736 | out: | 750 | out: |
@@ -750,6 +764,11 @@ void dlm_release_root_list(struct dlm_ls *ls) | |||
750 | up_write(&ls->ls_root_sem); | 764 | up_write(&ls->ls_root_sem); |
751 | } | 765 | } |
752 | 766 | ||
767 | /* If not using a directory, clear the entire toss list, there's no benefit to | ||
768 | caching the master value since it's fixed. If we are using a dir, keep the | ||
769 | rsb's we're the master of. Recovery will add them to the root list and from | ||
770 | there they'll be entered in the rebuilt directory. */ | ||
771 | |||
753 | void dlm_clear_toss_list(struct dlm_ls *ls) | 772 | void dlm_clear_toss_list(struct dlm_ls *ls) |
754 | { | 773 | { |
755 | struct dlm_rsb *r, *safe; | 774 | struct dlm_rsb *r, *safe; |
@@ -759,8 +778,10 @@ void dlm_clear_toss_list(struct dlm_ls *ls) | |||
759 | write_lock(&ls->ls_rsbtbl[i].lock); | 778 | write_lock(&ls->ls_rsbtbl[i].lock); |
760 | list_for_each_entry_safe(r, safe, &ls->ls_rsbtbl[i].toss, | 779 | list_for_each_entry_safe(r, safe, &ls->ls_rsbtbl[i].toss, |
761 | res_hashchain) { | 780 | res_hashchain) { |
762 | list_del(&r->res_hashchain); | 781 | if (dlm_no_directory(ls) || !is_master(r)) { |
763 | dlm_free_rsb(r); | 782 | list_del(&r->res_hashchain); |
783 | dlm_free_rsb(r); | ||
784 | } | ||
764 | } | 785 | } |
765 | write_unlock(&ls->ls_rsbtbl[i].lock); | 786 | write_unlock(&ls->ls_rsbtbl[i].lock); |
766 | } | 787 | } |
diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c index 4b89e20eebe7..997f9531d594 100644 --- a/fs/dlm/recoverd.c +++ b/fs/dlm/recoverd.c | |||
@@ -67,17 +67,18 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
67 | dlm_astd_resume(); | 67 | dlm_astd_resume(); |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * This list of root rsb's will be the basis of most of the recovery | 70 | * Free non-master tossed rsb's. Master rsb's are kept on toss |
71 | * routines. | 71 | * list and put on root list to be included in resdir recovery. |
72 | */ | 72 | */ |
73 | 73 | ||
74 | dlm_create_root_list(ls); | 74 | dlm_clear_toss_list(ls); |
75 | 75 | ||
76 | /* | 76 | /* |
77 | * Free all the tossed rsb's so we don't have to recover them. | 77 | * This list of root rsb's will be the basis of most of the recovery |
78 | * routines. | ||
78 | */ | 79 | */ |
79 | 80 | ||
80 | dlm_clear_toss_list(ls); | 81 | dlm_create_root_list(ls); |
81 | 82 | ||
82 | /* | 83 | /* |
83 | * Add or remove nodes from the lockspace's ls_nodes list. | 84 | * Add or remove nodes from the lockspace's ls_nodes list. |