" -l -- also displays the length of each extent in 512-byte blocks.\n"
" -n -- query n extents.\n"
" -v -- Verbose information\n"
+" offset is the starting offset to map, and is optional. If offset is\n"
+" specified, mapping length may (optionally) be specified as well."
"\n"));
}
char lbuf[48];
char bbuf[48];
char flgbuf[16];
+ int num_printed = 0;
llast = BTOBBT(last_logical);
lstart = BTOBBT(extent->fe_logical);
flg_w, _("FLAGS"));
}
- if (lstart != llast) {
+ if (lstart > llast) {
print_hole(foff_w, boff_w, tot_w, cur_extent, 0, false, llast,
lstart);
cur_extent++;
+ num_printed++;
}
if (cur_extent == max_extents)
- return 1;
+ return num_printed;
snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]:",
(unsigned long long)lstart, lstart + len - 1ULL);
printf("%4d: %-*s %-*s %*llu %*s\n", cur_extent, foff_w, lbuf,
boff_w, bbuf, tot_w, (unsigned long long)len, flg_w, flgbuf);
- return 2;
+ num_printed++;
+
+ return num_printed;
}
static int
__u64 llast;
__u64 block;
__u64 len;
+ int num_printed = 0;
llast = BTOBBT(last_logical);
lstart = BTOBBT(extent->fe_logical);
len = BTOBBT(extent->fe_length);
block = BTOBBT(extent->fe_physical);
- if (lstart != llast) {
+ if (lstart > llast) {
print_hole(0, 0, 0, cur_extent, lflag, true, llast, lstart);
cur_extent++;
+ num_printed++;
}
if (cur_extent == max_extents)
- return 1;
+ return num_printed;
printf("\t%d: [%llu..%llu]: %llu..%llu", cur_extent,
(unsigned long long)lstart, lstart + len - 1ULL,
(unsigned long long)block, block + len - 1ULL);
+ num_printed++;
+
if (lflag)
printf(_(" %llu blocks\n"), (unsigned long long)len);
else
printf("\n");
- return 2;
+ return num_printed;
}
/*
char **argv)
{
struct fiemap *fiemap;
- int last = 0;
+ int done = 0;
int lflag = 0;
int vflag = 0;
int fiemap_flags = FIEMAP_FLAG_SYNC;
int boff_w = 16;
int tot_w = 5; /* 5 since its just one number */
int flg_w = 5;
- __u64 last_logical = 0;
+ __u64 last_logical = 0; /* last extent offset handled */
+ off64_t start_offset = 0; /* mapping start */
+ off64_t length = -1LL; /* mapping length */
+ off64_t range_end = -1LL; /* mapping end*/
+ size_t fsblocksize, fssectsize;
struct stat st;
+ init_cvtnum(&fsblocksize, &fssectsize);
+
while ((c = getopt(argc, argv, "aln:v")) != EOF) {
switch (c) {
case 'a':
}
}
+ /* Range start (optional) */
+ if (optind < argc) {
+ start_offset = cvtnum(fsblocksize, fssectsize, argv[optind]);
+ if (start_offset < 0) {
+ printf("non-numeric offset argument -- %s\n", argv[optind]);
+ return 0;
+ }
+ last_logical = start_offset;
+ optind++;
+ }
+
+ /* Range length (optional if range start was specified) */
+ if (optind < argc) {
+ length = cvtnum(fsblocksize, fssectsize, argv[optind]);
+ if (length < 0) {
+ printf("non-numeric len argument -- %s\n", argv[optind]);
+ return 0;
+ }
+ range_end = start_offset + length;
+ }
+
map_size = sizeof(struct fiemap) +
(EXTENT_BATCH * sizeof(struct fiemap_extent));
fiemap = malloc(map_size);
printf("%s:\n", file->name);
- while (!last && (cur_extent != max_extents)) {
-
+ while (!done) {
memset(fiemap, 0, map_size);
fiemap->fm_flags = fiemap_flags;
fiemap->fm_start = last_logical;
- fiemap->fm_length = -1LL;
+ fiemap->fm_length = range_end - last_logical;
fiemap->fm_extent_count = EXTENT_BATCH;
ret = ioctl(file->fd, FS_IOC_FIEMAP, (unsigned long)fiemap);
cur_extent += num_printed;
last_logical = extent->fe_logical + extent->fe_length;
+ /* Kernel has told us there are no more extents */
if (extent->fe_flags & FIEMAP_EXTENT_LAST) {
- last = 1;
+ done = 1;
+ break;
+ }
+
+ /* We have exhausted the requested range */
+ if (last_logical >= range_end) {
+ done = 1;
break;
}
- if (cur_extent == max_extents)
+ /* We have printed requested nr of extents */
+ if (cur_extent == max_extents) {
+ done = 1;
break;
+ }
}
}
return 0;
}
- if (cur_extent && last_logical < st.st_size)
+ /* Print last hole to EOF or to end of requested range */
+ range_end = min((uint64_t)range_end, st.st_size);
+
+ if (cur_extent && last_logical < range_end)
print_hole(foff_w, boff_w, tot_w, cur_extent, lflag, !vflag,
- BTOBBT(last_logical), BTOBBT(st.st_size));
+ BTOBBT(last_logical), BTOBBT(range_end));
out:
free(fiemap);
fiemap_cmd.argmin = 0;
fiemap_cmd.argmax = -1;
fiemap_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
- fiemap_cmd.args = _("[-alv] [-n nx]");
+ fiemap_cmd.args = _("[-alv] [-n nx] [offset [len]]");
fiemap_cmd.oneline = _("print block mapping for a file");
fiemap_cmd.help = fiemap_help;