1dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee#define _LARGEFILE64_SOURCE
2dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee#include <unistd.h>
3dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee#include <string.h>
4dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee#include <stdlib.h>
5dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee#include <stdio.h>
6dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee#include <fcntl.h>
7dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee#include <errno.h>
8379ff8916e8b3fd19bca44265b70e50584be2c31Natanael Copa#include <sys/types.h>
9dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee#include <sys/ioctl.h>
10dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee#include <sys/stat.h>
110e14e39d389bd01ff5419e8a1c1f0cc36cd170bdMike Frysinger#include <sys/sysmacros.h>
12b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee#include <libgen.h>
13b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee#include <linux/hdreg.h>
14dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee#include <linux/types.h>
1503ca33c40720a122e956989bd95f1229881dacaeJaegeuk Kim#include <linux/fs.h>
165a510076b737b734bdeab95dd4b597cdb681fb29Chao Yu#include <inttypes.h>
17dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
18dfe2a3384fbacb960463088176654bbf13c106e4Changman Leestruct file_ext {
19dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	__u32 f_pos;
20dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	__u32 start_blk;
21dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	__u32 end_blk;
22dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	__u32 blk_count;
23dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee};
24dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
25dfe2a3384fbacb960463088176654bbf13c106e4Changman Leevoid print_ext(struct file_ext *ext)
26dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee{
27dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	if (ext->end_blk == 0)
28dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		printf("%8d    %8d    %8d    %8d\n", ext->f_pos, 0, 0, ext->blk_count);
29dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	else
30dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		printf("%8d    %8d    %8d    %8d\n", ext->f_pos, ext->start_blk,
31dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee					ext->end_blk, ext->blk_count);
32dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee}
33dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
34e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Leevoid print_stat(struct stat64 *st)
35e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee{
36e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee	printf("--------------------------------------------\n");
37e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee	printf("dev       [%d:%d]\n", major(st->st_dev), minor(st->st_dev));
385a510076b737b734bdeab95dd4b597cdb681fb29Chao Yu	printf("ino       [0x%8"PRIx64" : %"PRIu64"]\n",
395a510076b737b734bdeab95dd4b597cdb681fb29Chao Yu						st->st_ino, st->st_ino);
40e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee	printf("mode      [0x%8x : %d]\n", st->st_mode, st->st_mode);
41e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee	printf("nlink     [0x%8lx : %ld]\n", st->st_nlink, st->st_nlink);
42e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee	printf("uid       [0x%8x : %d]\n", st->st_uid, st->st_uid);
43e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee	printf("gid       [0x%8x : %d]\n", st->st_gid, st->st_gid);
445a510076b737b734bdeab95dd4b597cdb681fb29Chao Yu	printf("size      [0x%8"PRIx64" : %"PRIu64"]\n",
455a510076b737b734bdeab95dd4b597cdb681fb29Chao Yu						st->st_size, st->st_size);
46e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee	printf("blksize   [0x%8lx : %ld]\n", st->st_blksize, st->st_blksize);
475a510076b737b734bdeab95dd4b597cdb681fb29Chao Yu	printf("blocks    [0x%8"PRIx64" : %"PRIu64"]\n",
485a510076b737b734bdeab95dd4b597cdb681fb29Chao Yu					st->st_blocks, st->st_blocks);
49e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee	printf("--------------------------------------------\n\n");
50e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee}
51e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee
52b611e1155a67be8220ceefc36d8ab5abae926d19Changman Leevoid stat_bdev(struct stat64 *st, unsigned int *start_lba)
53b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee{
54b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	struct stat bdev_stat;
55b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	struct hd_geometry geom;
56b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	char devname[32] = { 0, };
57b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	char linkname[32] = { 0, };
58b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	int fd;
59b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee
60b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	sprintf(devname, "/dev/block/%d:%d", major(st->st_dev), minor(st->st_dev));
61b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee
62b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	fd = open(devname, O_RDONLY);
63b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	if (fd < 0)
64b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee		return;
65b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee
66b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	if (fstat(fd, &bdev_stat) < 0)
67b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee		goto out;
68b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee
69b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	if (S_ISBLK(bdev_stat.st_mode)) {
70b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee		if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
71b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee			*start_lba = 0;
72b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee		else
73b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee			*start_lba = geom.start;
74b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	}
75b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee
76b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	if (readlink(devname, linkname, sizeof(linkname)) < 0)
77b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee		goto out;
78b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee
79b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	printf("----------------bdev info-------------------\n");
80b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	printf("devname = %s\n", basename(linkname));
81b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	printf("start_lba = %u\n", *start_lba);
82b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee
83b611e1155a67be8220ceefc36d8ab5abae926d19Changman Leeout:
84b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	close(fd);
85b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee
86b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee}
87b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee
88dfe2a3384fbacb960463088176654bbf13c106e4Changman Leeint main(int argc, char *argv[])
89dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee{
90dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	int fd;
91dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	int ret = 0;
92dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	char *filename;
93dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	struct stat64 st;
94dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	int total_blks;
95dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	unsigned int i;
96dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	struct file_ext ext;
97b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	__u32 start_lba;
98dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	__u32 blknum;
99dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
100dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	if (argc != 2) {
101dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		fprintf(stderr, "No filename\n");
102dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		exit(-1);
103dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	}
104dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	filename = argv[1];
105dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
106dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	fd = open(filename, O_RDONLY|O_LARGEFILE);
107dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	if (fd < 0) {
108dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		ret = errno;
109dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		perror(filename);
110dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		exit(-1);
111dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	}
112dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
113dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	fsync(fd);
114dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
115dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	if (fstat64(fd, &st) < 0) {
116dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		ret = errno;
117dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		perror(filename);
118dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		goto out;
119dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	}
120dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
121b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	stat_bdev(&st, &start_lba);
122b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee
123dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	total_blks = (st.st_size + st.st_blksize - 1) / st.st_blksize;
124dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
125b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	printf("\n----------------file info-------------------\n");
126b611e1155a67be8220ceefc36d8ab5abae926d19Changman Lee	printf("%s :\n", filename);
127e23d58533c631a1babd29dcf732c99c9cc4f8e89Changman Lee	print_stat(&st);
128dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	printf("file_pos   start_blk     end_blk        blks\n");
129dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
130dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	blknum = 0;
131dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	if (ioctl(fd, FIBMAP, &blknum) < 0) {
132dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		ret = errno;
133dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		perror("ioctl(FIBMAP)");
134dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		goto out;
135dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	}
136dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	ext.f_pos = 0;
137dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	ext.start_blk = blknum;
138dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	ext.end_blk = blknum;
139dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	ext.blk_count = 1;
140dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
141dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	for (i = 1; i < total_blks; i++) {
142dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		blknum = i;
143dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
144dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		if (ioctl(fd, FIBMAP, &blknum) < 0) {
145dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee			ret = errno;
146dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee			perror("ioctl(FIBMAP)");
147dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee			goto out;
148dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		}
149dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
150dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		if ((blknum == 0 && blknum == ext.end_blk) || (ext.end_blk + 1) == blknum) {
151dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee			ext.end_blk = blknum;
152dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee			ext.blk_count++;
153dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		} else {
154dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee			print_ext(&ext);
155dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee			ext.f_pos = i * st.st_blksize;
156dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee			ext.start_blk = blknum;
157dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee			ext.end_blk = blknum;
1581aae03594ba111174ed4902a29b969a1fb145adfJaegeuk Kim			ext.blk_count = 1;
159dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee		}
160dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	}
161dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee
162dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	print_ext(&ext);
163dfe2a3384fbacb960463088176654bbf13c106e4Changman Leeout:
164dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	close(fd);
165dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee	return ret;
166dfe2a3384fbacb960463088176654bbf13c106e4Changman Lee}
167