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