* %End-Header%
*/
+#include "config.h"
#ifndef __linux__
#include <stdio.h>
#include <stdlib.h>
int no_bs = 0; /* Don't use the files blocksize, use 1K blocksize */
int sync_file = 0; /* fsync file before getting the mapping */
int xattr_map = 0; /* get xattr mapping */
+int force_bmap = 0;
int logical_width = 12;
int physical_width = 14;
unsigned long long filesize;
struct fiemap_extent *fm_ext = &fiemap->fm_extents[0];
int count = (sizeof(buf) - sizeof(*fiemap)) /
sizeof(struct fiemap_extent);
- unsigned long long last_blk = 0;
+ unsigned long long expected = 0;
unsigned long flags = 0;
unsigned int i;
static int fiemap_incompat_printed;
+ int fiemap_header_printed = 0;
int tot_extents = 1, n = 0;
int last = 0;
int rc;
- fiemap->fm_length = ~0ULL;
-
memset(fiemap, 0, sizeof(struct fiemap));
- if (!verbose)
- count = 0;
-
if (sync_file)
flags |= FIEMAP_FLAG_SYNC;
if (xattr_map)
flags |= FIEMAP_FLAG_XATTR;
- if (verbose)
- printf(" ext %*s %*s %*s length flags\n", logical_width,
- "logical", physical_width, "physical",
- physical_width, "expected");
-
do {
fiemap->fm_length = ~0ULL;
fiemap->fm_flags = flags;
return rc;
}
- if (!verbose) {
- *num_extents = fiemap->fm_mapped_extents;
- goto out;
+ if (verbose && !fiemap_header_printed) {
+ /*
+ * No extents on first call?
+ * Skip header and show 0 extents.
+ */
+ if (fiemap->fm_mapped_extents == 0) {
+ *num_extents = 0;
+ goto out;
+ }
+ printf(" ext %*s %*s %*s length flags\n", logical_width,
+ "logical", physical_width, "physical",
+ physical_width, "expected");
+ fiemap_header_printed = 1;
}
/* If 0 extents are returned, then more ioctls are not needed */
ext_len = fm_ext[i].fe_length >> blk_shift;
logical_blk = fm_ext[i].fe_logical >> blk_shift;
- if (logical_blk && phy_blk != last_blk + 1)
+ if (logical_blk && phy_blk != expected)
tot_extents++;
else
- last_blk = 0;
- print_extent_info(&fm_ext[i], n, last_blk, blk_shift);
+ expected = 0;
+ if (verbose)
+ print_extent_info(&fm_ext[i], n, expected,
+ blk_shift);
- last_blk = phy_blk + ext_len - 1;
+ expected = phy_blk + ext_len;
if (fm_ext[i].fe_flags & FIEMAP_EXTENT_LAST)
last = 1;
n++;
#endif
int bs;
long fd;
- unsigned long block, last_block = 0, numblocks, i, count;
+ unsigned long block, last_block = 0, numblocks, i, count = 0;
long bpib; /* Blocks per indirect block */
long cylgroups;
int num_extents = 0, expected;
printf("File size of %s is %lld (%ld block%s, blocksize %d)\n",
filename, (long long) fileinfo.st_size, numblocks,
numblocks == 1 ? "" : "s", bs);
- if (filefrag_fiemap(fd, int_log2(bs), &num_extents) != 0) {
+ if (force_bmap ||
+ filefrag_fiemap(fd, int_log2(bs), &num_extents) != 0) {
for (i = 0, count = 0; i < numblocks; i++) {
if (is_ext2 && last_block) {
if (((i-EXT2_DIRECT) % bpib) == 0)
if (((i-EXT2_DIRECT-bpib) % (bpib*bpib)) == 0)
last_block++;
if (((i-EXT2_DIRECT-bpib-bpib*bpib) %
- (bpib*bpib*bpib)) == 0)
+ (((__u64) bpib)*bpib*bpib)) == 0)
last_block++;
}
rc = get_bmap(fd, i, &block);
if (block == 0)
continue;
+ if (!num_extents)
+ num_extents++;
count++;
if (last_block && (block != last_block+1) ) {
if (verbose)
printf("%s: 1 extent found", filename);
else
printf("%s: %d extents found", filename, num_extents);
+ /* count, and thus expected, only set for indirect FIBMAP'd files */
expected = (count/((bs*8)-(fsinfo.f_files/8/cylgroups)-3))+1;
- if (is_ext2 && expected < num_extents)
+ if (is_ext2 && expected && expected < num_extents)
printf(", perfection would be %d extent%s\n", expected,
(expected>1) ? "s" : "");
else
static void usage(const char *progname)
{
- fprintf(stderr, "Usage: %s [-bvsx] file ...\n", progname);
+ fprintf(stderr, "Usage: %s [-Bbvsx] file ...\n", progname);
exit(1);
}
char **cpp;
int c;
- while ((c = getopt(argc, argv, "bsvx")) != EOF)
+ while ((c = getopt(argc, argv, "Bbsvx")) != EOF)
switch (c) {
+ case 'B':
+ force_bmap++;
+ break;
case 'b':
no_bs++;
break;