xref: /aosp_15_r20/external/e2fsprogs/contrib/ext4-ioc.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
1 /*
2  * Test program to trigger various ext4 ioctl's
3  */
4 
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <fcntl.h>
10 #include <sys/ioctl.h>
11 
12 #if (!defined(EXT4_IOC_ALLOC_DA_BLKS) && defined(__linux__))
13 #define EXT4_IOC_ALLOC_DA_BLKS		_IO('f', 12)
14 #endif
15 
16 #if (!defined(EXT4_IOC_SWAP_BOOT) && defined(__linux__))
17 #define EXT4_IOC_SWAP_BOOT		_IO('f', 17)
18 #endif
19 
20 #if (!defined(EXT4_IOC_PRECACHE_EXTENTS) && defined(__linux__))
21 #define EXT4_IOC_PRECACHE_EXTENTS	_IO('f', 18)
22 #endif
23 
24 #if (!defined(EXT4_IOC_CLEAR_ES_CACHE) && defined(__linux__))
25 #define EXT4_IOC_CLEAR_ES_CACHE		_IO('f', 40)
26 #endif
27 
28 
29 #define EXT4_F_RW	0x0001
30 
31 struct cmd {
32 	const char	*cmd;
33 	unsigned long	ioc;
34 	int		flags;
35 };
36 
37 struct cmd cmds[] = {
38 	{ "alloc_da_blks", EXT4_IOC_ALLOC_DA_BLKS, EXT4_F_RW },
39 	{ "precache", EXT4_IOC_PRECACHE_EXTENTS, 0 },
40 	{ "swap_boot", EXT4_IOC_SWAP_BOOT, EXT4_F_RW },
41 	{ "clear_es_cache", EXT4_IOC_CLEAR_ES_CACHE, EXT4_F_RW },
42 	{ NULL, 0 }
43 };
44 
45 const char *progname;
46 
usage()47 void usage()
48 {
49 	struct cmd *p;
50 
51 	fprintf(stderr, "Usage: %s <cmd> <file>\n\n", progname);
52 	fprintf(stderr, "Available commands:\n");
53 	for (p = cmds; p->cmd; p++) {
54 		fprintf(stderr, "\t%s\n", p->cmd);
55 	}
56 	exit(1);
57 }
58 
do_single_cmd(const char * fn,struct cmd * p)59 int do_single_cmd(const char *fn, struct cmd *p)
60 {
61 	int	fd;
62 	int	oflags = O_RDONLY;
63 
64 	if (p->flags & EXT4_F_RW)
65 		oflags = O_RDWR;
66 	fd = open(fn, oflags, 0);
67 	if (fd < 0) {
68 		perror("open");
69 		return 1;
70 	}
71 	if (ioctl(fd, p->ioc) < 0) {
72 		perror("ioctl");
73 		return 1;
74 	}
75 	close(fd);
76 	return 0;
77 }
78 
main(int argc,char ** argv)79 int main(int argc, char **argv)
80 {
81 	int	i, fails = 0;
82 	struct cmd *p;
83 
84 	progname = argv[0];
85 	if (argc < 3 || strcmp(argv[1], "help") == 0)
86 		usage();
87 	for (p = cmds; p->cmd; p++) {
88 		if (strcmp(argv[1], p->cmd) == 0)
89 			break;
90 	}
91 	if (p->cmd == NULL) {
92 		fprintf(stderr, "Invalid command: %s\n", argv[1]);
93 		usage();
94 	}
95 	for (i = 2; i < argc; i++)
96 		fails += do_single_cmd(argv[i], p);
97 	return fails;
98 }
99