fibmap.c revision 3f4bcefe561da90a2639436dc66a8e6e783ea040
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
17struct file_ext {
18	__u32 f_pos;
19	__u32 start_blk;
20	__u32 end_blk;
21	__u32 blk_count;
22};
23
24void 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
33void 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
51void 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
82out:
83	close(fd);
84
85}
86
87int 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);
162out:
163	close(fd);
164	return ret;
165}
166