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