For example:
#./fiemap /var/log/syslog /var/log/syslog.2.gz
File /var/log/syslog has 19 extent(s):
Logical Physical Length Flag
0: 0000000000000000 00000010d63a8000 0000000000001000 0000
1: 0000000000001000 00000010d63c4000 0000000000001000 0000
2: 0000000000002000 00000010d63d6000 0000000000001000 0000
3: 0000000000003000 00000010d723e000 0000000000001000 0000
4: 0000000000004000 000000076c377000 0000000000001000 0000
5: 0000000000005000 00000010d550f000 0000000000001000 0000
6: 0000000000006000 00000010d7290000 0000000000001000 0000
7: 0000000000007000 00000010d57c9000 0000000000001000 0000
8: 0000000000008000 00000010d57f5000 0000000000001000 0000
9: 0000000000009000 000000076d6b3000 0000000000001000 0000
10: 000000000000a000 00000010d558d000 0000000000001000 0000
11: 000000000000b000 00000010d77ff000 0000000000001000 0000
12: 000000000000c000 00000010d67fb000 0000000000001000 0000
13: 000000000000d000 00000010d73fc000 0000000000001000 0000
14: 000000000000e000 00000005d2bb2000 0000000000001000 0000
15: 000000000000f000 00000007705a1000 0000000000001000 0000
16: 0000000000010000 0000000c8bf10000 0000000000010000 0000
17: 0000000000020000 0000001070020000 0000000000060000 0000
18: 0000000000080000 00000011aa580000 0000000000014000 0001
File /var/log/syslog.2.gz has 1 extent(s):
Logical Physical Length Flag
0: 0000000000000000 0000000995c40000 0000000000023000 0001
Signed-off-by: zhenwei pi <pizhenwei@xxxxxxxxxxxxx>
---
AUTHORS | 1 +
configure.ac | 3 +
misc-utils/Makemodule.am | 5 ++
misc-utils/fiemap.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 164 insertions(+)
create mode 100644 misc-utils/fiemap.c
diff --git a/AUTHORS b/AUTHORS
index d7dbbd6..a0cecf7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -20,6 +20,7 @@ AUTHORS (merged projects & commands):
fallocate: Eric Sandeen <sandeen@xxxxxxxxxx>
Karel Zak <kzak@xxxxxxxxxx>
Matěj Cepl <mcepl@xxxxxxxxxx>
+ fiemap: zhenwei pi <pizhenwei@xxxxxxxxxxxxx>
fincore: Masatake YAMATO <yamato@xxxxxxxxxx>
findmnt: Karel Zak <kzak@xxxxxxxxxx>
flock: H. Peter Anvin <hpa@xxxxxxxxx>
diff --git a/configure.ac b/configure.ac
index bbf07db..ccb1a12 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1769,6 +1769,9 @@ UL_REQUIRES_LINUX([fincore])
UL_REQUIRES_BUILD([fincore], [libsmartcols])
AM_CONDITIONAL([BUILD_FINCORE], [test "x$build_fincore" = xyes])
+UL_BUILD_INIT([fiemap], [yes])
+AM_CONDITIONAL([BUILD_FIEMAP], [test "x$build_fiemap" = xyes])
+
UL_BUILD_INIT([fsfreeze], [check])
UL_REQUIRES_LINUX([fsfreeze])
AM_CONDITIONAL([BUILD_FSFREEZE], [test "x$build_fsfreeze" = xyes])
diff --git a/misc-utils/Makemodule.am b/misc-utils/Makemodule.am
index f56a819..8bdc6fa 100644
--- a/misc-utils/Makemodule.am
+++ b/misc-utils/Makemodule.am
@@ -228,3 +228,8 @@ hardlink_CFLAGS += $(PCRE_CFLAGS)
endif
dist_man_MANS += misc-utils/hardlink.1
endif
+
+if BUILD_FIEMAP
+usrbin_exec_PROGRAMS += fiemap
+fiemap_SOURCES = misc-utils/fiemap.c
+endif
diff --git a/misc-utils/fiemap.c b/misc-utils/fiemap.c
new file mode 100644
index 0000000..b77eb14
--- /dev/null
+++ b/misc-utils/fiemap.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2019 zhenwei pi <pizhenwei@xxxxxxxxxxxxx>
+ *
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+
+#include "c.h"
+#include "nls.h"
+#include "closestream.h"
+
+#ifdef FS_IOC_FIEMAP
+#include <linux/fiemap.h>
+
+static struct fiemap *read_fiemap(int fd)
+{
+ struct fiemap *fiemap;
+ int extents_size;
+
+ fiemap = (struct fiemap *)malloc(sizeof(struct fiemap));
+ if (fiemap == NULL)
+ err(EXIT_FAILURE, _("malloc"));
+
+ memset(fiemap, 0, sizeof(struct fiemap));
+
+ fiemap->fm_start = 0;
+ fiemap->fm_length = ~0;
+ fiemap->fm_flags = 0;
+ fiemap->fm_extent_count = 0;
+ fiemap->fm_mapped_extents = 0;
+
+ /* count how many extents there are */
+ if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0)
+ err(EXIT_FAILURE, _("fiemap ioctl() failed"));
+
+ /* read in the extents */
+ extents_size = sizeof(struct fiemap_extent) *
+ (fiemap->fm_mapped_extents);
+
+ /* resize fiemaps for all extents */
+ fiemap = (struct fiemap *)realloc(fiemap, sizeof(struct fiemap) +
+ extents_size);
+ if (fiemap == NULL)
+ err(EXIT_FAILURE, _("realloc for extents memory"));
+
+ memset(fiemap->fm_extents, 0, extents_size);
+ fiemap->fm_extent_count = fiemap->fm_mapped_extents;
+ fiemap->fm_mapped_extents = 0;
+
+ if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0) {
+ err(EXIT_FAILURE, _("ioctl() FS_IOC_FIEMAP failed"));
+ return NULL;
+ }
+
+ return fiemap;
+}
+
+static void show_fiemap(struct fiemap *fiemap, char *filename)
+{
+ unsigned int i = 0;
+
+ printf("File %s has %d extent(s):\n", filename,
+ fiemap->fm_mapped_extents);
+ printf("#\tLogical Physical Length Flag\n");
+ for (i = 0; i < fiemap->fm_mapped_extents; i++) {
+ printf("%d:\t%-16.16llx %-16.16llx %-16.16llx %-4.4x\n", i,
+ fiemap->fm_extents[i].fe_logical,
+ fiemap->fm_extents[i].fe_physical,
+ fiemap->fm_extents[i].fe_length,
+ fiemap->fm_extents[i].fe_flags);
+ }
+
+ printf("\n");
+}
+
+static void __attribute__((__noreturn__)) usage(void)
+{
+ FILE *out = stdout;
+
+ fputs(USAGE_HEADER, out);
+ fprintf(out, _(" %s <file>...\n"), program_invocation_short_name);
+
+ fputs(USAGE_SEPARATOR, out);
+ exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+ int c;
+ static const struct option longopts[] = {
+ { "version", no_argument, NULL, 'V' },
+ { "help", no_argument, NULL, 'h' },
+ { NULL, 0, NULL, 0 },
+ };
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+ atexit(close_stdout);
+
+ while ((c = getopt_long (argc, argv, "Vh", longopts, NULL)) != -1) {
+ switch (c) {
+ case 'V':
+ printf(UTIL_LINUX_VERSION);
+ return EXIT_SUCCESS;
+
+ case 'h':
+ usage();
+
+ default:
+ errtryhelp(EXIT_FAILURE);
+ }
+ }
+
+ if (optind == argc) {
+ warnx(_("no file specified"));
+ errtryhelp(EXIT_FAILURE);
+ }
+
+ for ( ; optind < argc; optind++) {
+ int fd = 0;
+
+ fd = open(argv[optind], O_RDONLY);
+ if (fd < 0) {
+ err(EXIT_FAILURE, _("open file failed"));
+ } else {
+ struct fiemap *fiemap = NULL;
+
+ fiemap = read_fiemap(fd);
+ if (fiemap != NULL) {
+ show_fiemap(fiemap, argv[optind]);
+ free(fiemap);
+ }
+ close(fd);
+ }
+ }
+
+ return 0;
+}
+#else
+int main(int argc, char **argv)
+{
+ err(EXIT_FAILURE, _("FS_IOC_FIEMAP not supported"));
+
+ return 0;
+}
+#endif
--
2.7.4