errcode_t ext2fs_extent_save_path(ext2_extent_handle_t handle, ext2_extent_path_t *ret_path) { ext2_extent_path_t save_path; struct ext2fs_extent extent; struct ext2_extent_info info; errcode_t retval; retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent); if (retval) return retval; retval = ext2fs_extent_get_info(handle, &info); if (retval) return retval; retval = ext2fs_get_mem(sizeof(struct ext2_extent_path), &save_path); if (retval) return retval; memset(save_path, 0, sizeof(struct ext2_extent_path)); save_path->magic = EXT2_ET_MAGIC_EXTENT_PATH; save_path->leaf_height = info.max_depth - info.curr_level - 1; save_path->lblk = extent.e_lblk; *ret_path = save_path; return 0; }
void do_info(int argc, char **argv) { struct ext2fs_extent extent; struct ext2_extent_info info; errcode_t retval; if (common_extent_args_process(argc, argv, 1, 1, "info", "", 0)) return; retval = ext2fs_extent_get_info(current_handle, &info); if (retval) { com_err(argv[0], retval, 0); return; } retval = ext2fs_extent_get(current_handle, EXT2_EXTENT_CURRENT, &extent); if (retval) { com_err(argv[0], retval, 0); return; } dbg_print_extent(0, &extent); printf("Current handle location: %d/%d (max: %d, bytes %d), level %d/%d\n", info.curr_entry, info.num_entries, info.max_entries, info.bytes_avail, info.curr_level, info.max_depth); printf("\tmax lblk: %llu, max pblk: %llu\n", info.max_lblk, info.max_pblk); printf("\tmax_len: %u, max_uninit_len: %u\n", info.max_len, info.max_uninit_len); }
/* * Traverse back up to root fixing parents of current node as needed. * * If we changed start of first entry in a node, fix parent index start * and so on. * * Safe to call for any position in node; if not at the first entry, * will simply return. */ errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle) { int retval = 0; int orig_height; blk64_t start; struct extent_path *path; struct ext2fs_extent extent; struct ext2_extent_info info; EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE); if (!(handle->fs->flags & EXT2_FLAG_RW)) return EXT2_ET_RO_FILSYS; if (!handle->path) return EXT2_ET_NO_CURRENT_NODE; path = handle->path + handle->level; if (!path->curr) return EXT2_ET_NO_CURRENT_NODE; retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent); if (retval) goto done; /* modified node's start block */ start = extent.e_lblk; if ((retval = ext2fs_extent_get_info(handle, &info))) return retval; orig_height = info.max_depth - info.curr_level; /* traverse up until index not first, or startblk matches, or top */ while (handle->level > 0 && (path->left == path->entries - 1)) { retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP, &extent); if (retval) goto done; if (extent.e_lblk == start) break; path = handle->path + handle->level; extent.e_len += (extent.e_lblk - start); extent.e_lblk = start; retval = ext2fs_extent_replace(handle, 0, &extent); if (retval) goto done; update_path(handle); } /* put handle back to where we started */ retval = ext2fs_extent_goto2(handle, orig_height, start); done: return retval; }
//print Blocks of inode (ext4) static void local_dump_extents(FILE *f, const char *prefix, struct ext2_inode * inode, int flags, int logical_width, int physical_width) { ext2_extent_handle_t handle; struct ext2fs_extent extent; struct ext2_extent_info info; int op = EXT2_EXTENT_ROOT; unsigned int printed = 0; errcode_t errcode; errcode = local_ext2fs_extent_open(current_fs, *inode, &handle); if (errcode) return; if (flags & DUMP_EXTENT_TABLE) fprintf(f, "Level Entries %*s %*s Length Flags\n", (logical_width*2)+3, "Logical", (physical_width*2)+3, "Physical"); else fprintf(f, "%sEXTENTS:\n%s", prefix, prefix); while (1) { errcode = ext2fs_extent_get(handle, op, &extent); if (errcode) break; op = EXT2_EXTENT_NEXT; if (extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT) continue; if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) { if ((flags & DUMP_LEAF_EXTENTS) == 0) continue; } errcode = ext2fs_extent_get_info(handle, &info); if (errcode) continue; if (!(extent.e_flags & EXT2_EXTENT_FLAGS_LEAF)) { if (extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT) continue; if (flags & DUMP_EXTENT_TABLE) { fprintf(f, "%2d/%2d %3d/%3d %11llu - %11llu " "%11llu%14s %6u\n", info.curr_level, info.max_depth, info.curr_entry, info.num_entries, extent.e_lblk, extent.e_lblk + (extent.e_len - 1), extent.e_pblk, "", extent.e_len); continue; } fprintf(f, "%s(NODE #%d, %lld-%lld, blk %lld)", printed ? ", " : "", info.curr_entry, extent.e_lblk, extent.e_lblk + (extent.e_len - 1), extent.e_pblk); printed = 1; continue; } if (flags & DUMP_EXTENT_TABLE) { fprintf(f, "%2d/%2d %3d/%3d %11llu - %11llu %11llu - %11llu %6u %s\n", info.curr_level, info.max_depth, info.curr_entry, info.num_entries, extent.e_lblk, extent.e_lblk + (extent.e_len - 1), extent.e_pblk, extent.e_pblk + (extent.e_len - 1), extent.e_len, extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ? "Uninit" : ""); continue; } if (extent.e_len == 0) continue; else if (extent.e_len == 1) fprintf(f, "%s(%lld%s): %lld", printed ? ", " : "", extent.e_lblk, extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ? " [uninit]" : "", extent.e_pblk); else fprintf(f, "%s(%lld-%lld%s): %lld-%lld", printed ? ", " : "", extent.e_lblk, extent.e_lblk + (extent.e_len - 1), extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ? " [uninit]" : "", extent.e_pblk, extent.e_pblk + (extent.e_len - 1)); printed = 1; } if (printed) fprintf(f, "\n\n"); local_ext2fs_extent_free(handle); }