Add the ffs structures introspection functions for ddb.

Show the b_dep value for the buffer in the show buffer command.
Add a comand to dump the dirty/clean buffer list for vnode.

Reviewed by:	tegge
Tested and used by:   pho
MFC after:   1 month
This commit is contained in:
kib 2008-09-16 11:19:38 +00:00
parent 039c5da1b2
commit 0488506405
4 changed files with 110 additions and 3 deletions

View File

@ -610,6 +610,13 @@ See the
header file for more details on the exact meaning of the structure fields.
.\"
.Pp
.It Ic show Cm ffs Op Ar addr
Show brief information about ffs mount at the address
.Ar addr ,
if argument is given.
Otherwise, provides the summary about each ffs mount.
.\"
.Pp
.It Ic show Cm file Ar addr
Show information about the file structure
.Vt struct file
@ -642,6 +649,14 @@ The second one is the name of the interrupt/trap handler.
Those functions are machine dependent.
.\"
.Pp
.It Ic show Cm inodedeps Op Ar addr
Show brief information about each inodedep structure.
If
.Ar addr
is given, only inodedeps belonging to the fs located at the
supplied address are shown.
.\"
.Pp
.It Ic show Cm inpcb Ar addr
Show information on IP Control Block
.Vt struct in_pcb
@ -1019,6 +1034,11 @@ For the exact interpretation of the output, look at the
header file.
.\"
.Pp
.It Ic show Cm vnodebufs Ar addr
Shows clean/dirty buffer lists of the vnode located at
.Ar addr .
.\"
.Pp
.It Ic show Cm watches
Displays all watchpoints.
Shows watchpoints set with "watch" command.

View File

@ -3903,9 +3903,10 @@ DB_SHOW_COMMAND(buffer, db_show_buffer)
db_printf("b_flags = 0x%b\n", (u_int)bp->b_flags, PRINT_BUF_FLAGS);
db_printf(
"b_error = %d, b_bufsize = %ld, b_bcount = %ld, b_resid = %ld\n"
"b_bufobj = (%p), b_data = %p, b_blkno = %jd\n",
"b_bufobj = (%p), b_data = %p, b_blkno = %jd, b_dep = %p\n",
bp->b_error, bp->b_bufsize, bp->b_bcount, bp->b_resid,
bp->b_bufobj, bp->b_data, (intmax_t)bp->b_blkno);
bp->b_bufobj, bp->b_data, (intmax_t)bp->b_blkno,
bp->b_dep.lh_first);
if (bp->b_npages) {
int i;
db_printf("b_npages = %d, pages(OBJ, IDX, PA): ", bp->b_npages);
@ -3935,4 +3936,26 @@ DB_SHOW_COMMAND(lockedbufs, lockedbufs)
}
}
}
DB_SHOW_COMMAND(vnodebufs, db_show_vnodebufs)
{
struct vnode *vp;
struct buf *bp;
if (!have_addr) {
db_printf("usage: show vnodebufs <addr>\n");
return;
}
vp = (struct vnode *)addr;
db_printf("Clean buffers:\n");
TAILQ_FOREACH(bp, &vp->v_bufobj.bo_clean.bv_hd, b_bobufs) {
db_show_buffer((uintptr_t)bp, 1, 0, NULL);
db_printf("\n");
}
db_printf("Dirty buffers:\n");
TAILQ_FOREACH(bp, &vp->v_bufobj.bo_dirty.bv_hd, b_bobufs) {
db_show_buffer((uintptr_t)bp, 1, 0, NULL);
db_printf("\n");
}
}
#endif /* DDB */

View File

@ -41,6 +41,9 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_ffs.h"
#include "opt_ddb.h"
/*
* For now we want the safety net that the DEBUG flag provides.
*/
@ -77,7 +80,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include "opt_ffs.h"
#include <ddb/ddb.h>
#ifndef SOFTUPDATES
@ -6334,4 +6337,30 @@ softdep_error(func, error)
printf("%s: got error %d while accessing filesystem\n", func, error);
}
#ifdef DDB
DB_SHOW_COMMAND(inodedeps, db_show_inodedeps)
{
struct inodedep_hashhead *inodedephd;
struct inodedep *inodedep;
struct fs *fs;
int cnt;
fs = have_addr ? (struct fs *)addr : NULL;
for (cnt = 0; cnt < inodedep_hash; cnt++) {
inodedephd = &inodedep_hashtbl[cnt];
LIST_FOREACH(inodedep, inodedephd, id_hash) {
if (fs != NULL && fs != inodedep->id_fs)
continue;
db_printf("%p fs %p st %x ino %jd inoblk %jd\n",
inodedep, inodedep->id_fs, inodedep->id_state,
(intmax_t)inodedep->id_ino,
(intmax_t)fsbtodb(inodedep->id_fs,
ino_to_fsba(inodedep->id_fs, inodedep->id_ino)));
}
}
}
#endif /* DDB */
#endif /* SOFTUPDATES */

View File

@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include "opt_quota.h"
#include "opt_ufs.h"
#include "opt_ffs.h"
#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -71,6 +72,8 @@ __FBSDID("$FreeBSD$");
#include <geom/geom.h>
#include <geom/geom_vfs.h>
#include <ddb/ddb.h>
static uma_zone_t uma_inode, uma_ufs1, uma_ufs2;
static int ffs_reload(struct mount *, struct thread *);
@ -1863,3 +1866,35 @@ ffs_geom_strategy(struct bufobj *bo, struct buf *bp)
}
g_vfs_strategy(bo, bp);
}
#ifdef DDB
static void
db_print_ffs(struct ufsmount *ump)
{
db_printf("mp %p %s devvp %p fs %p su_wl %d su_wl_in %d su_deps %d "
"su_req %d\n",
ump->um_mountp, ump->um_mountp->mnt_stat.f_mntonname,
ump->um_devvp, ump->um_fs, ump->softdep_on_worklist,
ump->softdep_on_worklist_inprogress, ump->softdep_deps,
ump->softdep_req);
}
DB_SHOW_COMMAND(ffs, db_show_ffs)
{
struct mount *mp;
struct ufsmount *ump;
if (have_addr) {
ump = VFSTOUFS((struct mount *)addr);
db_print_ffs(ump);
return;
}
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
if (!strcmp(mp->mnt_stat.f_fstypename, ufs_vfsconf.vfc_name))
db_print_ffs(VFSTOUFS(mp));
}
}
#endif /* DDB */