diff options
Diffstat (limited to 'fs/dlm/debug_fs.c')
| -rw-r--r-- | fs/dlm/debug_fs.c | 103 | 
1 files changed, 96 insertions, 7 deletions
diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index 1c9b08095f9..b969deef9eb 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c @@ -344,6 +344,45 @@ static int print_format3(struct dlm_rsb *r, struct seq_file *s)  	return rv;  } +static int print_format4(struct dlm_rsb *r, struct seq_file *s) +{ +	int our_nodeid = dlm_our_nodeid(); +	int print_name = 1; +	int i, rv; + +	lock_rsb(r); + +	rv = seq_printf(s, "rsb %p %d %d %d %d %lu %lx %d ", +			r, +			r->res_nodeid, +			r->res_master_nodeid, +			r->res_dir_nodeid, +			our_nodeid, +			r->res_toss_time, +			r->res_flags, +			r->res_length); +	if (rv) +		goto out; + +	for (i = 0; i < r->res_length; i++) { +		if (!isascii(r->res_name[i]) || !isprint(r->res_name[i])) +			print_name = 0; +	} + +	seq_printf(s, "%s", print_name ? "str " : "hex"); + +	for (i = 0; i < r->res_length; i++) { +		if (print_name) +			seq_printf(s, "%c", r->res_name[i]); +		else +			seq_printf(s, " %02x", (unsigned char)r->res_name[i]); +	} +	rv = seq_printf(s, "\n"); + out: +	unlock_rsb(r); +	return rv; +} +  struct rsbtbl_iter {  	struct dlm_rsb *rsb;  	unsigned bucket; @@ -382,6 +421,13 @@ static int table_seq_show(struct seq_file *seq, void *iter_ptr)  		}  		rv = print_format3(ri->rsb, seq);  		break; +	case 4: +		if (ri->header) { +			seq_printf(seq, "version 4 rsb 2\n"); +			ri->header = 0; +		} +		rv = print_format4(ri->rsb, seq); +		break;  	}  	return rv; @@ -390,15 +436,18 @@ static int table_seq_show(struct seq_file *seq, void *iter_ptr)  static const struct seq_operations format1_seq_ops;  static const struct seq_operations format2_seq_ops;  static const struct seq_operations format3_seq_ops; +static const struct seq_operations format4_seq_ops;  static void *table_seq_start(struct seq_file *seq, loff_t *pos)  { +	struct rb_root *tree;  	struct rb_node *node;  	struct dlm_ls *ls = seq->private;  	struct rsbtbl_iter *ri;  	struct dlm_rsb *r;  	loff_t n = *pos;  	unsigned bucket, entry; +	int toss = (seq->op == &format4_seq_ops);  	bucket = n >> 32;  	entry = n & ((1LL << 32) - 1); @@ -417,11 +466,14 @@ static void *table_seq_start(struct seq_file *seq, loff_t *pos)  		ri->format = 2;  	if (seq->op == &format3_seq_ops)  		ri->format = 3; +	if (seq->op == &format4_seq_ops) +		ri->format = 4; + +	tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;  	spin_lock(&ls->ls_rsbtbl[bucket].lock); -	if (!RB_EMPTY_ROOT(&ls->ls_rsbtbl[bucket].keep)) { -		for (node = rb_first(&ls->ls_rsbtbl[bucket].keep); node; -		     node = rb_next(node)) { +	if (!RB_EMPTY_ROOT(tree)) { +		for (node = rb_first(tree); node; node = rb_next(node)) {  			r = rb_entry(node, struct dlm_rsb, res_hashnode);  			if (!entry--) {  				dlm_hold_rsb(r); @@ -449,10 +501,11 @@ static void *table_seq_start(struct seq_file *seq, loff_t *pos)  			kfree(ri);  			return NULL;  		} +		tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;  		spin_lock(&ls->ls_rsbtbl[bucket].lock); -		if (!RB_EMPTY_ROOT(&ls->ls_rsbtbl[bucket].keep)) { -			node = rb_first(&ls->ls_rsbtbl[bucket].keep); +		if (!RB_EMPTY_ROOT(tree)) { +			node = rb_first(tree);  			r = rb_entry(node, struct dlm_rsb, res_hashnode);  			dlm_hold_rsb(r);  			ri->rsb = r; @@ -469,10 +522,12 @@ static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos)  {  	struct dlm_ls *ls = seq->private;  	struct rsbtbl_iter *ri = iter_ptr; +	struct rb_root *tree;  	struct rb_node *next;  	struct dlm_rsb *r, *rp;  	loff_t n = *pos;  	unsigned bucket; +	int toss = (seq->op == &format4_seq_ops);  	bucket = n >> 32; @@ -511,10 +566,11 @@ static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos)  			kfree(ri);  			return NULL;  		} +		tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;  		spin_lock(&ls->ls_rsbtbl[bucket].lock); -		if (!RB_EMPTY_ROOT(&ls->ls_rsbtbl[bucket].keep)) { -			next = rb_first(&ls->ls_rsbtbl[bucket].keep); +		if (!RB_EMPTY_ROOT(tree)) { +			next = rb_first(tree);  			r = rb_entry(next, struct dlm_rsb, res_hashnode);  			dlm_hold_rsb(r);  			ri->rsb = r; @@ -558,9 +614,17 @@ static const struct seq_operations format3_seq_ops = {  	.show  = table_seq_show,  }; +static const struct seq_operations format4_seq_ops = { +	.start = table_seq_start, +	.next  = table_seq_next, +	.stop  = table_seq_stop, +	.show  = table_seq_show, +}; +  static const struct file_operations format1_fops;  static const struct file_operations format2_fops;  static const struct file_operations format3_fops; +static const struct file_operations format4_fops;  static int table_open(struct inode *inode, struct file *file)  { @@ -573,6 +637,8 @@ static int table_open(struct inode *inode, struct file *file)  		ret = seq_open(file, &format2_seq_ops);  	else if (file->f_op == &format3_fops)  		ret = seq_open(file, &format3_seq_ops); +	else if (file->f_op == &format4_fops) +		ret = seq_open(file, &format4_seq_ops);  	if (ret)  		return ret; @@ -606,6 +672,14 @@ static const struct file_operations format3_fops = {  	.release = seq_release  }; +static const struct file_operations format4_fops = { +	.owner   = THIS_MODULE, +	.open    = table_open, +	.read    = seq_read, +	.llseek  = seq_lseek, +	.release = seq_release +}; +  /*   * dump lkb's on the ls_waiters list   */ @@ -652,6 +726,8 @@ void dlm_delete_debug_file(struct dlm_ls *ls)  		debugfs_remove(ls->ls_debug_locks_dentry);  	if (ls->ls_debug_all_dentry)  		debugfs_remove(ls->ls_debug_all_dentry); +	if (ls->ls_debug_toss_dentry) +		debugfs_remove(ls->ls_debug_toss_dentry);  }  int dlm_create_debug_file(struct dlm_ls *ls) @@ -694,6 +770,19 @@ int dlm_create_debug_file(struct dlm_ls *ls)  	if (!ls->ls_debug_all_dentry)  		goto fail; +	/* format 4 */ + +	memset(name, 0, sizeof(name)); +	snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_toss", ls->ls_name); + +	ls->ls_debug_toss_dentry = debugfs_create_file(name, +						       S_IFREG | S_IRUGO, +						       dlm_root, +						       ls, +						       &format4_fops); +	if (!ls->ls_debug_toss_dentry) +		goto fail; +  	memset(name, 0, sizeof(name));  	snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_waiters", ls->ls_name);  |