All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Fasheh <mfasheh@suse.com>
To: ocfs2-devel@oss.oracle.com
Subject: [Ocfs2-devel] [PATCH 3/9] ocfs2: Exposes the file system state via debugfs
Date: Tue, 16 Dec 2008 17:16:01 -0800	[thread overview]
Message-ID: <20081217011601.GB8791@wotan.suse.de> (raw)
In-Reply-To: <1229471363-15887-4-git-send-email-sunil.mushran@oracle.com>

On Tue, Dec 16, 2008 at 03:49:17PM -0800, Sunil Mushran wrote:
> Patch creates a per mount debugfs file, fs_state, which exposes information
> like, cluster stack in use, states of the downconvert, recovery and commit
> threads, number of journal txns, some allocation stats, list of all slots, etc.
> 
> Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
> ---
>  fs/ocfs2/ocfs2.h |    1 +
>  fs/ocfs2/super.c |  220 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 221 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
> index 3fed9e3..d912b70 100644
> --- a/fs/ocfs2/ocfs2.h
> +++ b/fs/ocfs2/ocfs2.h
> @@ -301,6 +301,7 @@ struct ocfs2_super
>  	struct ocfs2_dlm_debug *osb_dlm_debug;
>  
>  	struct dentry *osb_debug_root;
> +	struct dentry *osb_ctxt;
>  
>  	wait_queue_head_t recovery_event;
>  
> diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
> index 304b63a..7808866 100644
> --- a/fs/ocfs2/super.c
> +++ b/fs/ocfs2/super.c
> @@ -619,6 +619,214 @@ static int ocfs2_verify_userspace_stack(struct ocfs2_super *osb,
>  	return 0;
>  }
>  
> +#ifdef CONFIG_DEBUG_FS
> +struct ocfs2_debug_buffer {
> +	int len;
> +	char *buf;
> +};
> +
> +static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len)
> +{
> +	int out = 0;
> +	int i;
> +	struct ocfs2_cluster_connection *cconn = osb->cconn;
> +	struct ocfs2_recovery_map *rm = osb->recovery_map;
> +
> +	out += snprintf(buf + out, len - out,
> +			"%10s => Id: %-s  Uuid: %-s  Gen: 0x%X  Label: %-s\n",
> +			"Device", osb->dev_str, osb->uuid_str,
> +			osb->fs_generation, osb->vol_label);
> +
> +	out += snprintf(buf + out, len - out,
> +			"%10s => State: %d  Flags: 0x%lX\n", "Volume",
> +			atomic_read(&osb->vol_state), osb->osb_flags);
> +
> +	out += snprintf(buf + out, len - out,
> +			"%10s => Block: %lu  Cluster: %d\n", "Sizes",
> +			osb->sb->s_blocksize, osb->s_clustersize);
> +
> +	out += snprintf(buf + out, len - out,
> +			"%10s => Compat: 0x%X  Incompat: 0x%X  "
> +			"ROcompat: 0x%X\n",
> +			"Features", osb->s_feature_compat,
> +			osb->s_feature_incompat, osb->s_feature_ro_compat);
> +
> +	out += snprintf(buf + out, len - out,
> +			"%10s => Opts: 0x%lX  AtimeQuanta: %u\n", "Mount",
> +			osb->s_mount_opt, osb->s_atime_quantum);

A lot of the above seems a bit like overkill to me. Couldn't we just get
this stuff with 'mount' and 'debugfs.ocfs2'?



> +	out += snprintf(buf + out, len - out,
> +			"%10s => Stack: %s  Name: %*s  Version: %d.%d\n",
> +			"Cluster",
> +			(*osb->osb_cluster_stack == '\0' ?
> +			 "o2cb" : osb->osb_cluster_stack),
> +			cconn->cc_namelen, cconn->cc_name,
> +			cconn->cc_version.pv_major, cconn->cc_version.pv_minor);
> +
> +	spin_lock(&osb->dc_task_lock);
> +	out += snprintf(buf + out, len - out,
> +			"%10s => Pid: %d  Count: %lu  WakeSeq: %lu  "
> +			"WorkSeq: %lu\n", "DownCnvt",
> +			task_pid_nr(osb->dc_task), osb->blocked_lock_count,
> +			osb->dc_wake_sequence, osb->dc_work_sequence);
> +	spin_unlock(&osb->dc_task_lock);
> +
> +	spin_lock(&osb->osb_lock);
> +	out += snprintf(buf + out, len - out, "%10s => Pid: %d  Nodes:",
> +			"Recovery",
> +			(osb->recovery_thread_task ?
> +			 task_pid_nr(osb->recovery_thread_task) : -1));
> +	if (rm->rm_used == 0)
> +		out += snprintf(buf + out, len - out, " None\n");
> +	else {
> +		for (i = 0; i < rm->rm_used; i++)
> +			out += snprintf(buf + out, len - out, " %d",
> +					rm->rm_entries[i]);
> +		out += snprintf(buf + out, len - out, "\n");
> +	}
> +	spin_unlock(&osb->osb_lock);
> +
> +	out += snprintf(buf + out, len - out,
> +			"%10s => Pid: %d  Interval: %lu  Needs: %d\n", "Commit",
> +			task_pid_nr(osb->commit_task), osb->osb_commit_interval,
> +			atomic_read(&osb->needs_checkpoint));
> +
> +	out += snprintf(buf + out, len - out,
> +			"%10s => State: %d  NumTxns: %d  TxnId: %lu\n",
> +			"Journal", osb->journal->j_state,
> +			atomic_read(&osb->journal->j_num_trans),
> +			osb->journal->j_trans_id);
> +
> +	out += snprintf(buf + out, len - out,
> +			"%10s => GlobalAllocs: %d  LocalAllocs: %d  "
> +			"SubAllocs: %d  LAWinMoves: %d  SAExtends: %d\n",
> +			"Stats",
> +			atomic_read(&osb->alloc_stats.bitmap_data),
> +			atomic_read(&osb->alloc_stats.local_data),
> +			atomic_read(&osb->alloc_stats.bg_allocs),
> +			atomic_read(&osb->alloc_stats.moves),
> +			atomic_read(&osb->alloc_stats.bg_extends));
> +
> +	out += snprintf(buf + out, len - out,
> +			"%10s => State: %u  Descriptor: %llu  Size: %u bits  "
> +			"Default: %u bits\n",
> +			"LocalAlloc", osb->local_alloc_state,
> +			(unsigned long long)osb->la_last_gd,
> +			osb->local_alloc_bits, osb->local_alloc_default_bits);
> +
> +	spin_lock(&osb->osb_lock);
> +	out += snprintf(buf + out, len - out,
> +			"%10s => Slot: %d  NumStolen: %d\n", "Steal",
> +			osb->s_inode_steal_slot,
> +			atomic_read(&osb->s_num_inodes_stolen));
> +	spin_unlock(&osb->osb_lock);
> +
> +	out += snprintf(buf + out, len - out, "%10s => %3s  %10s\n",
> +			"Slots", "Num", "RecoGen");
> +
> +	for (i = 0; i < osb->max_slots; ++i) {
> +		out += snprintf(buf + out, len - out,
> +				"%10s  %c %3d  %10d\n",
> +				" ",
> +				(i == osb->slot_num ? '*' : ' '),
> +				i, osb->slot_recovery_generations[i]);
> +	}

Also, I wonder if it's not a bad idea to split out the important stuff into
their own files.


> +
> +	return out;
> +}
> +
> +static int ocfs2_osb_debug_open(struct inode *inode, struct file *file)
> +{
> +	struct ocfs2_debug_buffer *odb = NULL;
> +	struct ocfs2_super *osb = inode->i_private;
> +
> +	odb = kzalloc(sizeof(struct ocfs2_debug_buffer), GFP_KERNEL);
> +	if (!odb)
> +		goto bail;
> +
> +	odb->len = PAGE_SIZE;
> +	odb->buf = kmalloc(odb->len, GFP_KERNEL);
> +	if (!odb->buf) {
> +		kfree(odb);
> +		goto bail;
> +	}
> +
> +	odb->len = ocfs2_osb_dump(osb, odb->buf, odb->len);
> +
> +	file->private_data = odb;
> +
> +	return 0;
> +bail:
> +	return -ENOMEM;
> +}
> +
> +static int ocfs2_debug_release(struct inode *inode, struct file *file)
> +{
> +	struct ocfs2_debug_buffer *odb =
> +			(struct ocfs2_debug_buffer *)file->private_data;
> +
> +	kfree(odb->buf);
> +	kfree(odb);
> +
> +	return 0;
> +}
> +
> +static ssize_t ocfs2_debug_read(struct file *file, char __user *buf,
> +				size_t nbytes, loff_t *ppos)
> +{
> +	struct ocfs2_debug_buffer *odb =
> +			(struct ocfs2_debug_buffer *)file->private_data;
> +
> +	return simple_read_from_buffer(buf, nbytes, ppos, odb->buf, odb->len);
> +}
> +
> +static loff_t ocfs2_debug_llseek(struct file *file, loff_t off, int whence)
> +{
> +	struct ocfs2_debug_buffer *odb =
> +			(struct ocfs2_debug_buffer *)file->private_data;
> +	loff_t new = -1;
> +
> +	switch (whence) {
> +	case 0:
> +		new = off;
> +		break;
> +	case 1:
> +		new = file->f_pos + off;
> +		break;
> +	}
> +
> +	if (new < 0 || new > odb->len)
> +		return -EINVAL;
> +
> +	return (file->f_pos = new);
> +}

Same comment regarding generic_file_llseek() here.
	--Mark

--
Mark Fasheh

  reply	other threads:[~2008-12-17  1:16 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-16 23:49 [Ocfs2-devel] Patches for the next merge window Sunil Mushran
2008-12-16 23:49 ` [Ocfs2-devel] [PATCH 1/9] ocfs2/hb: Exposes list of heartbeating nodes via debugfs Sunil Mushran
2008-12-17  1:08   ` Mark Fasheh
2008-12-17  9:03   ` tristan.ye
2008-12-17 18:52     ` Sunil Mushran
2008-12-16 23:49 ` [Ocfs2-devel] [PATCH 2/9] ocfs2: Moves struct recovery_map to a header file Sunil Mushran
2008-12-16 23:49 ` [Ocfs2-devel] [PATCH 3/9] ocfs2: Exposes the file system state via debugfs Sunil Mushran
2008-12-17  1:16   ` Mark Fasheh [this message]
2008-12-17 19:18     ` Sunil Mushran
2008-12-16 23:49 ` [Ocfs2-devel] [PATCH 4/9] ocfs2: Remove debugfs file local_alloc_stats Sunil Mushran
2008-12-16 23:49 ` [Ocfs2-devel] [PATCH 5/9] ocfs2/dlm: Fixes race between migrate request and exit domain Sunil Mushran
2008-12-16 23:49 ` [Ocfs2-devel] [PATCH 6/9] ocfs2/dlm: Clean errors in dlm_proxy_ast_handler() Sunil Mushran
2008-12-16 23:49 ` [Ocfs2-devel] [PATCH 7/9] ocfs2/dlm: Hold off sending lockres drop ref message while lockres is migrating Sunil Mushran
2008-12-16 23:49 ` [Ocfs2-devel] [PATCH 8/9] ocfs2/dlm: Fix race in adding/removing lockres' to/from the tracking list Sunil Mushran
2008-12-16 23:49 ` [Ocfs2-devel] [PATCH 9/9] ocfs2/dlm: Fix race during lockres mastery Sunil Mushran
2008-12-17  0:25   ` Mark Fasheh
2008-12-17  0:40     ` Sunil Mushran
2008-12-17  1:30   ` Mark Fasheh
2008-12-23 21:05   ` Coly Li
2008-12-23 21:06     ` Sunil Mushran
2008-12-17 22:17 [Ocfs2-devel] Patches for next merge window - 2 Sunil Mushran
2008-12-17 22:17 ` [Ocfs2-devel] [PATCH 3/9] ocfs2: Exposes the file system state via debugfs Sunil Mushran

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081217011601.GB8791@wotan.suse.de \
    --to=mfasheh@suse.com \
    --cc=ocfs2-devel@oss.oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.