2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sbin/hammer/cmd_show.c,v 1.4 2008/01/25 05:53:41 dillon Exp $
39 #define FLAG_TOOFARLEFT 0x0001
40 #define FLAG_TOOFARRIGHT 0x0002
41 #define FLAG_BADTYPE 0x0004
43 static void print_btree_node(struct cluster_info
*cluster
,
44 int32_t node_offset
, int depth
, int spike
,
45 hammer_base_elm_t left_bound
,
46 hammer_base_elm_t right_bound
);
47 static void print_btree_elm(hammer_btree_elm_t elm
, int i
, u_int8_t type
,
48 int flags
, const char *label
);
49 static int print_elm_flags(hammer_node_ondisk_t node
, hammer_btree_elm_t elm
,
50 u_int8_t btype
, hammer_base_elm_t left_bound
,
51 hammer_base_elm_t right_bound
);
54 hammer_cmd_show(int32_t vol_no
, int32_t clu_no
, int depth
)
56 struct volume_info
*volume
;
57 struct cluster_info
*cluster
;
62 errx(1, "hammer show: root volume number unknown");
65 volume
= get_volume(vol_no
);
67 errx(1, "hammer show: Unable to locate volume %d", vol_no
);
69 clu_no
= volume
->ondisk
->vol0_root_clu_no
;
70 cluster
= get_cluster(volume
, clu_no
, 0);
71 printf("show %d:%d root@%08x parent@%d:%d:%08x depth %d\n",
73 cluster
->ondisk
->clu_btree_root
,
74 cluster
->ondisk
->clu_btree_parent_vol_no
,
75 cluster
->ondisk
->clu_btree_parent_clu_no
,
76 cluster
->ondisk
->clu_btree_parent_offset
,
79 printf("\trecords=%d\n",
80 cluster
->ondisk
->stat_records
);
82 node_offset
= cluster
->ondisk
->clu_btree_root
;
83 print_btree_node(cluster
, node_offset
, depth
, 0,
84 &cluster
->ondisk
->clu_btree_beg
,
85 &cluster
->ondisk
->clu_btree_end
);
86 print_btree_node(cluster
, node_offset
, depth
, 1,
87 &cluster
->ondisk
->clu_btree_beg
,
88 &cluster
->ondisk
->clu_btree_end
);
94 print_btree_node(struct cluster_info
*cluster
, int32_t node_offset
, int depth
,
96 hammer_base_elm_t left_bound
, hammer_base_elm_t right_bound
)
98 struct buffer_info
*buffer
= NULL
;
99 hammer_node_ondisk_t node
;
100 hammer_btree_elm_t elm
;
104 node
= get_node(cluster
, node_offset
, &buffer
);
107 printf(" NODE %d:%d:%08x count=%d parent=%08x "
108 "type=%c depth=%d {\n",
109 cluster
->volume
->vol_no
,
111 node_offset
, node
->count
, node
->parent
,
112 (node
->type
? node
->type
: '?'),
115 for (i
= 0; i
< node
->count
; ++i
) {
116 elm
= &node
->elms
[i
];
117 flags
= print_elm_flags(node
, elm
, elm
->base
.btype
,
118 left_bound
, right_bound
);
119 print_btree_elm(elm
, i
, node
->type
, flags
, "ELM");
121 if (node
->type
== HAMMER_BTREE_TYPE_INTERNAL
) {
122 elm
= &node
->elms
[i
];
123 flags
= print_elm_flags(node
, elm
, 'I',
124 left_bound
, right_bound
);
125 print_btree_elm(elm
, i
, node
->type
, flags
, "RBN");
130 for (i
= 0; i
< node
->count
; ++i
) {
131 elm
= &node
->elms
[i
];
134 case HAMMER_BTREE_TYPE_INTERNAL
:
135 if (elm
->internal
.subtree_offset
) {
136 print_btree_node(cluster
,
137 elm
->internal
.subtree_offset
,
139 &elm
[0].base
, &elm
[1].base
);
142 case HAMMER_BTREE_TYPE_LEAF
:
143 if (RecurseOpt
&& spike
&&
144 elm
->leaf
.base
.btype
== HAMMER_BTREE_TYPE_SPIKE_END
) {
145 hammer_cmd_show(elm
->leaf
.spike_vol_no
,
146 elm
->leaf
.spike_clu_no
,
157 print_btree_elm(hammer_btree_elm_t elm
, int i
, u_int8_t type
,
158 int flags
, const char *label
)
160 char flagstr
[8] = { 0, '-', '-', '-', '-', '-', '-', 0 };
162 flagstr
[0] = flags
? 'B' : 'G';
163 if (flags
& FLAG_TOOFARLEFT
)
165 if (flags
& FLAG_TOOFARRIGHT
)
167 if (flags
& FLAG_BADTYPE
)
170 printf("%s\t%s %2d %c ",
172 (elm
->base
.btype
? elm
->base
.btype
: '?'));
173 printf("obj=%016llx key=%016llx rt=%02x ot=%02x\n",
178 printf("\t tids %016llx:%016llx ",
179 elm
->base
.create_tid
,
180 elm
->base
.delete_tid
);
183 case HAMMER_BTREE_TYPE_INTERNAL
:
184 printf("suboff=%08x", elm
->internal
.subtree_offset
);
186 case HAMMER_BTREE_TYPE_LEAF
:
187 switch(elm
->base
.btype
) {
188 case HAMMER_BTREE_TYPE_RECORD
:
189 printf("recoff=%08x", elm
->leaf
.rec_offset
);
191 case HAMMER_BTREE_TYPE_SPIKE_BEG
:
192 case HAMMER_BTREE_TYPE_SPIKE_END
:
193 printf("spike %d:%d",
194 elm
->leaf
.spike_vol_no
,
195 elm
->leaf
.spike_clu_no
);
207 print_elm_flags(hammer_node_ondisk_t node
, hammer_btree_elm_t elm
,
209 hammer_base_elm_t left_bound
, hammer_base_elm_t right_bound
)
214 case HAMMER_BTREE_TYPE_INTERNAL
:
216 case HAMMER_BTREE_TYPE_INTERNAL
:
217 if (hammer_btree_cmp(&elm
->base
, left_bound
) < 0)
218 flags
|= FLAG_TOOFARLEFT
;
219 if (hammer_btree_cmp(&elm
->base
, right_bound
) > 0)
220 flags
|= FLAG_TOOFARRIGHT
;
222 case HAMMER_BTREE_TYPE_LEAF
:
223 if (hammer_btree_cmp(&elm
->base
, left_bound
) < 0)
224 flags
|= FLAG_TOOFARLEFT
;
225 if (hammer_btree_cmp(&elm
->base
, right_bound
) >= 0)
226 flags
|= FLAG_TOOFARRIGHT
;
229 flags
|= FLAG_BADTYPE
;
233 case HAMMER_BTREE_TYPE_LEAF
:
235 case HAMMER_BTREE_TYPE_SPIKE_END
:
236 if (hammer_btree_cmp(&elm
->base
, left_bound
) < 0)
237 flags
|= FLAG_TOOFARLEFT
;
238 if (hammer_btree_cmp(&elm
->base
, right_bound
) > 0)
239 flags
|= FLAG_TOOFARRIGHT
;
241 case HAMMER_BTREE_TYPE_SPIKE_BEG
:
242 case HAMMER_BTREE_TYPE_RECORD
:
243 if (hammer_btree_cmp(&elm
->base
, left_bound
) < 0)
244 flags
|= FLAG_TOOFARLEFT
;
245 if (hammer_btree_cmp(&elm
->base
, right_bound
) >= 0)
246 flags
|= FLAG_TOOFARRIGHT
;
249 flags
|= FLAG_BADTYPE
;
254 flags
|= FLAG_BADTYPE
;