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