Changeset ad34feb in mainline
- Timestamp:
- 2011-02-23T23:07:28Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 102d400
- Parents:
- a54af66
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/ext2info/ext2info.c
ra54af66 rad34feb 56 56 static void print_block_groups(ext2_filesystem_t *); 57 57 static void print_block_group(ext2_block_group_t *); 58 static void print_inode_by_number(ext2_filesystem_t *, uint32_t );58 static void print_inode_by_number(ext2_filesystem_t *, uint32_t, bool, uint32_t); 59 59 static void print_inode(ext2_filesystem_t *, ext2_inode_t *); 60 static void print_inode_data(ext2_filesystem_t *, ext2_inode_t *, uint32_t); 60 61 61 62 #define ARG_SUPERBLOCK 1 … … 63 64 #define ARG_INODE 4 64 65 #define ARG_STRICT_CHECK 8 66 #define ARG_INODE_DATA 16 65 67 #define ARG_COMMON (ARG_SUPERBLOCK | ARG_BLOCK_GROUPS) 66 68 #define ARG_ALL (ARG_COMMON | ARG_INODE) … … 77 79 int arg_flags; 78 80 uint32_t inode = 0; 81 uint32_t inode_data = 0; 79 82 80 83 arg_flags = 0; … … 120 123 arg_flags |= ARG_INODE; 121 124 --argc; ++argv; 125 126 if (str_cmp(*argv, "--inode-data") == 0) { 127 --argc; ++argv; 128 if (argc == 0) { 129 printf(NAME ": Argument expected for --inode-data\n"); 130 return 2; 131 } 132 133 inode_data = strtol(*argv, &endptr, 10); 134 if (*endptr != '\0') { 135 printf(NAME ": Error, invalid argument for --inode-data.\n"); 136 syntax_print(); 137 return 1; 138 } 139 140 arg_flags |= ARG_INODE_DATA; 141 --argc; ++argv; 142 } 122 143 } 123 144 … … 164 185 165 186 if (arg_flags & ARG_INODE) { 166 print_inode_by_number(&filesystem, inode); 187 print_inode_by_number(&filesystem, inode, arg_flags & ARG_INODE_DATA, 188 inode_data); 167 189 } 168 190 … … 175 197 static void syntax_print(void) 176 198 { 177 printf("syntax: ext2info --strict-check --superblock --block-groups --inode <i-number> <device_name>\n"); 199 printf("syntax: ext2info [--strict-check] [--superblock] [--block-groups] " 200 "[--inode <i-number> [--inode-data <block-number>]] <device_name>\n"); 178 201 } 179 202 … … 322 345 } 323 346 324 void print_inode_by_number(ext2_filesystem_t *fs, uint32_t inode) 347 void print_inode_by_number(ext2_filesystem_t *fs, uint32_t inode, 348 bool print_data, uint32_t data) 325 349 { 326 350 int rc; … … 336 360 337 361 print_inode(fs, inode_ref->inode); 362 if (print_data) { 363 print_inode_data(fs, inode_ref->inode, data); 364 } 338 365 339 366 rc = ext2_filesystem_put_inode_ref(inode_ref); … … 355 382 const char *type; 356 383 uint32_t block; 384 uint32_t total_blocks; 357 385 int i; 358 386 bool all_blocks = false; … … 365 393 usage_count = ext2_inode_get_usage_count(inode); 366 394 flags = ext2_inode_get_flags(inode); 395 total_blocks = ext2_inode_get_reserved_blocks(fs->superblock, inode); 367 396 368 397 type = "Unknown"; … … 390 419 391 420 access = mode & EXT2_INODE_MODE_ACCESS_MASK; 421 392 422 393 423 printf(" Mode: %08x (Type: %s, Access bits: %04ho)\n", mode, type, access); … … 397 427 printf(" Usage (link) count: %u\n", usage_count); 398 428 printf(" Flags: %u\n", flags); 429 printf(" Total allocated blocks: %u\n", total_blocks); 399 430 printf(" Block list: "); 400 431 for (i = 0; i < 12; i++) { … … 406 437 printf("%u ", block); 407 438 } 439 all_blocks = all_blocks || ext2_inode_get_indirect_block(inode, 0) == 0; 408 440 if (!all_blocks) { 409 441 printf(" and more..."); 410 442 } 411 443 printf("\n"); 444 } 445 446 void print_inode_data(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_t data) 447 { 448 int rc; 449 uint32_t data_block_index; 450 block_t *block; 451 size_t i; 452 unsigned char c; 453 454 rc = ext2_filesystem_get_inode_data_block_index(fs, inode, data, 455 &data_block_index); 456 457 if (rc != EOK) { 458 printf("Failed getting data block #%u\n", data); 459 return; 460 } 461 462 printf("Data for inode contents block #%u is located in filesystem " 463 "block %u\n", data, data_block_index); 464 465 printf("Data preview (only printable characters):\n"); 466 467 rc = block_get(&block, fs->device, data_block_index, 0); 468 if (rc != EOK) { 469 printf("Failed reading filesystem block %u\n", data_block_index); 470 return; 471 } 472 473 for (i = 0; i < block->size; i++) { 474 c = ((unsigned char *)block->data)[i]; 475 if (c >= 32 && c < 127) { 476 putchar(c); 477 } 478 else { 479 putchar('.'); 480 } 481 } 482 483 printf("\n"); 484 485 rc = block_put(block); 486 if (rc != EOK) { 487 printf("Failed putting filesystem block\n"); 488 } 489 412 490 } 413 491 -
uspace/lib/ext2/libext2_filesystem.c
ra54af66 rad34feb 41 41 #include <libblock.h> 42 42 #include <malloc.h> 43 #include <assert.h> 43 44 44 45 /** … … 255 256 256 257 /** 258 * Find a filesystem block number where iblock-th data block 259 * of the given inode is located. 260 * 261 * @return EOK on success or negative error code on failure 262 */ 263 int ext2_filesystem_get_inode_data_block_index(ext2_filesystem_t *fs, ext2_inode_t* inode, 264 aoff64_t iblock, uint32_t* fblock) 265 { 266 int rc; 267 aoff64_t limits[4]; 268 uint32_t block_ids_per_block; 269 aoff64_t blocks_per_level[4]; 270 uint32_t offset_in_block; 271 uint32_t current_block; 272 aoff64_t block_offset_in_level; 273 int i; 274 int level; 275 block_t *block; 276 277 if (iblock < EXT2_INODE_DIRECT_BLOCKS) { 278 current_block = ext2_inode_get_direct_block(inode, (uint32_t)iblock); 279 if (current_block == 0) { 280 return EIO; 281 } 282 *fblock = current_block; 283 return EOK; 284 } 285 286 // Compute limits for indirect block levels 287 // TODO: compute this once when loading filesystem and store in ext2_filesystem_t 288 block_ids_per_block = ext2_superblock_get_block_size(fs->superblock) / sizeof(uint32_t); 289 limits[0] = EXT2_INODE_DIRECT_BLOCKS; 290 blocks_per_level[0] = 1; 291 for (i = 1; i < 4; i++) { 292 blocks_per_level[i] = blocks_per_level[i-1] * 293 block_ids_per_block; 294 limits[i] = limits[i-1] + blocks_per_level[i]; 295 } 296 297 // Determine the indirection level needed to get the desired block 298 level = -1; 299 for (i = 1; i < 4; i++) { 300 if (iblock < limits[i]) { 301 level = i; 302 break; 303 } 304 } 305 306 if (level == -1) { 307 return EIO; 308 } 309 310 block_offset_in_level = iblock - limits[level-1]; 311 current_block = ext2_inode_get_indirect_block(inode, level-1); 312 offset_in_block = block_offset_in_level / blocks_per_level[level-1]; 313 314 while (level > 0) { 315 rc = block_get(&block, fs->device, current_block, 0); 316 if (rc != EOK) { 317 return rc; 318 } 319 320 assert(offset_in_block < block_ids_per_block); 321 current_block = ((uint32_t*)block->data)[offset_in_block]; 322 323 rc = block_put(block); 324 if (rc != EOK) { 325 return rc; 326 } 327 328 if (current_block == 0) { 329 return EIO; 330 } 331 332 level -= 1; 333 334 if (level == 0) { 335 break; 336 } 337 338 offset_in_block = block_offset_in_level / blocks_per_level[level-1]; 339 block_offset_in_level %= blocks_per_level[level-1]; 340 } 341 342 *fblock = current_block; 343 344 return EOK; 345 } 346 347 /** 257 348 * Finalize an instance of filesystem 258 349 * -
uspace/lib/ext2/libext2_filesystem.h
ra54af66 rad34feb 60 60 ext2_inode_ref_t **); 61 61 extern int ext2_filesystem_put_inode_ref(ext2_inode_ref_t *); 62 extern int ext2_filesystem_get_inode_data_block_index(ext2_filesystem_t *, ext2_inode_t*, 63 aoff64_t, uint32_t*); 62 64 extern void ext2_filesystem_fini(ext2_filesystem_t *); 63 65 -
uspace/lib/ext2/libext2_inode.c
ra54af66 rad34feb 38 38 #include "libext2_superblock.h" 39 39 #include <byteorder.h> 40 #include <assert.h> 40 41 41 42 /** … … 142 143 143 144 /** 145 * Get number of blocks allocated for contents of the file 146 * represented by this inode. 147 * 148 * @param inode pointer to inode 149 */ 150 inline uint32_t ext2_inode_get_reserved_blocks(ext2_superblock_t *sb, 151 ext2_inode_t *inode) 152 { 153 return ext2_inode_get_reserved_512_blocks(inode) / 154 (ext2_superblock_get_block_size(sb) / 512); 155 } 156 157 /** 144 158 * Get inode flags 145 159 * … … 158 172 inline uint32_t ext2_inode_get_direct_block(ext2_inode_t *inode, uint8_t idx) 159 173 { 174 assert(idx < EXT2_INODE_DIRECT_BLOCKS); 160 175 return uint32_t_le2host(inode->direct_blocks[idx]); 161 176 } … … 165 180 * 166 181 * @param inode pointer to inode 182 * @param idx Indirection level. Valid values are 0 <= idx < 3, where 0 is 183 * singly-indirect block and 2 is triply-indirect-block 167 184 */ 168 inline uint32_t ext2_inode_get_ single_indirect_block(ext2_inode_t *inode)185 inline uint32_t ext2_inode_get_indirect_block(ext2_inode_t *inode, uint8_t idx) 169 186 { 170 return uint32_t_le2host(inode->single_indirect_block); 187 assert(idx < 3); 188 return uint32_t_le2host(inode->indirect_blocks[idx]); 171 189 } 172 173 /**174 * Get double indirect block ID175 *176 * @param inode pointer to inode177 */178 inline uint32_t ext2_inode_get_double_indirect_block(ext2_inode_t *inode)179 {180 return uint32_t_le2host(inode->double_indirect_block);181 }182 183 /**184 * Get triple indirect block ID185 *186 * @param inode pointer to inode187 */188 inline uint32_t ext2_inode_get_triple_indirect_block(ext2_inode_t *inode)189 {190 return uint32_t_le2host(inode->triple_indirect_block);191 }192 193 194 190 195 191 /** @} -
uspace/lib/ext2/libext2_inode.h
ra54af66 rad34feb 51 51 uint8_t unused2[4]; 52 52 uint32_t direct_blocks[12]; // Direct block ids stored in this inode 53 uint32_t single_indirect_block; 54 uint32_t double_indirect_block; 55 uint32_t triple_indirect_block; 53 uint32_t indirect_blocks[3]; 56 54 uint32_t version; 57 55 uint32_t file_acl; … … 75 73 #define EXT2_INODE_MODE_ACCESS_MASK 0x0FFF 76 74 #define EXT2_INODE_MODE_TYPE_MASK 0xF000 75 #define EXT2_INODE_DIRECT_BLOCKS 12 77 76 78 77 typedef struct ext2_inode_ref { … … 88 87 inline uint16_t ext2_inode_get_usage_count(ext2_inode_t *); 89 88 inline uint32_t ext2_inode_get_reserved_512_blocks(ext2_inode_t *); 89 inline uint32_t ext2_inode_get_reserved_blocks(ext2_superblock_t *, 90 ext2_inode_t *); 90 91 inline uint32_t ext2_inode_get_flags(ext2_inode_t *); 91 92 inline uint32_t ext2_inode_get_direct_block(ext2_inode_t *, uint8_t); 92 inline uint32_t ext2_inode_get_single_indirect_block(ext2_inode_t *); 93 inline uint32_t ext2_inode_get_double_indirect_block(ext2_inode_t *); 94 inline uint32_t ext2_inode_get_triple_indirect_block(ext2_inode_t *); 93 inline uint32_t ext2_inode_get_indirect_block(ext2_inode_t *, uint8_t level); 95 94 96 95
Note:
See TracChangeset
for help on using the changeset viewer.