• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 struct file_ext {
18 	__u32 f_pos;
19 	__u32 start_blk;
20 	__u32 end_blk;
21 	__u32 blk_count;
22 };
23 
print_ext(struct file_ext * ext)24 void 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 
print_stat(struct stat64 * st)33 void 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 
stat_bdev(struct stat64 * st,unsigned int * start_lba)51 void 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 
82 out:
83 	close(fd);
84 
85 }
86 
main(int argc,char * argv[])87 int 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);
162 out:
163 	close(fd);
164 	return ret;
165 }
166