aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm/dir.c
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2008-01-16 14:02:31 -0500
committerDavid Teigland <teigland@redhat.com>2008-01-30 12:04:43 -0500
commit85f0379aa0f9366bb6918e2e898a915231176fbd (patch)
tree359544ba2ad34c1e49d4e6333b7c36cf8c7685f5 /fs/dlm/dir.c
parent594199ebaae5d77f025974dfcfa6651cc81325a8 (diff)
dlm: keep cached master rsbs during recovery
To prevent the master of an rsb from changing rapidly, an unused rsb is kept on the "toss list" for a period of time to be reused. The toss list was being cleared completely for each recovery, which is unnecessary. Much of the benefit of the toss list can be maintained if nodes keep rsb's in their toss list that they are the master of. These rsb's need to be included when the resource directory is rebuilt during recovery. Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/dlm/dir.c')
-rw-r--r--fs/dlm/dir.c66
1 files changed, 32 insertions, 34 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. 332static 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
335void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen, 351void 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);