+static int int_log10(unsigned long long arg)
+{
+ int l = 0;
+
+ arg = arg / 10;
+ while (arg) {
+ l++;
+ arg = arg / 10;
+ }
+ return l;
+}
+
+#define DUMP_LEAF_EXTENTS 0x01
+#define DUMP_NODE_EXTENTS 0x02
+#define DUMP_EXTENT_TABLE 0x04
+
+static void dump_extents(FILE *f, const char *prefix, ext2_ino_t ino,
+ 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 = ext2fs_extent_open(current_fs, ino, &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;
+ } else {
+ if ((flags & DUMP_NODE_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 %*llu - %*llu "
+ "%*llu%*s %6u\n",
+ info.curr_level, info.max_depth,
+ info.curr_entry, info.num_entries,
+ logical_width,
+ extent.e_lblk,
+ logical_width,
+ extent.e_lblk + (extent.e_len - 1),
+ physical_width,
+ extent.e_pblk,
+ physical_width+3, "", extent.e_len);
+ continue;
+ }
+
+ fprintf(f, "%s(ETB%d):%lld",
+ printed ? ", " : "", info.curr_level,
+ extent.e_pblk);
+ printed = 1;
+ continue;
+ }
+
+ if (flags & DUMP_EXTENT_TABLE) {
+ fprintf(f, "%2d/%2d %3d/%3d %*llu - %*llu "
+ "%*llu - %*llu %6u %s\n",
+ info.curr_level, info.max_depth,
+ info.curr_entry, info.num_entries,
+ logical_width,
+ extent.e_lblk,
+ logical_width,
+ extent.e_lblk + (extent.e_len - 1),
+ physical_width,
+ extent.e_pblk,
+ physical_width,
+ 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 ?
+ "[u]" : "",
+ 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 ?
+ "[u]" : "",
+ extent.e_pblk,
+ extent.e_pblk + (extent.e_len - 1));
+ printed = 1;
+ }
+ if (printed)
+ fprintf(f, "\n");
+}