use libblkid to get filesystem type
we can now use libblkid to detect exfat
diff --git a/libblkid/md.c b/libblkid/md.c
new file mode 100644
index 0000000..5eba947
--- /dev/null
+++ b/libblkid/md.c
@@ -0,0 +1,154 @@
+/*
+ * Linux Software RAID (md) topology
+ * -- this is fallback for old systems where the topology information is not
+ *    exported by sysfs
+ *
+ * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "topology.h"
+
+#ifndef MD_MAJOR
+#define MD_MAJOR	9
+#endif
+
+#ifndef _IOT__IOTBASE_uint32_t
+#define _IOT__IOTBASE_uint32_t IOT_SIMPLE(uint32_t)
+#endif
+#define _IOT_md_array_info _IOT (_IOTS(uint32_t), 18, 0, 0, 0, 0)
+#define GET_ARRAY_INFO          _IOR (MD_MAJOR, 0x11, struct md_array_info)
+
+struct md_array_info {
+	/*
+	 * Generic constant information
+	 */
+	uint32_t major_version;
+	uint32_t minor_version;
+	uint32_t patch_version;
+	uint32_t ctime;
+	uint32_t level;
+	uint32_t size;
+	uint32_t nr_disks;
+	uint32_t raid_disks;
+	uint32_t md_minor;
+	uint32_t not_persistent;
+
+	/*
+	 * Generic state information
+	 */
+	uint32_t utime;	  /*  0 Superblock update time		  */
+	uint32_t state;	  /*  1 State bits (clean, ...)		  */
+	uint32_t active_disks;  /*  2 Number of currently active disks  */
+	uint32_t working_disks; /*  3 Number of working disks		  */
+	uint32_t failed_disks;  /*  4 Number of failed disks		  */
+	uint32_t spare_disks;	  /*  5 Number of spare disks		  */
+
+	/*
+	 * Personality information
+	 */
+	uint32_t layout;	  /*  0 the array's physical layout	  */
+	uint32_t chunk_size;	  /*  1 chunk size in bytes		  */
+
+};
+
+static int is_md_device(dev_t devno)
+{
+	if (major(devno) == MD_MAJOR)
+		return 1;
+	return blkid_driver_has_major("md", major(devno));
+}
+
+static int probe_md_tp(blkid_probe pr,
+		const struct blkid_idmag *mag __attribute__((__unused__)))
+{
+	int fd = -1;
+	dev_t disk = 0;
+	dev_t devno = blkid_probe_get_devno(pr);
+	struct md_array_info md;
+
+	if (!devno)
+		goto nothing;		/* probably not a block device */
+
+	if (!is_md_device(devno))
+		goto nothing;
+
+	if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk))
+		goto nothing;
+
+	if (disk == devno)
+		fd = pr->fd;
+	else {
+		char *diskpath = blkid_devno_to_devname(disk);
+
+		if (!diskpath)
+			goto nothing;
+
+		fd = open(diskpath, O_RDONLY|O_CLOEXEC);
+		free(diskpath);
+
+                if (fd == -1)
+			goto nothing;
+	}
+
+	memset(&md, 0, sizeof(md));
+
+	if (ioctl(fd, GET_ARRAY_INFO, &md))
+		goto nothing;
+
+	if (fd >= 0 && fd != pr->fd) {
+		close(fd);
+		fd = -1;
+	}
+
+	/*
+	 * Ignore levels we don't want aligned (e.g. linear)
+	 * and deduct disk(s) from stripe width on RAID4/5/6
+	 */
+	switch (md.level) {
+	case 6:
+		md.raid_disks--;
+		/* fallthrough */
+	case 5:
+	case 4:
+		md.raid_disks--;
+		/* fallthrough */
+	case 1:
+	case 0:
+	case 10:
+		break;
+	default:
+		goto nothing;
+	}
+
+	blkid_topology_set_minimum_io_size(pr, md.chunk_size);
+	blkid_topology_set_optimal_io_size(pr, md.chunk_size * md.raid_disks);
+
+	return 0;
+
+nothing:
+	if (fd >= 0 && fd != pr->fd)
+		close(fd);
+	return 1;
+}
+
+const struct blkid_idinfo md_tp_idinfo =
+{
+	.name		= "md",
+	.probefunc	= probe_md_tp,
+	.magics		= BLKID_NONE_MAGIC
+};
+