#include #include #include #include #include #include #include #include #include #include #include #include "fiemap.h" #define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap) static unsigned int num_extents = 1024; static unsigned int estimate_extents = 1; static unsigned long long map_start = 0ULL; static unsigned long long map_len = FIEMAP_MAX_OFFSET; static char *fname; static unsigned int blocksize = 4096; static void usage(void) { printf("Usage: fiemap filename\n"); exit(1); } static void print_extent(struct fiemap_extent *extent) { __u64 val; printf("Logical: ###[%8"PRIu64"]\t", extent->fe_logical); printf("Ext length: ###[%8"PRIu64"]\t", extent->fe_length); printf("Physical: ###[%8"PRIu64"]\t", extent->fe_physical); printf("flags: %u\t", extent->fe_flags); if (extent->fe_flags & FIEMAP_EXTENT_SHARED) printf("Yeah, found an shared extent\n"); if (extent->fe_flags & FIEMAP_EXTENT_UNWRITTEN) printf("Yeah, you are hole?\n"); printf("\n"); } static void show_results(struct fiemap *fiemap) { int i; printf("Extents returned: %u\n", fiemap->fm_mapped_extents); if (fiemap->fm_extent_count == 0 || fiemap->fm_mapped_extents == 0) return; for (i = 0; i < fiemap->fm_mapped_extents; i++) print_extent(&fiemap->fm_extents[i]); } static int figure_extents(int fd, unsigned int *num) { int ret; struct fiemap fiemap = { 0, }; fiemap.fm_start = map_start; fiemap.fm_length = map_len; fiemap.fm_flags = 0; ret = ioctl(fd, FS_IOC_FIEMAP, &fiemap); if (ret == -1) { fprintf(stderr, "fiemap get count error %d: \"%s\"\n", errno, strerror(errno)); return -1; } *num = fiemap.fm_mapped_extents; return 0; } int main(int argc, char **argv) { int ret, fd; struct fiemap *fiemap; fd = open(argv[1], O_RDONLY); if (fd == -1) { fprintf(stderr, "open error %d: \"%s\"\n", errno, strerror(errno)); return -1; } if (figure_extents(fd, &num_extents)) return -1; printf("Extents in file \"%s\": %u\n", argv[1], num_extents); fiemap = malloc(sizeof(fiemap) + num_extents * sizeof(struct fiemap_extent)); if (fiemap == NULL) { fprintf(stderr, "malloc error %d: \"%s\"\n", errno, strerror(errno)); return -1; } fiemap->fm_start = map_start; fiemap->fm_length = map_len; fiemap->fm_extent_count = num_extents; ret = ioctl(fd, FS_IOC_FIEMAP, fiemap); if (ret == -1) { if (errno == EBADR) { fprintf(stderr, "Kernel does not support the flags: 0x%x\n", fiemap->fm_flags); return -1; } fprintf(stderr, "fiemap error %d: \"%s\"\n", errno, strerror(errno)); return -1; } show_results(fiemap); close(fd); return 0; }