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