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.5 2008/02/08 08:30:56 dillon Exp $
39 #define FLAG_TOOFARLEFT 0x0001
40 #define FLAG_TOOFARRIGHT 0x0002
41 #define FLAG_BADTYPE 0x0004
43 static void print_btree_node(hammer_off_t node_offset
, int depth
, int spike
,
44 hammer_base_elm_t left_bound
,
45 hammer_base_elm_t right_bound
);
46 static void print_btree_elm(hammer_btree_elm_t elm
, int i
, u_int8_t type
,
47 int flags
, const char *label
);
48 static int print_elm_flags(hammer_node_ondisk_t node
, hammer_btree_elm_t elm
,
49 u_int8_t btype
, hammer_base_elm_t left_bound
,
50 hammer_base_elm_t right_bound
);
53 hammer_cmd_show(hammer_off_t node_offset
, int depth
,
54 hammer_base_elm_t left_bound
, hammer_base_elm_t right_bound
)
56 struct volume_info
*volume
;
58 if (node_offset
== (hammer_off_t
)-1) {
59 volume
= get_volume(RootVolNo
);
60 node_offset
= volume
->ondisk
->vol0_btree_root
;
62 printf("\trecords=%lld\n",
63 volume
->ondisk
->vol0_stat_records
);
67 printf("show %016llx depth %d\n", node_offset
, depth
);
68 print_btree_node(node_offset
, depth
, 0, left_bound
, right_bound
);
69 print_btree_node(node_offset
, depth
, 1, left_bound
, right_bound
);
73 print_btree_node(hammer_off_t node_offset
, int depth
, int spike
,
74 hammer_base_elm_t left_bound
, hammer_base_elm_t right_bound
)
76 struct buffer_info
*buffer
= NULL
;
77 hammer_node_ondisk_t node
;
78 hammer_btree_elm_t elm
;
82 node
= get_node(node_offset
, &buffer
);
85 printf(" NODE %016llx count=%d parent=%016llx "
86 "type=%c depth=%d {\n",
87 node_offset
, node
->count
, node
->parent
,
88 (node
->type
? node
->type
: '?'), depth
);
90 for (i
= 0; i
< node
->count
; ++i
) {
92 flags
= print_elm_flags(node
, elm
, elm
->base
.btype
,
93 left_bound
, right_bound
);
94 print_btree_elm(elm
, i
, node
->type
, flags
, "ELM");
96 if (node
->type
== HAMMER_BTREE_TYPE_INTERNAL
) {
98 flags
= print_elm_flags(node
, elm
, 'I',
99 left_bound
, right_bound
);
100 print_btree_elm(elm
, i
, node
->type
, flags
, "RBN");
105 for (i
= 0; i
< node
->count
; ++i
) {
106 elm
= &node
->elms
[i
];
109 case HAMMER_BTREE_TYPE_INTERNAL
:
110 if (elm
->internal
.subtree_offset
) {
111 print_btree_node(elm
->internal
.subtree_offset
,
113 &elm
[0].base
, &elm
[1].base
);
125 print_btree_elm(hammer_btree_elm_t elm
, int i
, u_int8_t type
,
126 int flags
, const char *label
)
128 char flagstr
[8] = { 0, '-', '-', '-', '-', '-', '-', 0 };
130 flagstr
[0] = flags
? 'B' : 'G';
131 if (flags
& FLAG_TOOFARLEFT
)
133 if (flags
& FLAG_TOOFARRIGHT
)
135 if (flags
& FLAG_BADTYPE
)
138 printf("%s\t%s %2d %c ",
140 (elm
->base
.btype
? elm
->base
.btype
: '?'));
141 printf("obj=%016llx key=%016llx rt=%02x ot=%02x\n",
146 printf("\t tids %016llx:%016llx ",
147 elm
->base
.create_tid
,
148 elm
->base
.delete_tid
);
151 case HAMMER_BTREE_TYPE_INTERNAL
:
152 printf("suboff=%016llx", elm
->internal
.subtree_offset
);
154 case HAMMER_BTREE_TYPE_LEAF
:
155 switch(elm
->base
.btype
) {
156 case HAMMER_BTREE_TYPE_RECORD
:
157 printf("recoff=%016llx", elm
->leaf
.rec_offset
);
169 print_elm_flags(hammer_node_ondisk_t node
, hammer_btree_elm_t elm
,
171 hammer_base_elm_t left_bound
, hammer_base_elm_t right_bound
)
176 case HAMMER_BTREE_TYPE_INTERNAL
:
178 case HAMMER_BTREE_TYPE_INTERNAL
:
179 if (left_bound
== NULL
|| right_bound
== NULL
)
181 if (hammer_btree_cmp(&elm
->base
, left_bound
) < 0)
182 flags
|= FLAG_TOOFARLEFT
;
183 if (hammer_btree_cmp(&elm
->base
, right_bound
) > 0)
184 flags
|= FLAG_TOOFARRIGHT
;
186 case HAMMER_BTREE_TYPE_LEAF
:
187 if (left_bound
== NULL
|| right_bound
== NULL
)
189 if (hammer_btree_cmp(&elm
->base
, left_bound
) < 0)
190 flags
|= FLAG_TOOFARLEFT
;
191 if (hammer_btree_cmp(&elm
->base
, right_bound
) >= 0)
192 flags
|= FLAG_TOOFARRIGHT
;
195 flags
|= FLAG_BADTYPE
;
199 case HAMMER_BTREE_TYPE_LEAF
:
201 case HAMMER_BTREE_TYPE_RECORD
:
202 if (left_bound
== NULL
|| right_bound
== NULL
)
204 if (hammer_btree_cmp(&elm
->base
, left_bound
) < 0)
205 flags
|= FLAG_TOOFARLEFT
;
206 if (hammer_btree_cmp(&elm
->base
, right_bound
) >= 0)
207 flags
|= FLAG_TOOFARRIGHT
;
210 flags
|= FLAG_BADTYPE
;
215 flags
|= FLAG_BADTYPE
;