1 #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
2 #define _XOPEN_SOURCE 600
3 #define _DARWIN_C_SOURCE
4 #define _FILE_OFFSET_BITS 64
5 #ifndef _LARGEFILE_SOURCE
6 #define _LARGEFILE_SOURCE
7 #endif
8 #ifndef _LARGEFILE64_SOURCE
9 #define _LARGEFILE64_SOURCE
10 #endif
11 #ifndef _GNU_SOURCE
12 #define _GNU_SOURCE
13 #endif
14 #endif
15 #ifndef O_LARGEFILE
16 #define O_LARGEFILE 0
17 #endif
18 #include <f2fs_fs.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <sys/types.h>
26 #ifdef HAVE_SYS_IOCTL_H
27 #include <sys/ioctl.h>
28 #endif
29 #include <sys/stat.h>
30 #ifdef HAVE_SYS_SYSMACROS_H
31 #include <sys/sysmacros.h>
32 #endif
33 #include <libgen.h>
34 #ifdef HAVE_LINUX_HDREG_H
35 #include <linux/hdreg.h>
36 #endif
37 #ifdef HAVE_LINUX_TYPES_H
38 #include <linux/types.h>
39 #endif
40 #ifdef __KERNEL__
41 #include <linux/fs.h>
42 #endif
43 #include <inttypes.h>
44
45 #ifndef FIBMAP
46 #define FIBMAP _IO(0x00, 1) /* bmap access */
47 #endif
48
49 struct file_ext {
50 __u32 f_pos;
51 __u32 start_blk;
52 __u32 end_blk;
53 __u32 blk_count;
54 };
55
print_ext(struct file_ext * ext)56 void print_ext(struct file_ext *ext)
57 {
58 if (ext->end_blk == 0)
59 printf("%8d %8d %8d %8d\n", ext->f_pos, 0, 0, ext->blk_count);
60 else
61 printf("%8d %8d %8d %8d\n", ext->f_pos, ext->start_blk,
62 ext->end_blk, ext->blk_count);
63 }
64
65 #if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
print_stat(struct stat64 * st)66 void print_stat(struct stat64 *st)
67 #else
68 void print_stat(struct stat *st)
69 #endif
70 {
71 printf("--------------------------------------------\n");
72 printf("dev [%d:%d]\n", major(st->st_dev), minor(st->st_dev));
73 printf("ino [0x%8"PRIx64" : %"PRIu64"]\n",
74 st->st_ino, st->st_ino);
75 printf("mode [0x%8x : %d]\n", st->st_mode, st->st_mode);
76 printf("nlink [0x%8lx : %ld]\n",
77 (unsigned long)st->st_nlink,
78 (long)st->st_nlink);
79 printf("uid [0x%8x : %d]\n", st->st_uid, st->st_uid);
80 printf("gid [0x%8x : %d]\n", st->st_gid, st->st_gid);
81 printf("size [0x%8"PRIx64" : %"PRIu64"]\n",
82 (u64)st->st_size, (u64)st->st_size);
83 printf("blksize [0x%8lx : %ld]\n",
84 (unsigned long)st->st_blksize,
85 (long)st->st_blksize);
86 printf("blocks [0x%8"PRIx64" : %"PRIu64"]\n",
87 (u64)st->st_blocks, (u64)st->st_blocks);
88 printf("--------------------------------------------\n\n");
89 }
90
91 #if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
stat_bdev(struct stat64 * st,unsigned int * start_lba)92 static void stat_bdev(struct stat64 *st, unsigned int *start_lba)
93 #else
94 static void stat_bdev(struct stat *st, unsigned int *start_lba)
95 #endif
96 {
97 struct stat bdev_stat;
98 #ifdef HDIO_GETGIO
99 struct hd_geometry geom;
100 #endif
101 char devname[32] = { 0, };
102 char linkname[32] = { 0, };
103 int fd;
104
105 sprintf(devname, "/dev/block/%d:%d", major(st->st_dev), minor(st->st_dev));
106
107 fd = open(devname, O_RDONLY);
108 if (fd < 0)
109 return;
110
111 if (fstat(fd, &bdev_stat) < 0)
112 goto out;
113
114 if (S_ISBLK(bdev_stat.st_mode)) {
115 #ifdef HDIO_GETGIO
116 if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
117 *start_lba = 0;
118 else
119 *start_lba = geom.start;
120 #else
121 *start_lba = 0;
122 #endif
123 }
124
125 if (readlink(devname, linkname, sizeof(linkname)) < 0)
126 goto out;
127
128 printf("----------------bdev info-------------------\n");
129 printf("devname = %s\n", basename(linkname));
130 printf("start_lba = %u\n", *start_lba);
131
132 out:
133 close(fd);
134
135 }
136
main(int argc,char * argv[])137 int main(int argc, char *argv[])
138 {
139 int fd;
140 int ret = 0;
141 char *filename;
142 #if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
143 struct stat64 st;
144 #else
145 struct stat st;
146 #endif
147 int total_blks;
148 unsigned int i;
149 struct file_ext ext;
150 __u32 start_lba;
151 __u32 blknum;
152
153 if (argc != 2) {
154 fprintf(stderr, "No filename\n");
155 exit(-1);
156 }
157 filename = argv[1];
158
159 fd = open(filename, O_RDONLY|O_LARGEFILE);
160 if (fd < 0) {
161 ret = errno;
162 perror(filename);
163 exit(-1);
164 }
165
166 fsync(fd);
167
168 #if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
169 if (fstat64(fd, &st) < 0) {
170 #else
171 if (fstat(fd, &st) < 0) {
172 #endif
173 ret = errno;
174 perror(filename);
175 goto out;
176 }
177
178 stat_bdev(&st, &start_lba);
179
180 total_blks = (st.st_size + st.st_blksize - 1) / st.st_blksize;
181
182 printf("\n----------------file info-------------------\n");
183 printf("%s :\n", filename);
184 print_stat(&st);
185 printf("file_pos start_blk end_blk blks\n");
186
187 blknum = 0;
188 if (ioctl(fd, FIBMAP, &blknum) < 0) {
189 ret = errno;
190 perror("ioctl(FIBMAP)");
191 goto out;
192 }
193 ext.f_pos = 0;
194 ext.start_blk = blknum;
195 ext.end_blk = blknum;
196 ext.blk_count = 1;
197
198 for (i = 1; i < total_blks; i++) {
199 blknum = i;
200
201 if (ioctl(fd, FIBMAP, &blknum) < 0) {
202 ret = errno;
203 perror("ioctl(FIBMAP)");
204 goto out;
205 }
206
207 if ((blknum == 0 && blknum == ext.end_blk) || (ext.end_blk + 1) == blknum) {
208 ext.end_blk = blknum;
209 ext.blk_count++;
210 } else {
211 print_ext(&ext);
212 ext.f_pos = i * st.st_blksize;
213 ext.start_blk = blknum;
214 ext.end_blk = blknum;
215 ext.blk_count = 1;
216 }
217 }
218
219 print_ext(&ext);
220 out:
221 close(fd);
222 return ret;
223 }
224