__u64 buf[2048]; /* __u64 for proper field alignment */
struct fiemap *fiemap = (struct fiemap *)buf;
struct fiemap_extent *fm_ext = &fiemap->fm_extents[0];
+ struct fiemap_extent fm_last = {0};
int count = (sizeof(buf) - sizeof(*fiemap)) /
sizeof(struct fiemap_extent);
unsigned long long expected = 0;
+ unsigned long long expected_dense = 0;
unsigned long flags = 0;
unsigned int i;
int fiemap_header_printed = 0;
}
for (i = 0; i < fiemap->fm_mapped_extents; i++) {
+ expected_dense = fm_last.fe_physical +
+ fm_last.fe_length;
+ expected = fm_last.fe_physical +
+ fm_ext[i].fe_logical - fm_last.fe_logical;
if (fm_ext[i].fe_logical != 0 &&
- fm_ext[i].fe_physical != expected) {
+ fm_ext[i].fe_physical != expected &&
+ fm_ext[i].fe_physical != expected_dense) {
tot_extents++;
} else {
expected = 0;
if (verbose)
print_extent_info(&fm_ext[i], n, expected,
blk_shift, st);
-
- expected = fm_ext[i].fe_physical + fm_ext[i].fe_length;
if (fm_ext[i].fe_flags & FIEMAP_EXTENT_LAST)
last = 1;
+ fm_last = fm_ext[i];
n++;
}
ext2fs_struct_stat *st,
unsigned long numblocks, int is_ext2)
{
- struct fiemap_extent fm_ext;
+ struct fiemap_extent fm_ext, fm_last;
unsigned long i, last_block;
- unsigned long long logical;
+ unsigned long long logical, expected = 0;
/* Blocks per indirect block */
const long bpib = st->st_blksize / 4;
int count;
memset(&fm_ext, 0, sizeof(fm_ext));
+ memset(&fm_last, 0, sizeof(fm_last));
if (force_extent) {
fm_ext.fe_flags = FIEMAP_EXTENT_MERGED;
}
return rc;
if (block == 0)
continue;
- if (*num_extents == 0) {
- (*num_extents)++;
- if (force_extent) {
+
+ if (*num_extents == 0 || block != last_block + 1 ||
+ fm_ext.fe_logical + fm_ext.fe_length != logical) {
+ /*
+ * This is the start of a new extent; figure out where
+ * we expected it to be and report the extent.
+ */
+ if (*num_extents != 0 && fm_last.fe_length) {
+ expected = fm_last.fe_physical +
+ (fm_ext.fe_logical - fm_last.fe_logical);
+ if (expected == fm_ext.fe_physical)
+ expected = 0;
+ }
+ if (force_extent && *num_extents == 0)
print_extent_header();
- fm_ext.fe_physical = block * st->st_blksize;
+ if (force_extent && *num_extents != 0) {
+ print_extent_info(&fm_ext, *num_extents - 1,
+ expected, blk_shift, st);
}
- }
- count++;
- if (force_extent && last_block != 0 &&
- (block != last_block + 1 ||
- fm_ext.fe_logical + fm_ext.fe_length != logical)) {
- print_extent_info(&fm_ext, *num_extents - 1,
- (last_block + 1) * st->st_blksize,
- blk_shift, st);
- fm_ext.fe_length = 0;
+ if (verbose && expected != 0) {
+ printf("Discontinuity: Block %llu is at %llu "
+ "(was %llu)\n",
+ fm_ext.fe_logical / st->st_blksize,
+ fm_ext.fe_physical / st->st_blksize,
+ expected / st->st_blksize);
+ }
+ /* create the new extent */
+ fm_last = fm_ext;
(*num_extents)++;
- fm_ext.fe_logical = logical;
fm_ext.fe_physical = block * st->st_blksize;
- } else if (last_block && (block != last_block + 1)) {
- if (verbose)
- printf("Discontinuity: Block %ld is at %lu (was "
- "%lu)\n", i, block, last_block + 1);
- fm_ext.fe_length = 0;
- (*num_extents)++;
fm_ext.fe_logical = logical;
- fm_ext.fe_physical = block * st->st_blksize;
+ fm_ext.fe_length = 0;
}
fm_ext.fe_length += st->st_blksize;
last_block = block;
}
-
- if (force_extent)
- print_extent_info(&fm_ext, *num_extents - 1,
- last_block * st->st_blksize, blk_shift, st);
+ if (force_extent && *num_extents != 0) {
+ if (fm_last.fe_length) {
+ expected = fm_last.fe_physical +
+ (fm_ext.fe_logical - fm_last.fe_logical);
+ if (expected == fm_ext.fe_physical)
+ expected = 0;
+ }
+ print_extent_info(&fm_ext, *num_extents - 1, expected,
+ blk_shift, st);
+ }
return count;
}