Print a list of disk blocks used by file(s) - Linux

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












This code takes a list of filenames as arguments or from stdin (or from a provided file) and dumps a list of disk blocks used by those files.



An attempt is made to use the linux ioctl function fiemap and if that fails (ex. on FAT filesystems) falls back to using the fibmap function.



This code compiles with VS Community 2017 on a Ubuntu Bionic system.



(Any suggestions as to better argument switches [such as using -o for output file and something else for offset will also be appreciated)



 /*
*
* 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.
*
*/

/*
* Copyright (C) 2018
* Author afuna
* parts Copyright (C) 2010 Canonical: Colin Ian King, colin.king@canonical.com
*/



#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.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)

printf("lsblocks - Dumps a list of blocks occupied by a file using FIEMAP or FIBMAP.n");
printf("nUsage: %s [file1 file2...]n", argv[0]);
printf("nYou can provide a list of newline delimited filenames from stdin.n");
printf("nOptions:n");
printf(
" -h show this help screen.n"
" -v print file information to stderr before dumping block numbers.n"
" use -vv to print to the output filen"
" -i <path> read filenames from <path>n"
" -s <path> save output to <path>n"
" -o <count> offset values by <count>.n"
" -d <dir> change working directory to <dir>.n"
" -f <format> format block values using the given string;n"
" you must provide the terminator (\n or ' ' etc.)n"
);


static unsigned long long offset = 0;
static int verbosity = 0;
static char* format = NULL;
static char* infile = NULL;
static char* outfile = NULL;

static FILE* fd_in = NULL;
static FILE* fd_out = NULL;
static FILE* fd_info = NULL;

struct fiemap *read_fiemap(int fd)

struct fiemap *fiemap;
int extents_size;

if ((fiemap = (struct fiemap*)malloc(sizeof(struct fiemap))) == NULL)
fprintf(stderr, "Out of memory allocating fiemapn");
return NULL;

memset(fiemap, 0, sizeof(struct fiemap));

fiemap->fm_start = 0;
fiemap->fm_length = ~0; /* Lazy */
fiemap->fm_flags = 0;
fiemap->fm_extent_count = 0;
fiemap->fm_mapped_extents = 0;

/* Find out how many extents there are */
if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0)
perror("fiemap ioctl() failed: ");
//fprintf(stderr, "fiemap ioctl() failedn");
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)
perror("Out of memory allocating fiemap: ");
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)
perror("fiemap ioctl() failed: ");
return NULL;


return fiemap;


void dump_fiemap(struct fiemap *fiemap, char *filename)
if (verbosity > 0)
fprintf(fd_info, "blocksize %dn", 512);

for (int i = 0; i < fiemap->fm_mapped_extents; i++)
unsigned long long base = offset + (fiemap->fm_extents[i].fe_physical / 512);
unsigned long long count = fiemap->fm_extents[i].fe_length / 512;
for (int j = 0; j < count; j++)
fprintf(fd_out, format, base++);




void dump_fibmap(int fd)
int block, blocksize, blkcnt;
struct stat st;

if (ioctl(fd, FIGETBSZ, &blocksize))
perror("FIBMAP ioctl failed: ");
return;


if (fstat(fd, &st))
perror("fstat error");
return;


blkcnt = (st.st_size + blocksize - 1) / blocksize;

if (verbosity > 0)
fprintf(fd_info, "size %d blocks %d blocksize %dn", (int)st.st_size, blkcnt, blocksize);

for (int i = 0; i < blkcnt; i++)
block = i;
if (ioctl(fd, FIBMAP, &block))
perror("FIBMAP ioctl failed: ");

else
int result;
result = fprintf(fd_out, format, offset + block);
if (result < 0)
perror("failed write: ");





void dump(char* path)

int fd;

if ((fd = open(path, O_RDONLY)) < 0)
fprintf(stderr, "Cannot open file %sn", path);
perror(NULL);

else
fprintf(fd_info, "Dumping file %s ", path);

struct fiemap *fiemap;

fiemap = read_fiemap(fd);
fiemap != NULL ? dump_fiemap(fiemap, path) : dump_fibmap(fd);
close(fd);




int main(int argc, char **argv)

char* path = NULL;

opterr = 0;

int opt = 0;
while ((opt = getopt(argc, argv, "o:f:d:i:s:vh")) != -1)
switch (opt)

case 'o':
offset = strtoull(optarg, NULL, 10);
break;
case 'f':
format = optarg;
break;
case 'd':
if (chdir(optarg) != 0)
perror("Failed to change working directory: ");
return EXIT_FAILURE;

break;
case 'i':
infile = optarg;
break;
case 's':
outfile = optarg;
case 'v':
verbosity++;
break;
case 'h':
syntax(argv);
return EXIT_SUCCESS;
case '?':
if (optopt == 'c')
fprintf(stderr, "Option -%c requires an argument.n", optopt);
else if (isprint(optopt))
fprintf(stderr, "Unknown option '-%c'.n", optopt);
else
fprintf(stderr, "Unknown option character '\x%x'.n", optopt);
return EXIT_FAILURE;
default:
abort();


if (format == NULL)
format = "%llun";

if (infile == NULL)
fd_in = stdin;
else if ((fd_in = fopen(infile, "rb")) == NULL)
perror("Cannot open input file: ");
exit(EXIT_FAILURE);


if (outfile == NULL)
fd_out = stdout;
else if ((fd_out = fopen(outfile, "w")) == NULL)
perror("Cannot open output file: ");
return EXIT_FAILURE;


fd_info = verbosity <= 1 ? stderr : fd_out;

if (optind == argc






share|improve this question



















  • @Coal_ good idea; i've 'touched' almost all of the code so I'm not sure if it will be worth it...
    – afuna
    Jun 10 at 15:43
















up vote
3
down vote

favorite












This code takes a list of filenames as arguments or from stdin (or from a provided file) and dumps a list of disk blocks used by those files.



An attempt is made to use the linux ioctl function fiemap and if that fails (ex. on FAT filesystems) falls back to using the fibmap function.



This code compiles with VS Community 2017 on a Ubuntu Bionic system.



(Any suggestions as to better argument switches [such as using -o for output file and something else for offset will also be appreciated)



 /*
*
* 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.
*
*/

/*
* Copyright (C) 2018
* Author afuna
* parts Copyright (C) 2010 Canonical: Colin Ian King, colin.king@canonical.com
*/



#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.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)

printf("lsblocks - Dumps a list of blocks occupied by a file using FIEMAP or FIBMAP.n");
printf("nUsage: %s [file1 file2...]n", argv[0]);
printf("nYou can provide a list of newline delimited filenames from stdin.n");
printf("nOptions:n");
printf(
" -h show this help screen.n"
" -v print file information to stderr before dumping block numbers.n"
" use -vv to print to the output filen"
" -i <path> read filenames from <path>n"
" -s <path> save output to <path>n"
" -o <count> offset values by <count>.n"
" -d <dir> change working directory to <dir>.n"
" -f <format> format block values using the given string;n"
" you must provide the terminator (\n or ' ' etc.)n"
);


static unsigned long long offset = 0;
static int verbosity = 0;
static char* format = NULL;
static char* infile = NULL;
static char* outfile = NULL;

static FILE* fd_in = NULL;
static FILE* fd_out = NULL;
static FILE* fd_info = NULL;

struct fiemap *read_fiemap(int fd)

struct fiemap *fiemap;
int extents_size;

if ((fiemap = (struct fiemap*)malloc(sizeof(struct fiemap))) == NULL)
fprintf(stderr, "Out of memory allocating fiemapn");
return NULL;

memset(fiemap, 0, sizeof(struct fiemap));

fiemap->fm_start = 0;
fiemap->fm_length = ~0; /* Lazy */
fiemap->fm_flags = 0;
fiemap->fm_extent_count = 0;
fiemap->fm_mapped_extents = 0;

/* Find out how many extents there are */
if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0)
perror("fiemap ioctl() failed: ");
//fprintf(stderr, "fiemap ioctl() failedn");
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)
perror("Out of memory allocating fiemap: ");
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)
perror("fiemap ioctl() failed: ");
return NULL;


return fiemap;


void dump_fiemap(struct fiemap *fiemap, char *filename)
if (verbosity > 0)
fprintf(fd_info, "blocksize %dn", 512);

for (int i = 0; i < fiemap->fm_mapped_extents; i++)
unsigned long long base = offset + (fiemap->fm_extents[i].fe_physical / 512);
unsigned long long count = fiemap->fm_extents[i].fe_length / 512;
for (int j = 0; j < count; j++)
fprintf(fd_out, format, base++);




void dump_fibmap(int fd)
int block, blocksize, blkcnt;
struct stat st;

if (ioctl(fd, FIGETBSZ, &blocksize))
perror("FIBMAP ioctl failed: ");
return;


if (fstat(fd, &st))
perror("fstat error");
return;


blkcnt = (st.st_size + blocksize - 1) / blocksize;

if (verbosity > 0)
fprintf(fd_info, "size %d blocks %d blocksize %dn", (int)st.st_size, blkcnt, blocksize);

for (int i = 0; i < blkcnt; i++)
block = i;
if (ioctl(fd, FIBMAP, &block))
perror("FIBMAP ioctl failed: ");

else
int result;
result = fprintf(fd_out, format, offset + block);
if (result < 0)
perror("failed write: ");





void dump(char* path)

int fd;

if ((fd = open(path, O_RDONLY)) < 0)
fprintf(stderr, "Cannot open file %sn", path);
perror(NULL);

else
fprintf(fd_info, "Dumping file %s ", path);

struct fiemap *fiemap;

fiemap = read_fiemap(fd);
fiemap != NULL ? dump_fiemap(fiemap, path) : dump_fibmap(fd);
close(fd);




int main(int argc, char **argv)

char* path = NULL;

opterr = 0;

int opt = 0;
while ((opt = getopt(argc, argv, "o:f:d:i:s:vh")) != -1)
switch (opt)

case 'o':
offset = strtoull(optarg, NULL, 10);
break;
case 'f':
format = optarg;
break;
case 'd':
if (chdir(optarg) != 0)
perror("Failed to change working directory: ");
return EXIT_FAILURE;

break;
case 'i':
infile = optarg;
break;
case 's':
outfile = optarg;
case 'v':
verbosity++;
break;
case 'h':
syntax(argv);
return EXIT_SUCCESS;
case '?':
if (optopt == 'c')
fprintf(stderr, "Option -%c requires an argument.n", optopt);
else if (isprint(optopt))
fprintf(stderr, "Unknown option '-%c'.n", optopt);
else
fprintf(stderr, "Unknown option character '\x%x'.n", optopt);
return EXIT_FAILURE;
default:
abort();


if (format == NULL)
format = "%llun";

if (infile == NULL)
fd_in = stdin;
else if ((fd_in = fopen(infile, "rb")) == NULL)
perror("Cannot open input file: ");
exit(EXIT_FAILURE);


if (outfile == NULL)
fd_out = stdout;
else if ((fd_out = fopen(outfile, "w")) == NULL)
perror("Cannot open output file: ");
return EXIT_FAILURE;


fd_info = verbosity <= 1 ? stderr : fd_out;

if (optind == argc






share|improve this question



















  • @Coal_ good idea; i've 'touched' almost all of the code so I'm not sure if it will be worth it...
    – afuna
    Jun 10 at 15:43












up vote
3
down vote

favorite









up vote
3
down vote

favorite











This code takes a list of filenames as arguments or from stdin (or from a provided file) and dumps a list of disk blocks used by those files.



An attempt is made to use the linux ioctl function fiemap and if that fails (ex. on FAT filesystems) falls back to using the fibmap function.



This code compiles with VS Community 2017 on a Ubuntu Bionic system.



(Any suggestions as to better argument switches [such as using -o for output file and something else for offset will also be appreciated)



 /*
*
* 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.
*
*/

/*
* Copyright (C) 2018
* Author afuna
* parts Copyright (C) 2010 Canonical: Colin Ian King, colin.king@canonical.com
*/



#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.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)

printf("lsblocks - Dumps a list of blocks occupied by a file using FIEMAP or FIBMAP.n");
printf("nUsage: %s [file1 file2...]n", argv[0]);
printf("nYou can provide a list of newline delimited filenames from stdin.n");
printf("nOptions:n");
printf(
" -h show this help screen.n"
" -v print file information to stderr before dumping block numbers.n"
" use -vv to print to the output filen"
" -i <path> read filenames from <path>n"
" -s <path> save output to <path>n"
" -o <count> offset values by <count>.n"
" -d <dir> change working directory to <dir>.n"
" -f <format> format block values using the given string;n"
" you must provide the terminator (\n or ' ' etc.)n"
);


static unsigned long long offset = 0;
static int verbosity = 0;
static char* format = NULL;
static char* infile = NULL;
static char* outfile = NULL;

static FILE* fd_in = NULL;
static FILE* fd_out = NULL;
static FILE* fd_info = NULL;

struct fiemap *read_fiemap(int fd)

struct fiemap *fiemap;
int extents_size;

if ((fiemap = (struct fiemap*)malloc(sizeof(struct fiemap))) == NULL)
fprintf(stderr, "Out of memory allocating fiemapn");
return NULL;

memset(fiemap, 0, sizeof(struct fiemap));

fiemap->fm_start = 0;
fiemap->fm_length = ~0; /* Lazy */
fiemap->fm_flags = 0;
fiemap->fm_extent_count = 0;
fiemap->fm_mapped_extents = 0;

/* Find out how many extents there are */
if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0)
perror("fiemap ioctl() failed: ");
//fprintf(stderr, "fiemap ioctl() failedn");
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)
perror("Out of memory allocating fiemap: ");
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)
perror("fiemap ioctl() failed: ");
return NULL;


return fiemap;


void dump_fiemap(struct fiemap *fiemap, char *filename)
if (verbosity > 0)
fprintf(fd_info, "blocksize %dn", 512);

for (int i = 0; i < fiemap->fm_mapped_extents; i++)
unsigned long long base = offset + (fiemap->fm_extents[i].fe_physical / 512);
unsigned long long count = fiemap->fm_extents[i].fe_length / 512;
for (int j = 0; j < count; j++)
fprintf(fd_out, format, base++);




void dump_fibmap(int fd)
int block, blocksize, blkcnt;
struct stat st;

if (ioctl(fd, FIGETBSZ, &blocksize))
perror("FIBMAP ioctl failed: ");
return;


if (fstat(fd, &st))
perror("fstat error");
return;


blkcnt = (st.st_size + blocksize - 1) / blocksize;

if (verbosity > 0)
fprintf(fd_info, "size %d blocks %d blocksize %dn", (int)st.st_size, blkcnt, blocksize);

for (int i = 0; i < blkcnt; i++)
block = i;
if (ioctl(fd, FIBMAP, &block))
perror("FIBMAP ioctl failed: ");

else
int result;
result = fprintf(fd_out, format, offset + block);
if (result < 0)
perror("failed write: ");





void dump(char* path)

int fd;

if ((fd = open(path, O_RDONLY)) < 0)
fprintf(stderr, "Cannot open file %sn", path);
perror(NULL);

else
fprintf(fd_info, "Dumping file %s ", path);

struct fiemap *fiemap;

fiemap = read_fiemap(fd);
fiemap != NULL ? dump_fiemap(fiemap, path) : dump_fibmap(fd);
close(fd);




int main(int argc, char **argv)

char* path = NULL;

opterr = 0;

int opt = 0;
while ((opt = getopt(argc, argv, "o:f:d:i:s:vh")) != -1)
switch (opt)

case 'o':
offset = strtoull(optarg, NULL, 10);
break;
case 'f':
format = optarg;
break;
case 'd':
if (chdir(optarg) != 0)
perror("Failed to change working directory: ");
return EXIT_FAILURE;

break;
case 'i':
infile = optarg;
break;
case 's':
outfile = optarg;
case 'v':
verbosity++;
break;
case 'h':
syntax(argv);
return EXIT_SUCCESS;
case '?':
if (optopt == 'c')
fprintf(stderr, "Option -%c requires an argument.n", optopt);
else if (isprint(optopt))
fprintf(stderr, "Unknown option '-%c'.n", optopt);
else
fprintf(stderr, "Unknown option character '\x%x'.n", optopt);
return EXIT_FAILURE;
default:
abort();


if (format == NULL)
format = "%llun";

if (infile == NULL)
fd_in = stdin;
else if ((fd_in = fopen(infile, "rb")) == NULL)
perror("Cannot open input file: ");
exit(EXIT_FAILURE);


if (outfile == NULL)
fd_out = stdout;
else if ((fd_out = fopen(outfile, "w")) == NULL)
perror("Cannot open output file: ");
return EXIT_FAILURE;


fd_info = verbosity <= 1 ? stderr : fd_out;

if (optind == argc






share|improve this question











This code takes a list of filenames as arguments or from stdin (or from a provided file) and dumps a list of disk blocks used by those files.



An attempt is made to use the linux ioctl function fiemap and if that fails (ex. on FAT filesystems) falls back to using the fibmap function.



This code compiles with VS Community 2017 on a Ubuntu Bionic system.



(Any suggestions as to better argument switches [such as using -o for output file and something else for offset will also be appreciated)



 /*
*
* 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.
*
*/

/*
* Copyright (C) 2018
* Author afuna
* parts Copyright (C) 2010 Canonical: Colin Ian King, colin.king@canonical.com
*/



#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.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)

printf("lsblocks - Dumps a list of blocks occupied by a file using FIEMAP or FIBMAP.n");
printf("nUsage: %s [file1 file2...]n", argv[0]);
printf("nYou can provide a list of newline delimited filenames from stdin.n");
printf("nOptions:n");
printf(
" -h show this help screen.n"
" -v print file information to stderr before dumping block numbers.n"
" use -vv to print to the output filen"
" -i <path> read filenames from <path>n"
" -s <path> save output to <path>n"
" -o <count> offset values by <count>.n"
" -d <dir> change working directory to <dir>.n"
" -f <format> format block values using the given string;n"
" you must provide the terminator (\n or ' ' etc.)n"
);


static unsigned long long offset = 0;
static int verbosity = 0;
static char* format = NULL;
static char* infile = NULL;
static char* outfile = NULL;

static FILE* fd_in = NULL;
static FILE* fd_out = NULL;
static FILE* fd_info = NULL;

struct fiemap *read_fiemap(int fd)

struct fiemap *fiemap;
int extents_size;

if ((fiemap = (struct fiemap*)malloc(sizeof(struct fiemap))) == NULL)
fprintf(stderr, "Out of memory allocating fiemapn");
return NULL;

memset(fiemap, 0, sizeof(struct fiemap));

fiemap->fm_start = 0;
fiemap->fm_length = ~0; /* Lazy */
fiemap->fm_flags = 0;
fiemap->fm_extent_count = 0;
fiemap->fm_mapped_extents = 0;

/* Find out how many extents there are */
if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0)
perror("fiemap ioctl() failed: ");
//fprintf(stderr, "fiemap ioctl() failedn");
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)
perror("Out of memory allocating fiemap: ");
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)
perror("fiemap ioctl() failed: ");
return NULL;


return fiemap;


void dump_fiemap(struct fiemap *fiemap, char *filename)
if (verbosity > 0)
fprintf(fd_info, "blocksize %dn", 512);

for (int i = 0; i < fiemap->fm_mapped_extents; i++)
unsigned long long base = offset + (fiemap->fm_extents[i].fe_physical / 512);
unsigned long long count = fiemap->fm_extents[i].fe_length / 512;
for (int j = 0; j < count; j++)
fprintf(fd_out, format, base++);




void dump_fibmap(int fd)
int block, blocksize, blkcnt;
struct stat st;

if (ioctl(fd, FIGETBSZ, &blocksize))
perror("FIBMAP ioctl failed: ");
return;


if (fstat(fd, &st))
perror("fstat error");
return;


blkcnt = (st.st_size + blocksize - 1) / blocksize;

if (verbosity > 0)
fprintf(fd_info, "size %d blocks %d blocksize %dn", (int)st.st_size, blkcnt, blocksize);

for (int i = 0; i < blkcnt; i++)
block = i;
if (ioctl(fd, FIBMAP, &block))
perror("FIBMAP ioctl failed: ");

else
int result;
result = fprintf(fd_out, format, offset + block);
if (result < 0)
perror("failed write: ");





void dump(char* path)

int fd;

if ((fd = open(path, O_RDONLY)) < 0)
fprintf(stderr, "Cannot open file %sn", path);
perror(NULL);

else
fprintf(fd_info, "Dumping file %s ", path);

struct fiemap *fiemap;

fiemap = read_fiemap(fd);
fiemap != NULL ? dump_fiemap(fiemap, path) : dump_fibmap(fd);
close(fd);




int main(int argc, char **argv)

char* path = NULL;

opterr = 0;

int opt = 0;
while ((opt = getopt(argc, argv, "o:f:d:i:s:vh")) != -1)
switch (opt)

case 'o':
offset = strtoull(optarg, NULL, 10);
break;
case 'f':
format = optarg;
break;
case 'd':
if (chdir(optarg) != 0)
perror("Failed to change working directory: ");
return EXIT_FAILURE;

break;
case 'i':
infile = optarg;
break;
case 's':
outfile = optarg;
case 'v':
verbosity++;
break;
case 'h':
syntax(argv);
return EXIT_SUCCESS;
case '?':
if (optopt == 'c')
fprintf(stderr, "Option -%c requires an argument.n", optopt);
else if (isprint(optopt))
fprintf(stderr, "Unknown option '-%c'.n", optopt);
else
fprintf(stderr, "Unknown option character '\x%x'.n", optopt);
return EXIT_FAILURE;
default:
abort();


if (format == NULL)
format = "%llun";

if (infile == NULL)
fd_in = stdin;
else if ((fd_in = fopen(infile, "rb")) == NULL)
perror("Cannot open input file: ");
exit(EXIT_FAILURE);


if (outfile == NULL)
fd_out = stdout;
else if ((fd_out = fopen(outfile, "w")) == NULL)
perror("Cannot open output file: ");
return EXIT_FAILURE;


fd_info = verbosity <= 1 ? stderr : fd_out;

if (optind == argc








share|improve this question










share|improve this question




share|improve this question









asked Jun 10 at 14:37









afuna

18217




18217











  • @Coal_ good idea; i've 'touched' almost all of the code so I'm not sure if it will be worth it...
    – afuna
    Jun 10 at 15:43
















  • @Coal_ good idea; i've 'touched' almost all of the code so I'm not sure if it will be worth it...
    – afuna
    Jun 10 at 15:43















@Coal_ good idea; i've 'touched' almost all of the code so I'm not sure if it will be worth it...
– afuna
Jun 10 at 15:43




@Coal_ good idea; i've 'touched' almost all of the code so I'm not sure if it will be worth it...
– afuna
Jun 10 at 15:43















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f196234%2fprint-a-list-of-disk-blocks-used-by-files-linux%23new-answer', 'question_page');

);

Post as a guest



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f196234%2fprint-a-list-of-disk-blocks-used-by-files-linux%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Python Lists

Aion

JavaScript Array Iteration Methods