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