Skip to content

Commit 93a693d

Browse files
Alexander Aringteigland
authored andcommitted
dlm: add rsb lists for iteration
To prepare for using rhashtable, add two rsb lists for iterating through rsb's in two uncommon cases where this is necesssary: - when dumping rsb state from debugfs, now using seq_list. - when looking at all rsb's during recovery. Signed-off-by: Alexander Aring <[email protected]> Signed-off-by: David Teigland <[email protected]>
1 parent 2d90354 commit 93a693d

File tree

6 files changed

+84
-261
lines changed

6 files changed

+84
-261
lines changed

fs/dlm/debug_fs.c

Lines changed: 36 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -366,12 +366,10 @@ static void print_format4(struct dlm_rsb *r, struct seq_file *s)
366366
unlock_rsb(r);
367367
}
368368

369-
struct rsbtbl_iter {
370-
struct dlm_rsb *rsb;
371-
unsigned bucket;
372-
int format;
373-
int header;
374-
};
369+
static const struct seq_operations format1_seq_ops;
370+
static const struct seq_operations format2_seq_ops;
371+
static const struct seq_operations format3_seq_ops;
372+
static const struct seq_operations format4_seq_ops;
375373

376374
/*
377375
* If the buffer is full, seq_printf can be called again, but it
@@ -382,220 +380,61 @@ struct rsbtbl_iter {
382380

383381
static int table_seq_show(struct seq_file *seq, void *iter_ptr)
384382
{
385-
struct rsbtbl_iter *ri = iter_ptr;
386-
387-
switch (ri->format) {
388-
case 1:
389-
print_format1(ri->rsb, seq);
390-
break;
391-
case 2:
392-
if (ri->header) {
393-
seq_puts(seq, "id nodeid remid pid xid exflags flags sts grmode rqmode time_ms r_nodeid r_len r_name\n");
394-
ri->header = 0;
395-
}
396-
print_format2(ri->rsb, seq);
397-
break;
398-
case 3:
399-
if (ri->header) {
400-
seq_puts(seq, "rsb ptr nodeid first_lkid flags !root_list_empty !recover_list_empty recover_locks_count len\n");
401-
ri->header = 0;
402-
}
403-
print_format3(ri->rsb, seq);
404-
break;
405-
case 4:
406-
if (ri->header) {
407-
seq_puts(seq, "rsb ptr nodeid master_nodeid dir_nodeid our_nodeid toss_time flags len str|hex name\n");
408-
ri->header = 0;
409-
}
410-
print_format4(ri->rsb, seq);
411-
break;
412-
}
383+
struct dlm_rsb *rsb = list_entry(iter_ptr, struct dlm_rsb, res_rsbs_list);
384+
385+
if (seq->op == &format1_seq_ops)
386+
print_format1(rsb, seq);
387+
else if (seq->op == &format2_seq_ops)
388+
print_format2(rsb, seq);
389+
else if (seq->op == &format3_seq_ops)
390+
print_format3(rsb, seq);
391+
else if (seq->op == &format4_seq_ops)
392+
print_format4(rsb, seq);
413393

414394
return 0;
415395
}
416396

417-
static const struct seq_operations format1_seq_ops;
418-
static const struct seq_operations format2_seq_ops;
419-
static const struct seq_operations format3_seq_ops;
420-
static const struct seq_operations format4_seq_ops;
421-
422397
static void *table_seq_start(struct seq_file *seq, loff_t *pos)
423398
{
424-
struct rb_root *tree;
425-
struct rb_node *node;
426399
struct dlm_ls *ls = seq->private;
427-
struct rsbtbl_iter *ri;
428-
struct dlm_rsb *r;
429-
loff_t n = *pos;
430-
unsigned bucket, entry;
431-
int toss = (seq->op == &format4_seq_ops);
432-
433-
bucket = n >> 32;
434-
entry = n & ((1LL << 32) - 1);
435-
436-
if (bucket >= ls->ls_rsbtbl_size)
437-
return NULL;
438-
439-
ri = kzalloc(sizeof(*ri), GFP_NOFS);
440-
if (!ri)
441-
return NULL;
442-
if (n == 0)
443-
ri->header = 1;
444-
if (seq->op == &format1_seq_ops)
445-
ri->format = 1;
446-
if (seq->op == &format2_seq_ops)
447-
ri->format = 2;
448-
if (seq->op == &format3_seq_ops)
449-
ri->format = 3;
450-
if (seq->op == &format4_seq_ops)
451-
ri->format = 4;
452-
453-
tree = &ls->ls_rsbtbl[bucket].r;
400+
struct list_head *list;
454401

455-
spin_lock_bh(&ls->ls_rsbtbl_lock);
456-
if (!RB_EMPTY_ROOT(tree)) {
457-
for (node = rb_first(tree); node; node = rb_next(node)) {
458-
r = rb_entry(node, struct dlm_rsb, res_hashnode);
459-
if (toss) {
460-
if (!rsb_flag(r, RSB_TOSS))
461-
continue;
462-
} else {
463-
if (rsb_flag(r, RSB_TOSS))
464-
continue;
465-
}
466-
467-
if (!entry--) {
468-
dlm_hold_rsb(r);
469-
ri->rsb = r;
470-
ri->bucket = bucket;
471-
spin_unlock_bh(&ls->ls_rsbtbl_lock);
472-
return ri;
473-
}
474-
}
402+
if (!*pos) {
403+
if (seq->op == &format2_seq_ops)
404+
seq_puts(seq, "id nodeid remid pid xid exflags flags sts grmode rqmode time_ms r_nodeid r_len r_name\n");
405+
else if (seq->op == &format3_seq_ops)
406+
seq_puts(seq, "rsb ptr nodeid first_lkid flags !root_list_empty !recover_list_empty recover_locks_count len\n");
407+
else if (seq->op == &format4_seq_ops)
408+
seq_puts(seq, "rsb ptr nodeid master_nodeid dir_nodeid our_nodeid toss_time flags len str|hex name\n");
475409
}
476-
spin_unlock_bh(&ls->ls_rsbtbl_lock);
477-
478-
/*
479-
* move to the first rsb in the next non-empty bucket
480-
*/
481-
482-
/* zero the entry */
483-
n &= ~((1LL << 32) - 1);
484410

485-
while (1) {
486-
bucket++;
487-
n += 1LL << 32;
411+
if (seq->op == &format4_seq_ops)
412+
list = &ls->ls_toss;
413+
else
414+
list = &ls->ls_keep;
488415

489-
if (bucket >= ls->ls_rsbtbl_size) {
490-
kfree(ri);
491-
return NULL;
492-
}
493-
tree = &ls->ls_rsbtbl[bucket].r;
494-
495-
spin_lock_bh(&ls->ls_rsbtbl_lock);
496-
if (!RB_EMPTY_ROOT(tree)) {
497-
node = rb_first(tree);
498-
r = rb_entry(node, struct dlm_rsb, res_hashnode);
499-
if (toss) {
500-
if (!rsb_flag(r, RSB_TOSS))
501-
continue;
502-
} else {
503-
if (rsb_flag(r, RSB_TOSS))
504-
continue;
505-
}
506-
507-
dlm_hold_rsb(r);
508-
ri->rsb = r;
509-
ri->bucket = bucket;
510-
spin_unlock_bh(&ls->ls_rsbtbl_lock);
511-
*pos = n;
512-
return ri;
513-
}
514-
spin_unlock_bh(&ls->ls_rsbtbl_lock);
515-
}
416+
spin_lock_bh(&ls->ls_rsbtbl_lock);
417+
return seq_list_start(list, *pos);
516418
}
517419

518420
static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos)
519421
{
520422
struct dlm_ls *ls = seq->private;
521-
struct rsbtbl_iter *ri = iter_ptr;
522-
struct rb_root *tree;
523-
struct rb_node *next;
524-
struct dlm_rsb *r, *rp;
525-
loff_t n = *pos;
526-
unsigned bucket;
527-
int toss = (seq->op == &format4_seq_ops);
528-
529-
bucket = n >> 32;
530-
531-
/*
532-
* move to the next rsb in the same bucket
533-
*/
534-
535-
spin_lock_bh(&ls->ls_rsbtbl_lock);
536-
rp = ri->rsb;
537-
next = rb_next(&rp->res_hashnode);
538-
539-
if (next) {
540-
r = rb_entry(next, struct dlm_rsb, res_hashnode);
541-
dlm_hold_rsb(r);
542-
ri->rsb = r;
543-
spin_unlock_bh(&ls->ls_rsbtbl_lock);
544-
dlm_put_rsb(rp);
545-
++*pos;
546-
return ri;
547-
}
548-
spin_unlock_bh(&ls->ls_rsbtbl_lock);
549-
dlm_put_rsb(rp);
550-
551-
/*
552-
* move to the first rsb in the next non-empty bucket
553-
*/
423+
struct list_head *list;
554424

555-
/* zero the entry */
556-
n &= ~((1LL << 32) - 1);
557-
558-
while (1) {
559-
bucket++;
560-
n += 1LL << 32;
425+
if (seq->op == &format4_seq_ops)
426+
list = &ls->ls_toss;
427+
else
428+
list = &ls->ls_keep;
561429

562-
if (bucket >= ls->ls_rsbtbl_size) {
563-
kfree(ri);
564-
++*pos;
565-
return NULL;
566-
}
567-
tree = &ls->ls_rsbtbl[bucket].r;
568-
569-
spin_lock_bh(&ls->ls_rsbtbl_lock);
570-
if (!RB_EMPTY_ROOT(tree)) {
571-
next = rb_first(tree);
572-
r = rb_entry(next, struct dlm_rsb, res_hashnode);
573-
if (toss) {
574-
if (!rsb_flag(r, RSB_TOSS))
575-
continue;
576-
} else {
577-
if (rsb_flag(r, RSB_TOSS))
578-
continue;
579-
}
580-
dlm_hold_rsb(r);
581-
ri->rsb = r;
582-
ri->bucket = bucket;
583-
spin_unlock_bh(&ls->ls_rsbtbl_lock);
584-
*pos = n;
585-
return ri;
586-
}
587-
spin_unlock_bh(&ls->ls_rsbtbl_lock);
588-
}
430+
return seq_list_next(iter_ptr, list, pos);
589431
}
590432

591433
static void table_seq_stop(struct seq_file *seq, void *iter_ptr)
592434
{
593-
struct rsbtbl_iter *ri = iter_ptr;
435+
struct dlm_ls *ls = seq->private;
594436

595-
if (ri) {
596-
dlm_put_rsb(ri->rsb);
597-
kfree(ri);
598-
}
437+
spin_unlock_bh(&ls->ls_rsbtbl_lock);
599438
}
600439

601440
static const struct seq_operations format1_seq_ops = {

fs/dlm/dlm_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ struct dlm_rsb {
339339
struct list_head res_convertqueue;
340340
struct list_head res_waitqueue;
341341

342+
struct list_head res_rsbs_list;
342343
struct list_head res_root_list; /* used for recovery */
343344
struct list_head res_masters_list; /* used for recovery */
344345
struct list_head res_recover_list; /* used for recovery */
@@ -595,6 +596,9 @@ struct dlm_ls {
595596
spinlock_t ls_rsbtbl_lock;
596597
uint32_t ls_rsbtbl_size;
597598

599+
struct list_head ls_toss;
600+
struct list_head ls_keep;
601+
598602
spinlock_t ls_waiters_lock;
599603
struct list_head ls_waiters; /* lkbs needing a reply */
600604

0 commit comments

Comments
 (0)