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 #include <mdb/mdb_modapi.h>
27 #include <sys/types.h>
28 #include <sys/sysmacros.h>
30 #include <sys/vnode.h>
31 #include <sys/fs/snode.h>
33 typedef struct snode_walk_data
{
39 snode_walk_init(mdb_walk_state_t
*wsp
)
45 snode_walk_data_t
*sw
;
47 if (mdb_readvar(&stablesz
, "stablesz") == -1) {
48 mdb_warn("failed to read 'stablesz'");
55 if (mdb_lookup_by_name("stable", &sym
) == -1) {
56 mdb_warn("failed to read 'stable'");
60 stable
= (uintptr_t)sym
.st_value
;
62 if (mdb_vread(&sp
, sizeof (sp
), stable
) == -1) {
63 mdb_warn("failed to read stable entry at %p", stable
);
67 sw
= mdb_alloc(sizeof (snode_walk_data_t
), UM_SLEEP
);
68 sw
->sw_stablesz
= stablesz
;
69 sw
->sw_stable
= stable
;
78 snode_walk_step(mdb_walk_state_t
*wsp
)
80 uintptr_t addr
= wsp
->walk_addr
;
81 snode_walk_data_t
*sw
= wsp
->walk_data
;
85 while (addr
== (uintptr_t)NULL
) {
86 if (--sw
->sw_stablesz
== 0)
89 sw
->sw_stable
+= sizeof (struct snode
*);
91 if (mdb_vread(&sp
, sizeof (sp
), sw
->sw_stable
) == -1) {
92 mdb_warn("failed to read stable entry at %p",
99 if (mdb_vread(&snode
, sizeof (snode
), addr
) == -1) {
100 mdb_warn("failed to read snode at %p", addr
);
104 wsp
->walk_addr
= (uintptr_t)snode
.s_next
;
106 return (wsp
->walk_callback(addr
, &snode
, wsp
->walk_cbdata
));
110 snode_walk_fini(mdb_walk_state_t
*wsp
)
112 mdb_free(wsp
->walk_data
, sizeof (snode_walk_data_t
));
115 typedef struct snode_cbdata
{
122 snode_cb(uintptr_t addr
, const struct snode
*snode
, snode_cbdata_t
*sd
)
124 static const mdb_bitmask_t s_flag_masks
[] = {
125 { "UPD", SUPD
, SUPD
},
126 { "ACC", SACC
, SACC
},
127 { "CHG", SCHG
, SCHG
},
128 { "PRIV", SPRIV
, SPRIV
},
129 { "LOFFSET", SLOFFSET
, SLOFFSET
},
130 { "LOCKED", SLOCKED
, SLOCKED
},
131 { "WANT", SWANT
, SWANT
},
132 { "CLONE", SCLONE
, SCLONE
},
133 { "NEEDCLOSE", SNEEDCLOSE
, SNEEDCLOSE
},
134 { "DIPSET", SDIPSET
, SDIPSET
},
135 { "SIZEVALID", SSIZEVALID
, SSIZEVALID
},
136 { "MUXED", SMUXED
, SMUXED
},
137 { "SELFCLONE", SSELFCLONE
, SSELFCLONE
},
138 { "NOFLUSH", SNOFLUSH
, SNOFLUSH
},
139 { "CLOSING", SCLOSING
, SCLOSING
},
143 int major
= getmajor(snode
->s_dev
);
144 int minor
= getminor(snode
->s_dev
);
146 if (sd
->sd_major
!= -1 && sd
->sd_major
!= major
)
149 if (sd
->sd_minor
!= -1 && sd
->sd_minor
!= minor
)
152 if (sd
->sd_verbose
) {
153 mdb_printf("%0?p %?p %6d %16lx <%b>\n",
154 addr
, snode
->s_vnode
, snode
->s_count
, snode
->s_dev
,
155 snode
->s_flag
, s_flag_masks
);
157 mdb_printf("%p\n", addr
);
165 snode(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
169 uintptr_t major
= 0, dev
= 0;
173 sd
.sd_verbose
= !(flags
& DCMD_PIPE_OUT
);
175 if (mdb_getopts(argc
, argv
,
176 'm', MDB_OPT_UINTPTR
, &major
,
177 'd', MDB_OPT_UINTPTR
, &dev
, NULL
) != argc
)
181 sd
.sd_major
= getmajor(dev
);
182 sd
.sd_minor
= getminor(dev
);
188 if (DCMD_HDRSPEC(flags
) && !(flags
& DCMD_PIPE_OUT
)) {
189 mdb_printf("%<u>%?s %?s %6s %16s %-15s%</u>\n",
190 "ADDR", "VNODE", "COUNT", "DEV", "FLAG");
193 if (!(flags
& DCMD_ADDRSPEC
)) {
194 if (mdb_walk("snode", (mdb_walk_cb_t
)snode_cb
, &sd
) == -1) {
195 mdb_warn("can't walk snodes");
201 if (mdb_vread(&snode
, sizeof (snode
), addr
) == -1) {
202 mdb_warn("failed to read snode structure at %p", addr
);
206 snode_cb(addr
, &snode
, &sd
);
213 major2snode(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
217 if (!(flags
& DCMD_ADDRSPEC
) || argc
!= 0)
224 if (mdb_pwalk("snode", (mdb_walk_cb_t
)snode_cb
, &sd
, 0) != 0)
232 dev2snode(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
236 if (!(flags
& DCMD_ADDRSPEC
) || argc
!= 0)
239 sd
.sd_major
= getmajor(addr
);
240 sd
.sd_minor
= getminor(addr
);
243 if (mdb_pwalk("snode", (mdb_walk_cb_t
)snode_cb
, &sd
, 0) != 0)
252 mdb_printf("Options:\n"
253 " -d device filter snodes of the specified dev_t\n"
254 " -m major filter snodes of the specified major number\n");
260 static const mdb_dcmd_t dcmds
[] = {
261 { "dev2snode", ":", "given a dev_t, return the snode", dev2snode
},
262 { "major2snode", ":", "given a major number, return the snode(s)",
264 { "snode", "?[-d device] [-m major]",
265 "filter and display snode structures", snode
, snode_help
},
269 static const mdb_walker_t walkers
[] = {
270 { "snode", "walk global snode lists",
271 snode_walk_init
, snode_walk_step
, snode_walk_fini
},
275 static const mdb_modinfo_t modinfo
= { MDB_API_VERSION
, dcmds
, walkers
};
277 const mdb_modinfo_t
*