1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
#define _LARGEFILE64_SOURCE
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <libgen.h>
#include <linux/hdreg.h>
#include <linux/types.h>
#include <linux/fs.h>
struct file_ext {
__u32 f_pos;
__u32 start_blk;
__u32 end_blk;
__u32 blk_count;
};
void print_ext(struct file_ext *ext)
{
if (ext->end_blk == 0)
printf("%8d %8d %8d %8d\n", ext->f_pos, 0, 0, ext->blk_count);
else
printf("%8d %8d %8d %8d\n", ext->f_pos, ext->start_blk,
ext->end_blk, ext->blk_count);
}
void print_stat(struct stat64 *st)
{
printf("--------------------------------------------\n");
printf("dev [%d:%d]\n", major(st->st_dev), minor(st->st_dev));
printf("ino [0x%8lx : %ld]\n", st->st_ino, st->st_ino);
printf("mode [0x%8x : %d]\n", st->st_mode, st->st_mode);
printf("nlink [0x%8lx : %ld]\n", st->st_nlink, st->st_nlink);
printf("uid [0x%8x : %d]\n", st->st_uid, st->st_uid);
printf("gid [0x%8x : %d]\n", st->st_gid, st->st_gid);
printf("size [0x%8lx : %ld]\n", st->st_size, st->st_size);
printf("blksize [0x%8lx : %ld]\n", st->st_blksize, st->st_blksize);
printf("blocks [0x%8lx : %ld]\n", st->st_blocks, st->st_blocks);
printf("--------------------------------------------\n\n");
}
void stat_bdev(struct stat64 *st, unsigned int *start_lba)
{
struct stat bdev_stat;
struct hd_geometry geom;
char devname[32] = { 0, };
char linkname[32] = { 0, };
int fd;
sprintf(devname, "/dev/block/%d:%d", major(st->st_dev), minor(st->st_dev));
fd = open(devname, O_RDONLY);
if (fd < 0)
return;
if (fstat(fd, &bdev_stat) < 0)
goto out;
if (S_ISBLK(bdev_stat.st_mode)) {
if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
*start_lba = 0;
else
*start_lba = geom.start;
}
if (readlink(devname, linkname, sizeof(linkname)) < 0)
goto out;
printf("----------------bdev info-------------------\n");
printf("devname = %s\n", basename(linkname));
printf("start_lba = %u\n", *start_lba);
out:
close(fd);
}
int main(int argc, char *argv[])
{
int fd;
int ret = 0;
char *filename;
struct stat64 st;
int total_blks;
unsigned int i;
struct file_ext ext;
__u32 start_lba;
__u32 blknum;
if (argc != 2) {
fprintf(stderr, "No filename\n");
exit(-1);
}
filename = argv[1];
fd = open(filename, O_RDONLY|O_LARGEFILE);
if (fd < 0) {
ret = errno;
perror(filename);
exit(-1);
}
fsync(fd);
if (fstat64(fd, &st) < 0) {
ret = errno;
perror(filename);
goto out;
}
stat_bdev(&st, &start_lba);
total_blks = (st.st_size + st.st_blksize - 1) / st.st_blksize;
printf("\n----------------file info-------------------\n");
printf("%s :\n", filename);
print_stat(&st);
printf("file_pos start_blk end_blk blks\n");
blknum = 0;
if (ioctl(fd, FIBMAP, &blknum) < 0) {
ret = errno;
perror("ioctl(FIBMAP)");
goto out;
}
ext.f_pos = 0;
ext.start_blk = blknum;
ext.end_blk = blknum;
ext.blk_count = 1;
for (i = 1; i < total_blks; i++) {
blknum = i;
if (ioctl(fd, FIBMAP, &blknum) < 0) {
ret = errno;
perror("ioctl(FIBMAP)");
goto out;
}
if ((blknum == 0 && blknum == ext.end_blk) || (ext.end_blk + 1) == blknum) {
ext.end_blk = blknum;
ext.blk_count++;
} else {
print_ext(&ext);
ext.f_pos = i * st.st_blksize;
ext.start_blk = blknum;
ext.end_blk = blknum;
ext.blk_count = 1;
}
}
print_ext(&ext);
out:
close(fd);
return ret;
}
|