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
print_ext(struct file_ext * ext)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
print_stat(struct stat64 * st)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
stat_bdev(struct stat64 * st,unsigned int * start_lba)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
main(int argc,char * argv[])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