xref: /haiku/src/add-ons/kernel/file_systems/bfs/Debug.cpp (revision 7120e97489acbf17d86d3f33e3b2e68974fd4b23)
1 /* Debug - debug stuff
2 **
3 ** Initial version by Axel Dörfler, axeld@pinc-software.de
4 ** Some code is based on work previously done by Marcus Overhagen
5 **
6 ** This file may be used under the terms of the OpenBeOS License.
7 */
8 
9 
10 #include "Debug.h"
11 #include "BPlusTree.h"
12 
13 #include <KernelExport.h>
14 
15 #include <time.h>
16 
17 #define Print __out
18 
19 
20 char *
21 get_tupel(uint32 id)
22 {
23 	static unsigned char tupel[5];
24 
25 	tupel[0] = 0xff & (id >> 24);
26 	tupel[1] = 0xff & (id >> 16);
27 	tupel[2] = 0xff & (id >> 8);
28 	tupel[3] = 0xff & (id);
29 	tupel[4] = 0;
30 	for (int16 i = 0;i < 4;i++)
31 		if (tupel[i] < ' ' || tupel[i] > 128)
32 			tupel[i] = '.';
33 
34 	return (char *)tupel;
35 }
36 
37 
38 void
39 dump_block_run(const char *prefix,block_run &run)
40 {
41 	Print("%s(%ld, %d, %d)\n",prefix,run.allocation_group,run.start,run.length);
42 }
43 
44 
45 void
46 dump_super_block(disk_super_block *superBlock)
47 {
48 	Print("disk_super_block:\n");
49 	Print("  name           = %s\n",superBlock->name);
50 	Print("  magic1         = %#08lx (%s) %s\n",superBlock->magic1, get_tupel(superBlock->magic1), (superBlock->magic1 == SUPER_BLOCK_MAGIC1 ? "valid" : "INVALID"));
51 	Print("  fs_byte_order  = %#08lx (%s)\n",superBlock->fs_byte_order, get_tupel(superBlock->fs_byte_order));
52 	Print("  block_size     = %lu\n",superBlock->block_size);
53 	Print("  block_shift    = %lu\n",superBlock->block_shift);
54 	Print("  num_blocks     = %Lu\n",superBlock->num_blocks);
55 	Print("  used_blocks    = %Lu\n",superBlock->used_blocks);
56 	Print("  inode_size     = %lu\n",superBlock->inode_size);
57 	Print("  magic2         = %#08lx (%s) %s\n",superBlock->magic2, get_tupel(superBlock->magic2), (superBlock->magic2 == (int)SUPER_BLOCK_MAGIC2 ? "valid" : "INVALID"));
58 	Print("  blocks_per_ag  = %lu\n",superBlock->blocks_per_ag);
59 	Print("  ag_shift       = %lu (%ld bytes)\n",superBlock->ag_shift, 1LL << superBlock->ag_shift);
60 	Print("  num_ags        = %lu\n",superBlock->num_ags);
61 	Print("  flags          = %#08lx (%s)\n",superBlock->flags, get_tupel(superBlock->flags));
62 	dump_block_run("  log_blocks     = ",superBlock->log_blocks);
63 	Print("  log_start      = %Lu\n",superBlock->log_start);
64 	Print("  log_end        = %Lu\n",superBlock->log_end);
65 	Print("  magic3         = %#08lx (%s) %s\n",superBlock->magic3, get_tupel(superBlock->magic3), (superBlock->magic3 == SUPER_BLOCK_MAGIC3 ? "valid" : "INVALID"));
66 	dump_block_run("  root_dir       = ",superBlock->root_dir);
67 	dump_block_run("  indices        = ",superBlock->indices);
68 }
69 
70 
71 void
72 dump_data_stream(data_stream *stream)
73 {
74 	Print("data_stream:\n");
75 	for (int i = 0; i < NUM_DIRECT_BLOCKS; i++) {
76 		if (!stream->direct[i].IsZero()) {
77 			Print("  direct[%02d]                = ",i);
78 			dump_block_run("",stream->direct[i]);
79 		}
80 	}
81 	Print("  max_direct_range          = %Lu\n",stream->max_direct_range);
82 
83 	if (!stream->indirect.IsZero())
84 		dump_block_run("  indirect                  = ",stream->indirect);
85 
86 	Print("  max_indirect_range        = %Lu\n",stream->max_indirect_range);
87 
88 	if (!stream->double_indirect.IsZero())
89 		dump_block_run("  double_indirect           = ",stream->double_indirect);
90 
91 	Print("  max_double_indirect_range = %Lu\n",stream->max_double_indirect_range);
92 	Print("  size                      = %Lu\n",stream->size);
93 }
94 
95 
96 void
97 dump_inode(bfs_inode *inode)
98 {
99 	Print("inode:\n");
100 	Print("  magic1             = %08lx (%s) %s\n",inode->magic1,
101 			get_tupel(inode->magic1), (inode->magic1 == INODE_MAGIC1 ? "valid" : "INVALID"));
102 	dump_block_run(	"  inode_num          = ",inode->inode_num);
103 	Print("  uid                = %lu\n",inode->uid);
104 	Print("  gid                = %lu\n",inode->gid);
105 	Print("  mode               = %08lx\n",inode->mode);
106 	Print("  flags              = %08lx\n",inode->flags);
107 	Print("  create_time        = %Ld (%Ld)\n",inode->create_time,inode->create_time >> INODE_TIME_SHIFT);
108 	Print("  last_modified_time = %Ld (%Ld)\n",inode->last_modified_time,inode->last_modified_time >> INODE_TIME_SHIFT);
109 	dump_block_run(	"  parent             = ",inode->parent);
110 	dump_block_run(	"  attributes         = ",inode->attributes);
111 	Print("  type               = %lu\n",inode->type);
112 	Print("  inode_size         = %lu\n",inode->inode_size);
113 	Print("  etc                = %#08lx\n",inode->etc);
114 	Print("  short_symlink      = %s\n",
115 			S_ISLNK(inode->mode) && (inode->flags & INODE_LONG_SYMLINK) == 0? inode->short_symlink : "-");
116 	dump_data_stream(&(inode->data));
117 	Print("  --\n  pad[0]             = %08lx\n",inode->pad[0]);
118 	Print("  pad[1]             = %08lx\n",inode->pad[1]);
119 	Print("  pad[2]             = %08lx\n",inode->pad[2]);
120 	Print("  pad[3]             = %08lx\n",inode->pad[3]);
121 }
122 
123 
124 void
125 dump_bplustree_header(bplustree_header *header)
126 {
127 	Print("bplustree_header:\n");
128 	Print("  magic                = %#08lx (%s) %s\n",header->magic,
129 			get_tupel(header->magic), (header->magic == BPLUSTREE_MAGIC ? "valid" : "INVALID"));
130 	Print("  node_size            = %lu\n",header->node_size);
131 	Print("  max_number_of_levels = %lu\n",header->max_number_of_levels);
132 	Print("  data_type            = %lu\n",header->data_type);
133 	Print("  root_node_pointer    = %Ld\n",header->root_node_pointer);
134 	Print("  free_node_pointer    = %Ld\n",header->free_node_pointer);
135 	Print("  maximum_size         = %Lu\n",header->maximum_size);
136 }
137 
138 
139 #define DUMPED_BLOCK_SIZE 16
140 
141 void
142 dump_block(const char *buffer,int size)
143 {
144 	for(int i = 0;i < size;) {
145 		int start = i;
146 
147 		for(;i < start+DUMPED_BLOCK_SIZE;i++) {
148 			if (!(i % 4))
149 				Print(" ");
150 
151 			if (i >= size)
152 				Print("  ");
153 			else
154 				Print("%02x",*(unsigned char *)(buffer+i));
155 		}
156 		Print("  ");
157 
158 		for(i = start;i < start + DUMPED_BLOCK_SIZE;i++) {
159 			if (i < size) {
160 				char c = *(buffer+i);
161 
162 				if (c < 30)
163 					Print(".");
164 				else
165 					Print("%c",c);
166 			}
167 			else
168 				break;
169 		}
170 		Print("\n");
171 	}
172 }
173 
174 
175 void
176 dump_bplustree_node(bplustree_node *node,bplustree_header *header,Volume *volume)
177 {
178 	Print("bplustree_node:\n");
179 	Print("  left_link      = %Ld\n",node->left_link);
180 	Print("  right_link     = %Ld\n",node->right_link);
181 	Print("  overflow_link  = %Ld\n",node->overflow_link);
182 	Print("  all_key_count  = %u\n",node->all_key_count);
183 	Print("  all_key_length = %u\n",node->all_key_length);
184 
185 	if (header == NULL)
186 		return;
187 
188 	if (node->all_key_count > node->all_key_length
189 		|| uint32(node->all_key_count * 10) > (uint32)header->node_size
190 		|| node->all_key_count == 0) {
191 		Print("\n");
192 		dump_block((char *)node,header->node_size/*,sizeof(off_t)*/);
193 		return;
194 	}
195 
196 	Print("\n");
197 	for (int32 i = 0;i < node->all_key_count;i++) {
198 		uint16 length;
199 		char buffer[256],*key = (char *)node->KeyAt(i,&length);
200 		if (length > 255 || length == 0) {
201 			Print("  %2ld. Invalid length (%u)!!\n",i,length);
202 			dump_block((char *)node,header->node_size/*,sizeof(off_t)*/);
203 			break;
204 		}
205 		memcpy(buffer,key,length);
206 		buffer[length] = '\0';
207 
208 		off_t *value = node->Values() + i;
209 		if ((uint32)value < (uint32)node || (uint32)value > (uint32)node + header->node_size)
210 			Print("  %2ld. Invalid Offset!!\n",i);
211 		else {
212 			Print("  %2ld. ",i);
213 			if (header->data_type == BPLUSTREE_STRING_TYPE)
214 				Print("\"%s\"",buffer);
215 			else if (header->data_type == BPLUSTREE_INT32_TYPE)
216 				Print("int32 = %ld (0x%lx)",*(int32 *)&buffer,*(int32 *)&buffer);
217 			else if (header->data_type == BPLUSTREE_UINT32_TYPE)
218 				Print("uint32 = %lu (0x%lx)",*(uint32 *)&buffer,*(uint32 *)&buffer);
219 			else if (header->data_type == BPLUSTREE_INT64_TYPE)
220 				Print("int64 = %Ld (0x%Lx)",*(int64 *)&buffer,*(int64 *)&buffer);
221 			else
222 				Print("???");
223 
224 			off_t offset = *value & 0x3fffffffffffffffLL;
225 			Print(" (%d bytes) -> %Ld",length,offset);
226 			if (volume != NULL)
227 			{
228 				block_run run = volume->ToBlockRun(offset);
229 				Print(" (%ld, %d)",run.allocation_group,run.start);
230 			}
231 			if (bplustree_node::LinkType(*value) == BPLUSTREE_DUPLICATE_FRAGMENT)
232 				Print(" (duplicate fragment %Ld)\n",*value & 0x3ff);
233 			else if (bplustree_node::LinkType(*value) == BPLUSTREE_DUPLICATE_NODE)
234 				Print(" (duplicate node)\n");
235 			else
236 				Print("\n");
237 		}
238 	}
239 }
240 
241 
242