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