Util-Linux Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH] fiemap : add fiemap misc tool
@ 2019-03-31  6:35 zhenwei pi
  0 siblings, 0 replies; only message in thread
From: zhenwei pi @ 2019-03-31  6:35 UTC (permalink / raw)
  To: kzak; +Cc: util-linux, pizhenwei

Add fiemap to dump file extent mappings. Typically we can recognize a
file is sparse or not.

For example :
 #./fiemap /var/log/syslog /var/log/syslog.2.gz
File /var/log/syslog has 19 extents :
  	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 extents :
  	Logical          Physical         Length           Flag
0:	0000000000000000 0000000995c40000 0000000000023000 0001

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
---
 configure.ac             |   4 +-
 misc-utils/Makemodule.am |   5 ++
 misc-utils/fiemap.c      | 152 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 160 insertions(+), 1 deletion(-)
 create mode 100644 misc-utils/fiemap.c

diff --git a/configure.ac b/configure.ac
index bbf07db..98c3f42 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])
@@ -1820,7 +1823,6 @@ AM_CONDITIONAL([BUILD_HEXDUMP], [test "x$build_hexdump" = xyes])
 UL_BUILD_INIT([rev], [yes])
 AM_CONDITIONAL([BUILD_REV], [test "x$build_rev" = xyes])
 
-
 AC_ARG_ENABLE([tunelp],
   AS_HELP_STRING([--enable-tunelp], [build tunelp]),
   [], [UL_DEFAULT_ENABLE([tunelp], [no])]
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..bcc807e
--- /dev/null
+++ b/misc-utils/fiemap.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2019 zhenwei pi <pizhenwei@bytedance.com>
+ *
+ * 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;
+
+	if ((fiemap = (struct fiemap*)malloc(sizeof(struct 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 */
+	if ((fiemap = (struct fiemap*)realloc(fiemap,sizeof(struct fiemap) + 
+					extents_size)) == 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 extents :\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");
+}
+#else
+static struct fiemap *read_fiemap(int fd)
+{
+	return NULL;
+}
+
+static void show_fiemap(struct fiemap *fiemap, char *filename)
+{
+}
+#endif
+
+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;
+
+		if ((fd = open(argv[optind], O_RDONLY)) < 0) {
+			err(EXIT_FAILURE, _("open file failed"));
+		} else {
+			struct fiemap *fiemap = NULL;
+
+			if ((fiemap = read_fiemap(fd)) != NULL) {
+				show_fiemap(fiemap, argv[optind]);
+				free(fiemap);
+			}
+			close(fd);
+		}
+	}
+
+	return 0;
+}
-- 
2.7.4


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, back to index

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-31  6:35 [PATCH] fiemap : add fiemap misc tool zhenwei pi

Util-Linux Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/util-linux/0 util-linux/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 util-linux util-linux/ https://lore.kernel.org/util-linux \
		util-linux@vger.kernel.org util-linux@archiver.kernel.org
	public-inbox-index util-linux


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.util-linux


AGPL code for this site: git clone https://public-inbox.org/ public-inbox