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
18 struct file_ext {
19 __u32 f_pos;
20 __u32 start_blk;
21 __u32 end_blk;
22 __u32 blk_count;
23 };
24
print_ext(struct file_ext * ext)25 void 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
print_stat(struct stat64 * st)34 void 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
stat_bdev(struct stat64 * st,unsigned int * start_lba)52 void 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
83 out:
84 close(fd);
85
86 }
87
main(int argc,char * argv[])88 int 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);
163 out:
164 close(fd);
165 return ret;
166 }
167