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

Clash 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
c file-system linux
add a comment |Â
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
c file-system linux
@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
add a comment |Â
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
c file-system linux
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
c file-system linux
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
add a comment |Â
@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
add a comment |Â
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
@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