Original rom http://smackerelofopinion.blogspot.de/2010/01/using-fiemap-ioctl-to-get-file-extents.html Extended by David Weber
/* | |
* Copyright (C) 2010 Canonical | |
* | |
* This program is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU General Public License | |
* as published by the Free Software Foundation; either version 2 | |
* of the License, or (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program; if not, write to the Free Software | |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
* | |
*/ | |
/* | |
* Author Colin Ian King, colin.king@canonical.com | |
*/ | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <sys/ioctl.h> | |
#include <linux/fs.h> | |
#include <linux/fiemap.h> | |
void syntax(char **argv) | |
{ | |
fprintf(stderr, "%s [filename] [start] [length]...\n",argv[0]); | |
} | |
struct fiemap *read_fiemap(int fd, __u64 start, __u64 length) | |
{ | |
struct fiemap *fiemap; | |
int extents_size; | |
if ((fiemap = (struct fiemap*)malloc(sizeof(struct fiemap))) == NULL) { | |
fprintf(stderr, "Out of memory allocating fiemap\n"); | |
return NULL; | |
} | |
memset(fiemap, 0, sizeof(struct fiemap)); | |
fiemap->fm_start = start; | |
fiemap->fm_length = length; /* Lazy */ | |
fiemap->fm_flags = 0; | |
fiemap->fm_extent_count = 0; | |
fiemap->fm_mapped_extents = 0; | |
printf("start: %x, length: %x\n", start, length); | |
/* Find out how many extents there are */ | |
if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0) { | |
fprintf(stderr, "fiemap ioctl() failed\n"); | |
return NULL; | |
} | |
/* Read in the extents */ | |
extents_size = sizeof(struct fiemap_extent) * | |
(fiemap->fm_mapped_extents); | |
/* Resize fiemap to allow us to read in the extents */ | |
if ((fiemap = (struct fiemap*)realloc(fiemap,sizeof(struct fiemap) + | |
extents_size)) == NULL) { | |
fprintf(stderr, "Out of memory allocating fiemap\n"); | |
return NULL; | |
} | |
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) { | |
fprintf(stderr, "fiemap ioctl() failed\n"); | |
return NULL; | |
} | |
return fiemap; | |
} | |
void dump_fiemap(struct fiemap *fiemap, char *filename) | |
{ | |
int i; | |
printf("File %s has %d extents:\n",filename, fiemap->fm_mapped_extents); | |
printf("#\tLogical Physical Length Flags\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"); | |
} | |
int main(int argc, char **argv) | |
{ | |
int i; | |
if (argc < 4) { | |
syntax(argv); | |
exit(EXIT_FAILURE); | |
} | |
int fd; | |
if ((fd = open(argv[1], O_RDONLY)) < 0) { | |
fprintf(stderr, "Cannot open file %s\n", argv[i]); | |
} | |
else { | |
struct fiemap *fiemap; | |
if ((fiemap = read_fiemap(fd, (__u64)atoi(argv[2]), (__u64)atoi(argv[3]))) != NULL) | |
dump_fiemap(fiemap, argv[1]); | |
close(fd); | |
} | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment