4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <mdb/mdb_modapi.h>
29 #include <sys/types.h>
30 #include <sys/sysmacros.h>
32 #include <sys/vnode.h>
33 #include <sys/fs/snode.h>
35 typedef struct snode_walk_data
{
41 snode_walk_init(mdb_walk_state_t
*wsp
)
47 snode_walk_data_t
*sw
;
49 if (mdb_readvar(&stablesz
, "stablesz") == -1) {
50 mdb_warn("failed to read 'stablesz'");
57 if (mdb_lookup_by_name("stable", &sym
) == -1) {
58 mdb_warn("failed to read 'stable'");
62 stable
= (uintptr_t)sym
.st_value
;
64 if (mdb_vread(&sp
, sizeof (sp
), stable
) == -1) {
65 mdb_warn("failed to read stable entry at %p", stable
);
69 sw
= mdb_alloc(sizeof (snode_walk_data_t
), UM_SLEEP
);
70 sw
->sw_stablesz
= stablesz
;
71 sw
->sw_stable
= stable
;
80 snode_walk_step(mdb_walk_state_t
*wsp
)
82 uintptr_t addr
= wsp
->walk_addr
;
83 snode_walk_data_t
*sw
= wsp
->walk_data
;
87 while (addr
== NULL
) {
88 if (--sw
->sw_stablesz
== 0)
91 sw
->sw_stable
+= sizeof (struct snode
*);
93 if (mdb_vread(&sp
, sizeof (sp
), sw
->sw_stable
) == -1) {
94 mdb_warn("failed to read stable entry at %p",
101 if (mdb_vread(&snode
, sizeof (snode
), addr
) == -1) {
102 mdb_warn("failed to read snode at %p", addr
);
106 wsp
->walk_addr
= (uintptr_t)snode
.s_next
;
108 return (wsp
->walk_callback(addr
, &snode
, wsp
->walk_cbdata
));
112 snode_walk_fini(mdb_walk_state_t
*wsp
)
114 mdb_free(wsp
->walk_data
, sizeof (snode_walk_data_t
));
117 typedef struct snode_cbdata
{
124 snode_cb(uintptr_t addr
, const struct snode
*snode
, snode_cbdata_t
*sd
)
126 static const mdb_bitmask_t s_flag_masks
[] = {
127 { "UPD", SUPD
, SUPD
},
128 { "ACC", SACC
, SACC
},
129 { "CHG", SCHG
, SCHG
},
130 { "PRIV", SPRIV
, SPRIV
},
131 { "LOFFSET", SLOFFSET
, SLOFFSET
},
132 { "LOCKED", SLOCKED
, SLOCKED
},
133 { "WANT", SWANT
, SWANT
},
134 { "CLONE", SCLONE
, SCLONE
},
135 { "NEEDCLOSE", SNEEDCLOSE
, SNEEDCLOSE
},
136 { "DIPSET", SDIPSET
, SDIPSET
},
137 { "SIZEVALID", SSIZEVALID
, SSIZEVALID
},
138 { "MUXED", SMUXED
, SMUXED
},
139 { "SELFCLONE", SSELFCLONE
, SSELFCLONE
},
140 { "NOFLUSH", SNOFLUSH
, SNOFLUSH
},
141 { "CLOSING", SCLOSING
, SCLOSING
},
145 int major
= getmajor(snode
->s_dev
);
146 int minor
= getminor(snode
->s_dev
);
148 if (sd
->sd_major
!= -1 && sd
->sd_major
!= major
)
151 if (sd
->sd_minor
!= -1 && sd
->sd_minor
!= minor
)
154 if (sd
->sd_verbose
) {
155 mdb_printf("%0?p %?p %6d %16lx <%b>\n",
156 addr
, snode
->s_vnode
, snode
->s_count
, snode
->s_dev
,
157 snode
->s_flag
, s_flag_masks
);
159 mdb_printf("%p\n", addr
);
167 snode(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
171 uintptr_t major
= 0, dev
= 0;
175 sd
.sd_verbose
= !(flags
& DCMD_PIPE_OUT
);
177 if (mdb_getopts(argc
, argv
,
178 'm', MDB_OPT_UINTPTR
, &major
,
179 'd', MDB_OPT_UINTPTR
, &dev
, NULL
) != argc
)
183 sd
.sd_major
= getmajor(dev
);
184 sd
.sd_minor
= getminor(dev
);
190 if (DCMD_HDRSPEC(flags
) && !(flags
& DCMD_PIPE_OUT
)) {
191 mdb_printf("%<u>%?s %?s %6s %16s %-15s%</u>\n",
192 "ADDR", "VNODE", "COUNT", "DEV", "FLAG");
195 if (!(flags
& DCMD_ADDRSPEC
)) {
196 if (mdb_walk("snode", (mdb_walk_cb_t
)snode_cb
, &sd
) == -1) {
197 mdb_warn("can't walk snodes");
203 if (mdb_vread(&snode
, sizeof (snode
), addr
) == -1) {
204 mdb_warn("failed to read snode structure at %p", addr
);
208 snode_cb(addr
, &snode
, &sd
);
215 major2snode(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
219 if (!(flags
& DCMD_ADDRSPEC
) || argc
!= 0)
226 if (mdb_pwalk("snode", (mdb_walk_cb_t
)snode_cb
, &sd
, 0) != 0)
234 dev2snode(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
238 if (!(flags
& DCMD_ADDRSPEC
) || argc
!= 0)
241 sd
.sd_major
= getmajor(addr
);
242 sd
.sd_minor
= getminor(addr
);
245 if (mdb_pwalk("snode", (mdb_walk_cb_t
)snode_cb
, &sd
, 0) != 0)
254 mdb_printf("Options:\n"
255 " -d device filter snodes of the specified dev_t\n"
256 " -m major filter snodes of the specified major number\n");
262 static const mdb_dcmd_t dcmds
[] = {
263 { "dev2snode", ":", "given a dev_t, return the snode", dev2snode
},
264 { "major2snode", ":", "given a major number, return the snode(s)",
266 { "snode", "?[-d device] [-m major]",
267 "filter and display snode structures", snode
, snode_help
},
271 static const mdb_walker_t walkers
[] = {
272 { "snode", "walk global snode lists",
273 snode_walk_init
, snode_walk_step
, snode_walk_fini
},
277 static const mdb_modinfo_t modinfo
= { MDB_API_VERSION
, dcmds
, walkers
};
279 const mdb_modinfo_t
*