xref: /aosp_15_r20/external/f2fs-tools/tools/f2fs_io/f2fs_io.c (revision 59bfda1f02d633cd6b8b69f31eee485d40f6eef6)
1*59bfda1fSAndroid Build Coastguard Worker /*
2*59bfda1fSAndroid Build Coastguard Worker  * f2fs_io.c - f2fs ioctl utility
3*59bfda1fSAndroid Build Coastguard Worker  *
4*59bfda1fSAndroid Build Coastguard Worker  * Author: Jaegeuk Kim <[email protected]>
5*59bfda1fSAndroid Build Coastguard Worker  *
6*59bfda1fSAndroid Build Coastguard Worker  * Copied portion of the code from ../f2fscrypt.c
7*59bfda1fSAndroid Build Coastguard Worker  */
8*59bfda1fSAndroid Build Coastguard Worker 
9*59bfda1fSAndroid Build Coastguard Worker #ifndef _GNU_SOURCE
10*59bfda1fSAndroid Build Coastguard Worker #define _GNU_SOURCE
11*59bfda1fSAndroid Build Coastguard Worker #endif
12*59bfda1fSAndroid Build Coastguard Worker #ifndef O_LARGEFILE
13*59bfda1fSAndroid Build Coastguard Worker #define O_LARGEFILE 0
14*59bfda1fSAndroid Build Coastguard Worker #endif
15*59bfda1fSAndroid Build Coastguard Worker #ifndef __SANE_USERSPACE_TYPES__
16*59bfda1fSAndroid Build Coastguard Worker #define __SANE_USERSPACE_TYPES__       /* For PPC64, to get LL64 types */
17*59bfda1fSAndroid Build Coastguard Worker #endif
18*59bfda1fSAndroid Build Coastguard Worker 
19*59bfda1fSAndroid Build Coastguard Worker #include <errno.h>
20*59bfda1fSAndroid Build Coastguard Worker #include <fcntl.h>
21*59bfda1fSAndroid Build Coastguard Worker #include <getopt.h>
22*59bfda1fSAndroid Build Coastguard Worker #include <inttypes.h>
23*59bfda1fSAndroid Build Coastguard Worker #include <limits.h>
24*59bfda1fSAndroid Build Coastguard Worker #include <linux/fs.h>
25*59bfda1fSAndroid Build Coastguard Worker #include <signal.h>
26*59bfda1fSAndroid Build Coastguard Worker #include <stdarg.h>
27*59bfda1fSAndroid Build Coastguard Worker #include <stdbool.h>
28*59bfda1fSAndroid Build Coastguard Worker #include <stdio.h>
29*59bfda1fSAndroid Build Coastguard Worker #include <stdlib.h>
30*59bfda1fSAndroid Build Coastguard Worker #include <string.h>
31*59bfda1fSAndroid Build Coastguard Worker #include <sys/mman.h>
32*59bfda1fSAndroid Build Coastguard Worker #include <sys/sendfile.h>
33*59bfda1fSAndroid Build Coastguard Worker #include <sys/stat.h>
34*59bfda1fSAndroid Build Coastguard Worker #include <sys/types.h>
35*59bfda1fSAndroid Build Coastguard Worker #include <termios.h>
36*59bfda1fSAndroid Build Coastguard Worker #include <time.h>
37*59bfda1fSAndroid Build Coastguard Worker #include <unistd.h>
38*59bfda1fSAndroid Build Coastguard Worker #include <sys/xattr.h>
39*59bfda1fSAndroid Build Coastguard Worker 
40*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
41*59bfda1fSAndroid Build Coastguard Worker #include <config.h>
42*59bfda1fSAndroid Build Coastguard Worker #endif
43*59bfda1fSAndroid Build Coastguard Worker #include <android_config.h>
44*59bfda1fSAndroid Build Coastguard Worker 
45*59bfda1fSAndroid Build Coastguard Worker #include "f2fs_io.h"
46*59bfda1fSAndroid Build Coastguard Worker 
47*59bfda1fSAndroid Build Coastguard Worker struct cmd_desc {
48*59bfda1fSAndroid Build Coastguard Worker 	const char *cmd_name;
49*59bfda1fSAndroid Build Coastguard Worker 	void (*cmd_func)(int, char **, const struct cmd_desc *);
50*59bfda1fSAndroid Build Coastguard Worker 	const char *cmd_desc;
51*59bfda1fSAndroid Build Coastguard Worker 	const char *cmd_help;
52*59bfda1fSAndroid Build Coastguard Worker 	int cmd_flags;
53*59bfda1fSAndroid Build Coastguard Worker };
54*59bfda1fSAndroid Build Coastguard Worker 
55*59bfda1fSAndroid Build Coastguard Worker static void __attribute__((noreturn))
do_die(const char * format,va_list va,int err)56*59bfda1fSAndroid Build Coastguard Worker do_die(const char *format, va_list va, int err)
57*59bfda1fSAndroid Build Coastguard Worker {
58*59bfda1fSAndroid Build Coastguard Worker 	vfprintf(stderr, format, va);
59*59bfda1fSAndroid Build Coastguard Worker 	if (err)
60*59bfda1fSAndroid Build Coastguard Worker 		fprintf(stderr, ": %s", strerror(err));
61*59bfda1fSAndroid Build Coastguard Worker 	putc('\n', stderr);
62*59bfda1fSAndroid Build Coastguard Worker 	exit(1);
63*59bfda1fSAndroid Build Coastguard Worker }
64*59bfda1fSAndroid Build Coastguard Worker 
65*59bfda1fSAndroid Build Coastguard Worker static void __attribute__((noreturn, format(printf, 1, 2)))
die_errno(const char * format,...)66*59bfda1fSAndroid Build Coastguard Worker die_errno(const char *format, ...)
67*59bfda1fSAndroid Build Coastguard Worker {
68*59bfda1fSAndroid Build Coastguard Worker 	va_list va;
69*59bfda1fSAndroid Build Coastguard Worker 
70*59bfda1fSAndroid Build Coastguard Worker 	va_start(va, format);
71*59bfda1fSAndroid Build Coastguard Worker 	do_die(format, va, errno);
72*59bfda1fSAndroid Build Coastguard Worker 	va_end(va);
73*59bfda1fSAndroid Build Coastguard Worker }
74*59bfda1fSAndroid Build Coastguard Worker 
75*59bfda1fSAndroid Build Coastguard Worker static void __attribute__((noreturn, format(printf, 1, 2)))
die(const char * format,...)76*59bfda1fSAndroid Build Coastguard Worker die(const char *format, ...)
77*59bfda1fSAndroid Build Coastguard Worker {
78*59bfda1fSAndroid Build Coastguard Worker 	va_list va;
79*59bfda1fSAndroid Build Coastguard Worker 
80*59bfda1fSAndroid Build Coastguard Worker 	va_start(va, format);
81*59bfda1fSAndroid Build Coastguard Worker 	do_die(format, va, 0);
82*59bfda1fSAndroid Build Coastguard Worker 	va_end(va);
83*59bfda1fSAndroid Build Coastguard Worker }
84*59bfda1fSAndroid Build Coastguard Worker 
xmalloc(size_t size)85*59bfda1fSAndroid Build Coastguard Worker static void *xmalloc(size_t size)
86*59bfda1fSAndroid Build Coastguard Worker {
87*59bfda1fSAndroid Build Coastguard Worker 	void *p = malloc(size);
88*59bfda1fSAndroid Build Coastguard Worker 
89*59bfda1fSAndroid Build Coastguard Worker 	if (!p)
90*59bfda1fSAndroid Build Coastguard Worker 		die("Memory alloc failed (requested %zu bytes)", size);
91*59bfda1fSAndroid Build Coastguard Worker 	return p;
92*59bfda1fSAndroid Build Coastguard Worker }
93*59bfda1fSAndroid Build Coastguard Worker 
aligned_xalloc(size_t alignment,size_t size)94*59bfda1fSAndroid Build Coastguard Worker static void *aligned_xalloc(size_t alignment, size_t size)
95*59bfda1fSAndroid Build Coastguard Worker {
96*59bfda1fSAndroid Build Coastguard Worker 	void *p = aligned_alloc(alignment, size);
97*59bfda1fSAndroid Build Coastguard Worker 
98*59bfda1fSAndroid Build Coastguard Worker 	if (!p)
99*59bfda1fSAndroid Build Coastguard Worker 		die("Memory alloc failed (requested %zu bytes)", size);
100*59bfda1fSAndroid Build Coastguard Worker 	return p;
101*59bfda1fSAndroid Build Coastguard Worker }
102*59bfda1fSAndroid Build Coastguard Worker 
xopen(const char * pathname,int flags,mode_t mode)103*59bfda1fSAndroid Build Coastguard Worker static int xopen(const char *pathname, int flags, mode_t mode)
104*59bfda1fSAndroid Build Coastguard Worker {
105*59bfda1fSAndroid Build Coastguard Worker 	int fd = open(pathname, flags, mode);
106*59bfda1fSAndroid Build Coastguard Worker 
107*59bfda1fSAndroid Build Coastguard Worker 	if (fd < 0)
108*59bfda1fSAndroid Build Coastguard Worker 		die_errno("Failed to open %s", pathname);
109*59bfda1fSAndroid Build Coastguard Worker 	return fd;
110*59bfda1fSAndroid Build Coastguard Worker }
111*59bfda1fSAndroid Build Coastguard Worker 
xread(int fd,void * buf,size_t count)112*59bfda1fSAndroid Build Coastguard Worker static ssize_t xread(int fd, void *buf, size_t count)
113*59bfda1fSAndroid Build Coastguard Worker {
114*59bfda1fSAndroid Build Coastguard Worker 	ssize_t ret = read(fd, buf, count);
115*59bfda1fSAndroid Build Coastguard Worker 
116*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
117*59bfda1fSAndroid Build Coastguard Worker 		die_errno("read failed");
118*59bfda1fSAndroid Build Coastguard Worker 	return ret;
119*59bfda1fSAndroid Build Coastguard Worker }
120*59bfda1fSAndroid Build Coastguard Worker 
full_write(int fd,const void * buf,size_t count)121*59bfda1fSAndroid Build Coastguard Worker static void full_write(int fd, const void *buf, size_t count)
122*59bfda1fSAndroid Build Coastguard Worker {
123*59bfda1fSAndroid Build Coastguard Worker 	while (count) {
124*59bfda1fSAndroid Build Coastguard Worker 		ssize_t ret = write(fd, buf, count);
125*59bfda1fSAndroid Build Coastguard Worker 
126*59bfda1fSAndroid Build Coastguard Worker 		if (ret < 0)
127*59bfda1fSAndroid Build Coastguard Worker 			die_errno("write failed");
128*59bfda1fSAndroid Build Coastguard Worker 		buf = (char *)buf + ret;
129*59bfda1fSAndroid Build Coastguard Worker 		count -= ret;
130*59bfda1fSAndroid Build Coastguard Worker 	}
131*59bfda1fSAndroid Build Coastguard Worker }
132*59bfda1fSAndroid Build Coastguard Worker 
133*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_MACH_TIME_H
get_current_us()134*59bfda1fSAndroid Build Coastguard Worker static u64 get_current_us()
135*59bfda1fSAndroid Build Coastguard Worker {
136*59bfda1fSAndroid Build Coastguard Worker 	return mach_absolute_time() / 1000;
137*59bfda1fSAndroid Build Coastguard Worker }
138*59bfda1fSAndroid Build Coastguard Worker #elif defined(HAVE_CLOCK_GETTIME) && defined(HAVE_CLOCK_BOOTTIME)
get_current_us()139*59bfda1fSAndroid Build Coastguard Worker static u64 get_current_us()
140*59bfda1fSAndroid Build Coastguard Worker {
141*59bfda1fSAndroid Build Coastguard Worker 	struct timespec t;
142*59bfda1fSAndroid Build Coastguard Worker 	t.tv_sec = t.tv_nsec = 0;
143*59bfda1fSAndroid Build Coastguard Worker 	clock_gettime(CLOCK_BOOTTIME, &t);
144*59bfda1fSAndroid Build Coastguard Worker 	return (u64)t.tv_sec * 1000000LL + t.tv_nsec / 1000;
145*59bfda1fSAndroid Build Coastguard Worker }
146*59bfda1fSAndroid Build Coastguard Worker #else
get_current_us()147*59bfda1fSAndroid Build Coastguard Worker static u64 get_current_us()
148*59bfda1fSAndroid Build Coastguard Worker {
149*59bfda1fSAndroid Build Coastguard Worker 	return 0;
150*59bfda1fSAndroid Build Coastguard Worker }
151*59bfda1fSAndroid Build Coastguard Worker #endif
152*59bfda1fSAndroid Build Coastguard Worker 
153*59bfda1fSAndroid Build Coastguard Worker #define fsync_desc "fsync"
154*59bfda1fSAndroid Build Coastguard Worker #define fsync_help						\
155*59bfda1fSAndroid Build Coastguard Worker "f2fs_io fsync [file]\n\n"					\
156*59bfda1fSAndroid Build Coastguard Worker "fsync given the file\n"					\
157*59bfda1fSAndroid Build Coastguard Worker 
do_fsync(int argc,char ** argv,const struct cmd_desc * cmd)158*59bfda1fSAndroid Build Coastguard Worker static void do_fsync(int argc, char **argv, const struct cmd_desc *cmd)
159*59bfda1fSAndroid Build Coastguard Worker {
160*59bfda1fSAndroid Build Coastguard Worker 	int fd;
161*59bfda1fSAndroid Build Coastguard Worker 
162*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
163*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
164*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
165*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
166*59bfda1fSAndroid Build Coastguard Worker 	}
167*59bfda1fSAndroid Build Coastguard Worker 
168*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_WRONLY, 0);
169*59bfda1fSAndroid Build Coastguard Worker 
170*59bfda1fSAndroid Build Coastguard Worker 	if (fsync(fd) != 0)
171*59bfda1fSAndroid Build Coastguard Worker 		die_errno("fsync failed");
172*59bfda1fSAndroid Build Coastguard Worker 
173*59bfda1fSAndroid Build Coastguard Worker 	printf("fsync a file\n");
174*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
175*59bfda1fSAndroid Build Coastguard Worker }
176*59bfda1fSAndroid Build Coastguard Worker 
177*59bfda1fSAndroid Build Coastguard Worker #define fdatasync_desc "fdatasync"
178*59bfda1fSAndroid Build Coastguard Worker #define fdatasync_help						\
179*59bfda1fSAndroid Build Coastguard Worker "f2fs_io fdatasync [file]\n\n"					\
180*59bfda1fSAndroid Build Coastguard Worker "fdatasync given the file\n"					\
181*59bfda1fSAndroid Build Coastguard Worker 
do_fdatasync(int argc,char ** argv,const struct cmd_desc * cmd)182*59bfda1fSAndroid Build Coastguard Worker static void do_fdatasync(int argc, char **argv, const struct cmd_desc *cmd)
183*59bfda1fSAndroid Build Coastguard Worker {
184*59bfda1fSAndroid Build Coastguard Worker 	int fd;
185*59bfda1fSAndroid Build Coastguard Worker 
186*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
187*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
188*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
189*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
190*59bfda1fSAndroid Build Coastguard Worker 	}
191*59bfda1fSAndroid Build Coastguard Worker 
192*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_WRONLY, 0);
193*59bfda1fSAndroid Build Coastguard Worker 
194*59bfda1fSAndroid Build Coastguard Worker 	if (fdatasync(fd) != 0)
195*59bfda1fSAndroid Build Coastguard Worker 		die_errno("fdatasync failed");
196*59bfda1fSAndroid Build Coastguard Worker 
197*59bfda1fSAndroid Build Coastguard Worker 	printf("fdatasync a file\n");
198*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
199*59bfda1fSAndroid Build Coastguard Worker }
200*59bfda1fSAndroid Build Coastguard Worker 
201*59bfda1fSAndroid Build Coastguard Worker #define set_verity_desc "Set fs-verity"
202*59bfda1fSAndroid Build Coastguard Worker #define set_verity_help					\
203*59bfda1fSAndroid Build Coastguard Worker "f2fs_io set_verity [file]\n\n"				\
204*59bfda1fSAndroid Build Coastguard Worker "Set fsverity bit given a file\n"			\
205*59bfda1fSAndroid Build Coastguard Worker 
do_set_verity(int argc,char ** argv,const struct cmd_desc * cmd)206*59bfda1fSAndroid Build Coastguard Worker static void do_set_verity(int argc, char **argv, const struct cmd_desc *cmd)
207*59bfda1fSAndroid Build Coastguard Worker {
208*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
209*59bfda1fSAndroid Build Coastguard Worker 	struct fsverity_enable_arg args = {.version = 1};
210*59bfda1fSAndroid Build Coastguard Worker 
211*59bfda1fSAndroid Build Coastguard Worker 	args.hash_algorithm = FS_VERITY_HASH_ALG_SHA256;
212*59bfda1fSAndroid Build Coastguard Worker 	args.block_size = F2FS_DEFAULT_BLKSIZE;
213*59bfda1fSAndroid Build Coastguard Worker 
214*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
215*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
216*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
217*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
218*59bfda1fSAndroid Build Coastguard Worker 	}
219*59bfda1fSAndroid Build Coastguard Worker 	fd = open(argv[1], O_RDONLY);
220*59bfda1fSAndroid Build Coastguard Worker 
221*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, FS_IOC_ENABLE_VERITY, &args);
222*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0) {
223*59bfda1fSAndroid Build Coastguard Worker 		perror("FS_IOC_ENABLE_VERITY");
224*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
225*59bfda1fSAndroid Build Coastguard Worker 	}
226*59bfda1fSAndroid Build Coastguard Worker 
227*59bfda1fSAndroid Build Coastguard Worker 	printf("Set fsverity bit to %s\n", argv[1]);
228*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
229*59bfda1fSAndroid Build Coastguard Worker }
230*59bfda1fSAndroid Build Coastguard Worker 
231*59bfda1fSAndroid Build Coastguard Worker #define getflags_desc "getflags ioctl"
232*59bfda1fSAndroid Build Coastguard Worker #define getflags_help						\
233*59bfda1fSAndroid Build Coastguard Worker "f2fs_io getflags [file]\n\n"					\
234*59bfda1fSAndroid Build Coastguard Worker "get a flag given the file\n"					\
235*59bfda1fSAndroid Build Coastguard Worker "flag can show \n"						\
236*59bfda1fSAndroid Build Coastguard Worker "  encryption\n"						\
237*59bfda1fSAndroid Build Coastguard Worker "  nocow(pinned)\n"						\
238*59bfda1fSAndroid Build Coastguard Worker "  inline_data\n"						\
239*59bfda1fSAndroid Build Coastguard Worker "  verity\n"							\
240*59bfda1fSAndroid Build Coastguard Worker "  casefold\n"							\
241*59bfda1fSAndroid Build Coastguard Worker "  compression\n"						\
242*59bfda1fSAndroid Build Coastguard Worker "  nocompression\n"						\
243*59bfda1fSAndroid Build Coastguard Worker "  immutable\n"
244*59bfda1fSAndroid Build Coastguard Worker 
do_getflags(int argc,char ** argv,const struct cmd_desc * cmd)245*59bfda1fSAndroid Build Coastguard Worker static void do_getflags(int argc, char **argv, const struct cmd_desc *cmd)
246*59bfda1fSAndroid Build Coastguard Worker {
247*59bfda1fSAndroid Build Coastguard Worker 	long flag = 0;
248*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
249*59bfda1fSAndroid Build Coastguard Worker 	int exist = 0;
250*59bfda1fSAndroid Build Coastguard Worker 
251*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
252*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
253*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
254*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
255*59bfda1fSAndroid Build Coastguard Worker 	}
256*59bfda1fSAndroid Build Coastguard Worker 
257*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_RDONLY, 0);
258*59bfda1fSAndroid Build Coastguard Worker 
259*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_GETFLAGS, &flag);
260*59bfda1fSAndroid Build Coastguard Worker 	printf("get a flag on %s ret=%d, flags=", argv[1], ret);
261*59bfda1fSAndroid Build Coastguard Worker 	if (flag & FS_CASEFOLD_FL) {
262*59bfda1fSAndroid Build Coastguard Worker 		printf("casefold");
263*59bfda1fSAndroid Build Coastguard Worker 		exist = 1;
264*59bfda1fSAndroid Build Coastguard Worker 	}
265*59bfda1fSAndroid Build Coastguard Worker 	if (flag & FS_COMPR_FL) {
266*59bfda1fSAndroid Build Coastguard Worker 		if (exist)
267*59bfda1fSAndroid Build Coastguard Worker 			printf(",");
268*59bfda1fSAndroid Build Coastguard Worker 		printf("compression");
269*59bfda1fSAndroid Build Coastguard Worker 		exist = 1;
270*59bfda1fSAndroid Build Coastguard Worker 	}
271*59bfda1fSAndroid Build Coastguard Worker 	if (flag & FS_NOCOMP_FL) {
272*59bfda1fSAndroid Build Coastguard Worker 		if (exist)
273*59bfda1fSAndroid Build Coastguard Worker 			printf(",");
274*59bfda1fSAndroid Build Coastguard Worker 		printf("nocompression");
275*59bfda1fSAndroid Build Coastguard Worker 		exist = 1;
276*59bfda1fSAndroid Build Coastguard Worker 	}
277*59bfda1fSAndroid Build Coastguard Worker 	if (flag & FS_ENCRYPT_FL) {
278*59bfda1fSAndroid Build Coastguard Worker 		if (exist)
279*59bfda1fSAndroid Build Coastguard Worker 			printf(",");
280*59bfda1fSAndroid Build Coastguard Worker 		printf("encrypt");
281*59bfda1fSAndroid Build Coastguard Worker 		exist = 1;
282*59bfda1fSAndroid Build Coastguard Worker 	}
283*59bfda1fSAndroid Build Coastguard Worker 	if (flag & FS_VERITY_FL) {
284*59bfda1fSAndroid Build Coastguard Worker 		if (exist)
285*59bfda1fSAndroid Build Coastguard Worker 			printf(",");
286*59bfda1fSAndroid Build Coastguard Worker 		printf("verity");
287*59bfda1fSAndroid Build Coastguard Worker 		exist = 1;
288*59bfda1fSAndroid Build Coastguard Worker 	}
289*59bfda1fSAndroid Build Coastguard Worker 	if (flag & FS_INLINE_DATA_FL) {
290*59bfda1fSAndroid Build Coastguard Worker 		if (exist)
291*59bfda1fSAndroid Build Coastguard Worker 			printf(",");
292*59bfda1fSAndroid Build Coastguard Worker 		printf("inline_data");
293*59bfda1fSAndroid Build Coastguard Worker 		exist = 1;
294*59bfda1fSAndroid Build Coastguard Worker 	}
295*59bfda1fSAndroid Build Coastguard Worker 	if (flag & FS_NOCOW_FL) {
296*59bfda1fSAndroid Build Coastguard Worker 		if (exist)
297*59bfda1fSAndroid Build Coastguard Worker 			printf(",");
298*59bfda1fSAndroid Build Coastguard Worker 		printf("nocow(pinned)");
299*59bfda1fSAndroid Build Coastguard Worker 		exist = 1;
300*59bfda1fSAndroid Build Coastguard Worker 	}
301*59bfda1fSAndroid Build Coastguard Worker 	if (flag & FS_IMMUTABLE_FL) {
302*59bfda1fSAndroid Build Coastguard Worker 		if (exist)
303*59bfda1fSAndroid Build Coastguard Worker 			printf(",");
304*59bfda1fSAndroid Build Coastguard Worker 		printf("immutable");
305*59bfda1fSAndroid Build Coastguard Worker 		exist = 1;
306*59bfda1fSAndroid Build Coastguard Worker 	}
307*59bfda1fSAndroid Build Coastguard Worker 	if (!exist)
308*59bfda1fSAndroid Build Coastguard Worker 		printf("none");
309*59bfda1fSAndroid Build Coastguard Worker 	printf("\n");
310*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
311*59bfda1fSAndroid Build Coastguard Worker }
312*59bfda1fSAndroid Build Coastguard Worker 
313*59bfda1fSAndroid Build Coastguard Worker #define setflags_desc "setflags ioctl"
314*59bfda1fSAndroid Build Coastguard Worker #define setflags_help						\
315*59bfda1fSAndroid Build Coastguard Worker "f2fs_io setflags [flag] [file]\n\n"				\
316*59bfda1fSAndroid Build Coastguard Worker "set a flag given the file\n"					\
317*59bfda1fSAndroid Build Coastguard Worker "flag can be\n"							\
318*59bfda1fSAndroid Build Coastguard Worker "  casefold\n"							\
319*59bfda1fSAndroid Build Coastguard Worker "  compression\n"						\
320*59bfda1fSAndroid Build Coastguard Worker "  nocompression\n"						\
321*59bfda1fSAndroid Build Coastguard Worker "  immutable\n"							\
322*59bfda1fSAndroid Build Coastguard Worker "  nocow\n"
323*59bfda1fSAndroid Build Coastguard Worker 
do_setflags(int argc,char ** argv,const struct cmd_desc * cmd)324*59bfda1fSAndroid Build Coastguard Worker static void do_setflags(int argc, char **argv, const struct cmd_desc *cmd)
325*59bfda1fSAndroid Build Coastguard Worker {
326*59bfda1fSAndroid Build Coastguard Worker 	long flag = 0;
327*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
328*59bfda1fSAndroid Build Coastguard Worker 
329*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 3) {
330*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
331*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
332*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
333*59bfda1fSAndroid Build Coastguard Worker 	}
334*59bfda1fSAndroid Build Coastguard Worker 
335*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[2], O_RDONLY, 0);
336*59bfda1fSAndroid Build Coastguard Worker 
337*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_GETFLAGS, &flag);
338*59bfda1fSAndroid Build Coastguard Worker 	printf("get a flag on %s ret=%d, flags=%lx\n", argv[1], ret, flag);
339*59bfda1fSAndroid Build Coastguard Worker 	if (ret)
340*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_GETFLAGS failed");
341*59bfda1fSAndroid Build Coastguard Worker 
342*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[1], "casefold"))
343*59bfda1fSAndroid Build Coastguard Worker 		flag |= FS_CASEFOLD_FL;
344*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "compression"))
345*59bfda1fSAndroid Build Coastguard Worker 		flag |= FS_COMPR_FL;
346*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "nocompression"))
347*59bfda1fSAndroid Build Coastguard Worker 		flag |= FS_NOCOMP_FL;
348*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "immutable"))
349*59bfda1fSAndroid Build Coastguard Worker 		flag |= FS_IMMUTABLE_FL;
350*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "nocow"))
351*59bfda1fSAndroid Build Coastguard Worker 		flag |= FS_NOCOW_FL;
352*59bfda1fSAndroid Build Coastguard Worker 
353*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_SETFLAGS, &flag);
354*59bfda1fSAndroid Build Coastguard Worker 	printf("set a flag on %s ret=%d, flags=%s\n", argv[2], ret, argv[1]);
355*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
356*59bfda1fSAndroid Build Coastguard Worker }
357*59bfda1fSAndroid Build Coastguard Worker 
358*59bfda1fSAndroid Build Coastguard Worker #define clearflags_desc "clearflags ioctl"
359*59bfda1fSAndroid Build Coastguard Worker #define clearflags_help						\
360*59bfda1fSAndroid Build Coastguard Worker "f2fs_io clearflags [flag] [file]\n\n"				\
361*59bfda1fSAndroid Build Coastguard Worker "clear a flag given the file\n"					\
362*59bfda1fSAndroid Build Coastguard Worker "flag can be\n"							\
363*59bfda1fSAndroid Build Coastguard Worker "  compression\n"						\
364*59bfda1fSAndroid Build Coastguard Worker "  nocompression\n"						\
365*59bfda1fSAndroid Build Coastguard Worker "  immutable\n"							\
366*59bfda1fSAndroid Build Coastguard Worker "  nocow\n"
367*59bfda1fSAndroid Build Coastguard Worker 
do_clearflags(int argc,char ** argv,const struct cmd_desc * cmd)368*59bfda1fSAndroid Build Coastguard Worker static void do_clearflags(int argc, char **argv, const struct cmd_desc *cmd)
369*59bfda1fSAndroid Build Coastguard Worker {
370*59bfda1fSAndroid Build Coastguard Worker 	long flag = 0;
371*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
372*59bfda1fSAndroid Build Coastguard Worker 
373*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 3) {
374*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
375*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
376*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
377*59bfda1fSAndroid Build Coastguard Worker 	}
378*59bfda1fSAndroid Build Coastguard Worker 
379*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[2], O_RDONLY, 0);
380*59bfda1fSAndroid Build Coastguard Worker 
381*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_GETFLAGS, &flag);
382*59bfda1fSAndroid Build Coastguard Worker 	printf("get a flag on %s ret=%d, flags=%lx\n", argv[1], ret, flag);
383*59bfda1fSAndroid Build Coastguard Worker 	if (ret)
384*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_GETFLAGS failed");
385*59bfda1fSAndroid Build Coastguard Worker 
386*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[1], "compression"))
387*59bfda1fSAndroid Build Coastguard Worker 		flag &= ~FS_COMPR_FL;
388*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "nocompression"))
389*59bfda1fSAndroid Build Coastguard Worker 		flag &= ~FS_NOCOMP_FL;
390*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "immutable"))
391*59bfda1fSAndroid Build Coastguard Worker 		flag &= ~FS_IMMUTABLE_FL;
392*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "nocow"))
393*59bfda1fSAndroid Build Coastguard Worker 		flag &= ~FS_NOCOW_FL;
394*59bfda1fSAndroid Build Coastguard Worker 
395*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_SETFLAGS, &flag);
396*59bfda1fSAndroid Build Coastguard Worker 	printf("clear a flag on %s ret=%d, flags=%s\n", argv[2], ret, argv[1]);
397*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
398*59bfda1fSAndroid Build Coastguard Worker }
399*59bfda1fSAndroid Build Coastguard Worker 
400*59bfda1fSAndroid Build Coastguard Worker #define shutdown_desc "shutdown filesystem"
401*59bfda1fSAndroid Build Coastguard Worker #define shutdown_help					\
402*59bfda1fSAndroid Build Coastguard Worker "f2fs_io shutdown [level] [dir]\n\n"			\
403*59bfda1fSAndroid Build Coastguard Worker "Freeze and stop all IOs given mount point\n"		\
404*59bfda1fSAndroid Build Coastguard Worker "level can be\n"					\
405*59bfda1fSAndroid Build Coastguard Worker "  0 : going down with full sync\n"			\
406*59bfda1fSAndroid Build Coastguard Worker "  1 : going down with checkpoint only\n"		\
407*59bfda1fSAndroid Build Coastguard Worker "  2 : going down with no sync\n"			\
408*59bfda1fSAndroid Build Coastguard Worker "  3 : going down with metadata flush\n"		\
409*59bfda1fSAndroid Build Coastguard Worker "  4 : going down with fsck mark\n"
410*59bfda1fSAndroid Build Coastguard Worker 
do_shutdown(int argc,char ** argv,const struct cmd_desc * cmd)411*59bfda1fSAndroid Build Coastguard Worker static void do_shutdown(int argc, char **argv, const struct cmd_desc *cmd)
412*59bfda1fSAndroid Build Coastguard Worker {
413*59bfda1fSAndroid Build Coastguard Worker 	u32 flag;
414*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
415*59bfda1fSAndroid Build Coastguard Worker 
416*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 3) {
417*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
418*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
419*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
420*59bfda1fSAndroid Build Coastguard Worker 	}
421*59bfda1fSAndroid Build Coastguard Worker 
422*59bfda1fSAndroid Build Coastguard Worker 	flag = atoi(argv[1]);
423*59bfda1fSAndroid Build Coastguard Worker 	if (flag >= F2FS_GOING_DOWN_MAX) {
424*59bfda1fSAndroid Build Coastguard Worker 		fputs("Wrong level\n\n", stderr);
425*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
426*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
427*59bfda1fSAndroid Build Coastguard Worker 	}
428*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[2], O_RDONLY, 0);
429*59bfda1fSAndroid Build Coastguard Worker 
430*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_SHUTDOWN, &flag);
431*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
432*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_SHUTDOWN failed");
433*59bfda1fSAndroid Build Coastguard Worker 
434*59bfda1fSAndroid Build Coastguard Worker 	printf("Shutdown %s with level=%d\n", argv[2], flag);
435*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
436*59bfda1fSAndroid Build Coastguard Worker }
437*59bfda1fSAndroid Build Coastguard Worker 
438*59bfda1fSAndroid Build Coastguard Worker #define fadvise_desc "fadvise"
439*59bfda1fSAndroid Build Coastguard Worker #define fadvise_help						\
440*59bfda1fSAndroid Build Coastguard Worker "f2fs_io fadvise [advice] [offset] [length] [file]\n\n"		\
441*59bfda1fSAndroid Build Coastguard Worker "fadvice given the file\n"					\
442*59bfda1fSAndroid Build Coastguard Worker "advice can be\n"						\
443*59bfda1fSAndroid Build Coastguard Worker " willneed\n"							\
444*59bfda1fSAndroid Build Coastguard Worker " sequential\n"							\
445*59bfda1fSAndroid Build Coastguard Worker 
do_fadvise(int argc,char ** argv,const struct cmd_desc * cmd)446*59bfda1fSAndroid Build Coastguard Worker static void do_fadvise(int argc, char **argv, const struct cmd_desc *cmd)
447*59bfda1fSAndroid Build Coastguard Worker {
448*59bfda1fSAndroid Build Coastguard Worker 	int fd, advice;
449*59bfda1fSAndroid Build Coastguard Worker 	off_t offset, length;
450*59bfda1fSAndroid Build Coastguard Worker 
451*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 5) {
452*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
453*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
454*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
455*59bfda1fSAndroid Build Coastguard Worker 	}
456*59bfda1fSAndroid Build Coastguard Worker 
457*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[4], O_RDWR, 0);
458*59bfda1fSAndroid Build Coastguard Worker 
459*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[1], "willneed")) {
460*59bfda1fSAndroid Build Coastguard Worker 		advice = POSIX_FADV_WILLNEED;
461*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(argv[1], "sequential")) {
462*59bfda1fSAndroid Build Coastguard Worker 		advice = POSIX_FADV_SEQUENTIAL;
463*59bfda1fSAndroid Build Coastguard Worker 	} else {
464*59bfda1fSAndroid Build Coastguard Worker 		fputs("Wrong advice\n\n", stderr);
465*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
466*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
467*59bfda1fSAndroid Build Coastguard Worker 	}
468*59bfda1fSAndroid Build Coastguard Worker 
469*59bfda1fSAndroid Build Coastguard Worker 	offset = atoi(argv[2]);
470*59bfda1fSAndroid Build Coastguard Worker 	length = atoll(argv[3]);
471*59bfda1fSAndroid Build Coastguard Worker 
472*59bfda1fSAndroid Build Coastguard Worker 	if (posix_fadvise(fd, offset, length, advice) != 0)
473*59bfda1fSAndroid Build Coastguard Worker 		die_errno("fadvise failed");
474*59bfda1fSAndroid Build Coastguard Worker 
475*59bfda1fSAndroid Build Coastguard Worker 	printf("fadvice %s to a file: %s\n", argv[1], argv[4]);
476*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
477*59bfda1fSAndroid Build Coastguard Worker }
478*59bfda1fSAndroid Build Coastguard Worker 
479*59bfda1fSAndroid Build Coastguard Worker #define pinfile_desc "pin file control"
480*59bfda1fSAndroid Build Coastguard Worker #define pinfile_help						\
481*59bfda1fSAndroid Build Coastguard Worker "f2fs_io pinfile [get|set|unset] [file]\n\n"			\
482*59bfda1fSAndroid Build Coastguard Worker "get/set pinning given the file\n"				\
483*59bfda1fSAndroid Build Coastguard Worker 
do_pinfile(int argc,char ** argv,const struct cmd_desc * cmd)484*59bfda1fSAndroid Build Coastguard Worker static void do_pinfile(int argc, char **argv, const struct cmd_desc *cmd)
485*59bfda1fSAndroid Build Coastguard Worker {
486*59bfda1fSAndroid Build Coastguard Worker 	u32 pin;
487*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
488*59bfda1fSAndroid Build Coastguard Worker 
489*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 3) {
490*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
491*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
492*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
493*59bfda1fSAndroid Build Coastguard Worker 	}
494*59bfda1fSAndroid Build Coastguard Worker 
495*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[2], O_RDONLY, 0);
496*59bfda1fSAndroid Build Coastguard Worker 
497*59bfda1fSAndroid Build Coastguard Worker 	ret = -1;
498*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[1], "set")) {
499*59bfda1fSAndroid Build Coastguard Worker 		pin = 1;
500*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(fd, F2FS_IOC_SET_PIN_FILE, &pin);
501*59bfda1fSAndroid Build Coastguard Worker 		if (ret != 0)
502*59bfda1fSAndroid Build Coastguard Worker 			die_errno("F2FS_IOC_SET_PIN_FILE failed");
503*59bfda1fSAndroid Build Coastguard Worker 		printf("%s pinfile: %u blocks moved in %s\n",
504*59bfda1fSAndroid Build Coastguard Worker 					argv[1], ret, argv[2]);
505*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(argv[1], "unset")) {
506*59bfda1fSAndroid Build Coastguard Worker 		pin = 0;
507*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(fd, F2FS_IOC_SET_PIN_FILE, &pin);
508*59bfda1fSAndroid Build Coastguard Worker 		if (ret != 0)
509*59bfda1fSAndroid Build Coastguard Worker 			die_errno("F2FS_IOC_SET_PIN_FILE failed");
510*59bfda1fSAndroid Build Coastguard Worker 		printf("%s pinfile in %s\n", argv[1], argv[2]);
511*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(argv[1], "get")) {
512*59bfda1fSAndroid Build Coastguard Worker 		unsigned int flags;
513*59bfda1fSAndroid Build Coastguard Worker 
514*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(fd, F2FS_IOC_GET_PIN_FILE, &pin);
515*59bfda1fSAndroid Build Coastguard Worker 		if (ret < 0)
516*59bfda1fSAndroid Build Coastguard Worker 			die_errno("F2FS_IOC_GET_PIN_FILE failed");
517*59bfda1fSAndroid Build Coastguard Worker 
518*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(fd, F2FS_IOC_GETFLAGS, &flags);
519*59bfda1fSAndroid Build Coastguard Worker 		if (ret < 0)
520*59bfda1fSAndroid Build Coastguard Worker 			die_errno("F2FS_IOC_GETFLAGS failed");
521*59bfda1fSAndroid Build Coastguard Worker 
522*59bfda1fSAndroid Build Coastguard Worker 		printf("get_pin_file: %s with %u blocks moved in %s\n",
523*59bfda1fSAndroid Build Coastguard Worker 				(flags & F2FS_NOCOW_FL) ? "pinned" : "un-pinned",
524*59bfda1fSAndroid Build Coastguard Worker 				pin, argv[2]);
525*59bfda1fSAndroid Build Coastguard Worker 	}
526*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
527*59bfda1fSAndroid Build Coastguard Worker }
528*59bfda1fSAndroid Build Coastguard Worker 
529*59bfda1fSAndroid Build Coastguard Worker #define fallocate_desc "fallocate"
530*59bfda1fSAndroid Build Coastguard Worker #define fallocate_help						\
531*59bfda1fSAndroid Build Coastguard Worker "f2fs_io fallocate [-c] [-i] [-p] [-z] [keep_size] [offset] [length] [file]\n\n"	\
532*59bfda1fSAndroid Build Coastguard Worker "fallocate given the file\n"					\
533*59bfda1fSAndroid Build Coastguard Worker " [keep_size] : 1 or 0\n"					\
534*59bfda1fSAndroid Build Coastguard Worker " -c : collapse range\n"					\
535*59bfda1fSAndroid Build Coastguard Worker " -i : insert range\n"						\
536*59bfda1fSAndroid Build Coastguard Worker " -p : punch hole\n"						\
537*59bfda1fSAndroid Build Coastguard Worker " -z : zero range\n"						\
538*59bfda1fSAndroid Build Coastguard Worker 
do_fallocate(int argc,char ** argv,const struct cmd_desc * cmd)539*59bfda1fSAndroid Build Coastguard Worker static void do_fallocate(int argc, char **argv, const struct cmd_desc *cmd)
540*59bfda1fSAndroid Build Coastguard Worker {
541*59bfda1fSAndroid Build Coastguard Worker 	int fd;
542*59bfda1fSAndroid Build Coastguard Worker 	off_t offset, length;
543*59bfda1fSAndroid Build Coastguard Worker 	struct stat sb;
544*59bfda1fSAndroid Build Coastguard Worker 	int mode = 0;
545*59bfda1fSAndroid Build Coastguard Worker 	int c;
546*59bfda1fSAndroid Build Coastguard Worker 
547*59bfda1fSAndroid Build Coastguard Worker 	while ((c = getopt(argc, argv, "cipz")) != -1) {
548*59bfda1fSAndroid Build Coastguard Worker 		switch (c) {
549*59bfda1fSAndroid Build Coastguard Worker 		case 'c':
550*59bfda1fSAndroid Build Coastguard Worker 			mode |= FALLOC_FL_COLLAPSE_RANGE;
551*59bfda1fSAndroid Build Coastguard Worker 			break;
552*59bfda1fSAndroid Build Coastguard Worker 		case 'i':
553*59bfda1fSAndroid Build Coastguard Worker 			mode |= FALLOC_FL_INSERT_RANGE;
554*59bfda1fSAndroid Build Coastguard Worker 			break;
555*59bfda1fSAndroid Build Coastguard Worker 		case 'p':
556*59bfda1fSAndroid Build Coastguard Worker 			mode |= FALLOC_FL_PUNCH_HOLE;
557*59bfda1fSAndroid Build Coastguard Worker 			break;
558*59bfda1fSAndroid Build Coastguard Worker 		case 'z':
559*59bfda1fSAndroid Build Coastguard Worker 			mode |= FALLOC_FL_ZERO_RANGE;
560*59bfda1fSAndroid Build Coastguard Worker 			break;
561*59bfda1fSAndroid Build Coastguard Worker 		default:
562*59bfda1fSAndroid Build Coastguard Worker 			fputs(cmd->cmd_help, stderr);
563*59bfda1fSAndroid Build Coastguard Worker 			exit(2);
564*59bfda1fSAndroid Build Coastguard Worker 		}
565*59bfda1fSAndroid Build Coastguard Worker 	}
566*59bfda1fSAndroid Build Coastguard Worker 	argc -= optind;
567*59bfda1fSAndroid Build Coastguard Worker 	argv += optind;
568*59bfda1fSAndroid Build Coastguard Worker 
569*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 4) {
570*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
571*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
572*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
573*59bfda1fSAndroid Build Coastguard Worker 	}
574*59bfda1fSAndroid Build Coastguard Worker 
575*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[0], "1"))
576*59bfda1fSAndroid Build Coastguard Worker 		mode |= FALLOC_FL_KEEP_SIZE;
577*59bfda1fSAndroid Build Coastguard Worker 
578*59bfda1fSAndroid Build Coastguard Worker 	offset = atoll(argv[1]);
579*59bfda1fSAndroid Build Coastguard Worker 	length = atoll(argv[2]);
580*59bfda1fSAndroid Build Coastguard Worker 
581*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[3], O_RDWR, 0);
582*59bfda1fSAndroid Build Coastguard Worker 
583*59bfda1fSAndroid Build Coastguard Worker 	if (fallocate(fd, mode, offset, length) != 0)
584*59bfda1fSAndroid Build Coastguard Worker 		die_errno("fallocate failed");
585*59bfda1fSAndroid Build Coastguard Worker 
586*59bfda1fSAndroid Build Coastguard Worker 	if (fstat(fd, &sb) != 0)
587*59bfda1fSAndroid Build Coastguard Worker 		die_errno("fstat failed");
588*59bfda1fSAndroid Build Coastguard Worker 
589*59bfda1fSAndroid Build Coastguard Worker 	printf("fallocated a file: i_size=%"PRIu64", i_blocks=%"PRIu64"\n", sb.st_size, sb.st_blocks);
590*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
591*59bfda1fSAndroid Build Coastguard Worker }
592*59bfda1fSAndroid Build Coastguard Worker 
593*59bfda1fSAndroid Build Coastguard Worker #define erase_desc "erase a block device"
594*59bfda1fSAndroid Build Coastguard Worker #define erase_help				\
595*59bfda1fSAndroid Build Coastguard Worker "f2fs_io erase [block_device_path]\n\n"		\
596*59bfda1fSAndroid Build Coastguard Worker "Send DISCARD | BLKSECDISCARD comamnd to"	\
597*59bfda1fSAndroid Build Coastguard Worker "block device in block_device_path\n"		\
598*59bfda1fSAndroid Build Coastguard Worker 
do_erase(int argc,char ** argv,const struct cmd_desc * cmd)599*59bfda1fSAndroid Build Coastguard Worker static void do_erase(int argc, char **argv, const struct cmd_desc *cmd)
600*59bfda1fSAndroid Build Coastguard Worker {
601*59bfda1fSAndroid Build Coastguard Worker 	int fd, ret;
602*59bfda1fSAndroid Build Coastguard Worker 	struct stat st;
603*59bfda1fSAndroid Build Coastguard Worker 	u64 range[2];
604*59bfda1fSAndroid Build Coastguard Worker 
605*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
606*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
607*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
608*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
609*59bfda1fSAndroid Build Coastguard Worker 	}
610*59bfda1fSAndroid Build Coastguard Worker 
611*59bfda1fSAndroid Build Coastguard Worker 	if (stat(argv[1], &st) != 0) {
612*59bfda1fSAndroid Build Coastguard Worker 		fputs("stat error\n", stderr);
613*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
614*59bfda1fSAndroid Build Coastguard Worker 	}
615*59bfda1fSAndroid Build Coastguard Worker 
616*59bfda1fSAndroid Build Coastguard Worker 	if (!S_ISBLK(st.st_mode)) {
617*59bfda1fSAndroid Build Coastguard Worker 		fputs(argv[1], stderr);
618*59bfda1fSAndroid Build Coastguard Worker 		fputs(" is not a block device\n", stderr);
619*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
620*59bfda1fSAndroid Build Coastguard Worker 	}
621*59bfda1fSAndroid Build Coastguard Worker 
622*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_WRONLY, 0);
623*59bfda1fSAndroid Build Coastguard Worker 
624*59bfda1fSAndroid Build Coastguard Worker 	range[0] = 0;
625*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, BLKGETSIZE64, &range[1]);
626*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0) {
627*59bfda1fSAndroid Build Coastguard Worker 		fputs("get size failed\n", stderr);
628*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
629*59bfda1fSAndroid Build Coastguard Worker 	}
630*59bfda1fSAndroid Build Coastguard Worker 
631*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, BLKSECDISCARD, &range);
632*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0) {
633*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(fd, BLKDISCARD, &range);
634*59bfda1fSAndroid Build Coastguard Worker 		if (ret < 0) {
635*59bfda1fSAndroid Build Coastguard Worker 			fputs("Discard failed\n", stderr);
636*59bfda1fSAndroid Build Coastguard Worker 			exit(1);
637*59bfda1fSAndroid Build Coastguard Worker 		}
638*59bfda1fSAndroid Build Coastguard Worker 	}
639*59bfda1fSAndroid Build Coastguard Worker 
640*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
641*59bfda1fSAndroid Build Coastguard Worker }
642*59bfda1fSAndroid Build Coastguard Worker 
do_write_with_advice(int argc,char ** argv,const struct cmd_desc * cmd,bool with_advice)643*59bfda1fSAndroid Build Coastguard Worker static void do_write_with_advice(int argc, char **argv,
644*59bfda1fSAndroid Build Coastguard Worker 			const struct cmd_desc *cmd, bool with_advice)
645*59bfda1fSAndroid Build Coastguard Worker {
646*59bfda1fSAndroid Build Coastguard Worker 	u64 buf_size = 0, inc_num = 0, written = 0;
647*59bfda1fSAndroid Build Coastguard Worker 	u64 offset;
648*59bfda1fSAndroid Build Coastguard Worker 	char *buf = NULL;
649*59bfda1fSAndroid Build Coastguard Worker 	unsigned bs, count, i;
650*59bfda1fSAndroid Build Coastguard Worker 	int flags = 0;
651*59bfda1fSAndroid Build Coastguard Worker 	int fd;
652*59bfda1fSAndroid Build Coastguard Worker 	u64 total_time = 0, max_time = 0, max_time_t = 0;
653*59bfda1fSAndroid Build Coastguard Worker 	bool atomic_commit = false, atomic_abort = false, replace = false;
654*59bfda1fSAndroid Build Coastguard Worker 	int useconds = 0;
655*59bfda1fSAndroid Build Coastguard Worker 
656*59bfda1fSAndroid Build Coastguard Worker 	srand(time(0));
657*59bfda1fSAndroid Build Coastguard Worker 
658*59bfda1fSAndroid Build Coastguard Worker 	bs = atoi(argv[1]);
659*59bfda1fSAndroid Build Coastguard Worker 	if (bs > 1024)
660*59bfda1fSAndroid Build Coastguard Worker 		die("Too big chunk size - limit: 4MB");
661*59bfda1fSAndroid Build Coastguard Worker 
662*59bfda1fSAndroid Build Coastguard Worker 	buf_size = bs * F2FS_DEFAULT_BLKSIZE;
663*59bfda1fSAndroid Build Coastguard Worker 
664*59bfda1fSAndroid Build Coastguard Worker 	offset = atoi(argv[2]) * buf_size;
665*59bfda1fSAndroid Build Coastguard Worker 
666*59bfda1fSAndroid Build Coastguard Worker 	buf = aligned_xalloc(F2FS_DEFAULT_BLKSIZE, buf_size);
667*59bfda1fSAndroid Build Coastguard Worker 	count = atoi(argv[3]);
668*59bfda1fSAndroid Build Coastguard Worker 
669*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[4], "zero"))
670*59bfda1fSAndroid Build Coastguard Worker 		memset(buf, 0, buf_size);
671*59bfda1fSAndroid Build Coastguard Worker 	else if (strcmp(argv[4], "inc_num") && strcmp(argv[4], "rand"))
672*59bfda1fSAndroid Build Coastguard Worker 		die("Wrong pattern type");
673*59bfda1fSAndroid Build Coastguard Worker 
674*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[5], "dio")) {
675*59bfda1fSAndroid Build Coastguard Worker 		flags |= O_DIRECT;
676*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(argv[5], "dsync")) {
677*59bfda1fSAndroid Build Coastguard Worker 		flags |= O_DIRECT | O_DSYNC;
678*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(argv[5], "osync")) {
679*59bfda1fSAndroid Build Coastguard Worker 		flags |= O_SYNC;
680*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(argv[5], "atomic_commit")) {
681*59bfda1fSAndroid Build Coastguard Worker 		atomic_commit = true;
682*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(argv[5], "atomic_abort")) {
683*59bfda1fSAndroid Build Coastguard Worker 		atomic_abort = true;
684*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(argv[5], "atomic_rcommit")) {
685*59bfda1fSAndroid Build Coastguard Worker 		atomic_commit = true;
686*59bfda1fSAndroid Build Coastguard Worker 		replace = true;
687*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(argv[5], "atomic_rabort")) {
688*59bfda1fSAndroid Build Coastguard Worker 		atomic_abort = true;
689*59bfda1fSAndroid Build Coastguard Worker 		replace = true;
690*59bfda1fSAndroid Build Coastguard Worker 	} else if (strcmp(argv[5], "buffered")) {
691*59bfda1fSAndroid Build Coastguard Worker 		die("Wrong IO type");
692*59bfda1fSAndroid Build Coastguard Worker 	}
693*59bfda1fSAndroid Build Coastguard Worker 
694*59bfda1fSAndroid Build Coastguard Worker 	if (!with_advice) {
695*59bfda1fSAndroid Build Coastguard Worker 		fd = xopen(argv[6], O_CREAT | O_WRONLY | flags, 0755);
696*59bfda1fSAndroid Build Coastguard Worker 	} else {
697*59bfda1fSAndroid Build Coastguard Worker 		unsigned char advice;
698*59bfda1fSAndroid Build Coastguard Worker 		int ret;
699*59bfda1fSAndroid Build Coastguard Worker 
700*59bfda1fSAndroid Build Coastguard Worker 		if (!strcmp(argv[6], "hot"))
701*59bfda1fSAndroid Build Coastguard Worker 			advice = FADVISE_HOT_BIT;
702*59bfda1fSAndroid Build Coastguard Worker 		else if (!strcmp(argv[6], "cold"))
703*59bfda1fSAndroid Build Coastguard Worker 			advice = FADVISE_COLD_BIT;
704*59bfda1fSAndroid Build Coastguard Worker 		else
705*59bfda1fSAndroid Build Coastguard Worker 			die("Wrong Advise type");
706*59bfda1fSAndroid Build Coastguard Worker 
707*59bfda1fSAndroid Build Coastguard Worker 		fd = xopen(argv[7], O_CREAT | O_WRONLY | flags, 0755);
708*59bfda1fSAndroid Build Coastguard Worker 
709*59bfda1fSAndroid Build Coastguard Worker 		ret = fsetxattr(fd, F2FS_SYSTEM_ADVISE_NAME,
710*59bfda1fSAndroid Build Coastguard Worker 				    (char *)&advice, 1, XATTR_CREATE);
711*59bfda1fSAndroid Build Coastguard Worker 		if (ret) {
712*59bfda1fSAndroid Build Coastguard Worker 			fputs("fsetxattr advice failed\n", stderr);
713*59bfda1fSAndroid Build Coastguard Worker 			exit(1);
714*59bfda1fSAndroid Build Coastguard Worker 		}
715*59bfda1fSAndroid Build Coastguard Worker 	}
716*59bfda1fSAndroid Build Coastguard Worker 
717*59bfda1fSAndroid Build Coastguard Worker 	if (atomic_commit || atomic_abort) {
718*59bfda1fSAndroid Build Coastguard Worker 		int ret;
719*59bfda1fSAndroid Build Coastguard Worker 
720*59bfda1fSAndroid Build Coastguard Worker 		if (argc == 8)
721*59bfda1fSAndroid Build Coastguard Worker 			useconds = atoi(argv[7]) * 1000;
722*59bfda1fSAndroid Build Coastguard Worker 
723*59bfda1fSAndroid Build Coastguard Worker 		if (replace)
724*59bfda1fSAndroid Build Coastguard Worker 			ret = ioctl(fd, F2FS_IOC_START_ATOMIC_REPLACE);
725*59bfda1fSAndroid Build Coastguard Worker 		else
726*59bfda1fSAndroid Build Coastguard Worker 			ret = ioctl(fd, F2FS_IOC_START_ATOMIC_WRITE);
727*59bfda1fSAndroid Build Coastguard Worker 
728*59bfda1fSAndroid Build Coastguard Worker 		if (ret < 0) {
729*59bfda1fSAndroid Build Coastguard Worker 			fputs("setting atomic file mode failed\n", stderr);
730*59bfda1fSAndroid Build Coastguard Worker 			exit(1);
731*59bfda1fSAndroid Build Coastguard Worker 		}
732*59bfda1fSAndroid Build Coastguard Worker 	}
733*59bfda1fSAndroid Build Coastguard Worker 
734*59bfda1fSAndroid Build Coastguard Worker 	total_time = get_current_us();
735*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < count; i++) {
736*59bfda1fSAndroid Build Coastguard Worker 		uint64_t ret;
737*59bfda1fSAndroid Build Coastguard Worker 
738*59bfda1fSAndroid Build Coastguard Worker 		if (!strcmp(argv[4], "inc_num"))
739*59bfda1fSAndroid Build Coastguard Worker 			*(int *)buf = inc_num++;
740*59bfda1fSAndroid Build Coastguard Worker 		else if (!strcmp(argv[4], "rand"))
741*59bfda1fSAndroid Build Coastguard Worker 			*(int *)buf = rand();
742*59bfda1fSAndroid Build Coastguard Worker 
743*59bfda1fSAndroid Build Coastguard Worker 		/* write data */
744*59bfda1fSAndroid Build Coastguard Worker 		max_time_t = get_current_us();
745*59bfda1fSAndroid Build Coastguard Worker 		ret = pwrite(fd, buf, buf_size, offset + buf_size * i);
746*59bfda1fSAndroid Build Coastguard Worker 		max_time_t = get_current_us() - max_time_t;
747*59bfda1fSAndroid Build Coastguard Worker 		if (max_time < max_time_t)
748*59bfda1fSAndroid Build Coastguard Worker 			max_time = max_time_t;
749*59bfda1fSAndroid Build Coastguard Worker 		if (ret != buf_size)
750*59bfda1fSAndroid Build Coastguard Worker 			break;
751*59bfda1fSAndroid Build Coastguard Worker 		written += ret;
752*59bfda1fSAndroid Build Coastguard Worker 	}
753*59bfda1fSAndroid Build Coastguard Worker 
754*59bfda1fSAndroid Build Coastguard Worker 	if (useconds)
755*59bfda1fSAndroid Build Coastguard Worker 		usleep(useconds);
756*59bfda1fSAndroid Build Coastguard Worker 
757*59bfda1fSAndroid Build Coastguard Worker 	if (atomic_commit) {
758*59bfda1fSAndroid Build Coastguard Worker 		int ret;
759*59bfda1fSAndroid Build Coastguard Worker 
760*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(fd, F2FS_IOC_COMMIT_ATOMIC_WRITE);
761*59bfda1fSAndroid Build Coastguard Worker 		if (ret < 0) {
762*59bfda1fSAndroid Build Coastguard Worker 			fputs("committing atomic write failed\n", stderr);
763*59bfda1fSAndroid Build Coastguard Worker 			exit(1);
764*59bfda1fSAndroid Build Coastguard Worker 		}
765*59bfda1fSAndroid Build Coastguard Worker 	} else if (atomic_abort) {
766*59bfda1fSAndroid Build Coastguard Worker 		int ret;
767*59bfda1fSAndroid Build Coastguard Worker 
768*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(fd, F2FS_IOC_ABORT_VOLATILE_WRITE);
769*59bfda1fSAndroid Build Coastguard Worker 		if (ret < 0) {
770*59bfda1fSAndroid Build Coastguard Worker 			fputs("aborting atomic write failed\n", stderr);
771*59bfda1fSAndroid Build Coastguard Worker 			exit(1);
772*59bfda1fSAndroid Build Coastguard Worker 		}
773*59bfda1fSAndroid Build Coastguard Worker 	}
774*59bfda1fSAndroid Build Coastguard Worker 
775*59bfda1fSAndroid Build Coastguard Worker 	printf("Written %"PRIu64" bytes with pattern=%s, total_time=%"PRIu64" us, max_latency=%"PRIu64" us\n",
776*59bfda1fSAndroid Build Coastguard Worker 				written, argv[4],
777*59bfda1fSAndroid Build Coastguard Worker 				get_current_us() - total_time,
778*59bfda1fSAndroid Build Coastguard Worker 				max_time);
779*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
780*59bfda1fSAndroid Build Coastguard Worker }
781*59bfda1fSAndroid Build Coastguard Worker 
782*59bfda1fSAndroid Build Coastguard Worker #define write_desc "write data into file"
783*59bfda1fSAndroid Build Coastguard Worker #define write_help					\
784*59bfda1fSAndroid Build Coastguard Worker "f2fs_io write [chunk_size in 4kb] [offset in chunk_size] [count] [pattern] [IO] [file_path] {delay}\n\n"	\
785*59bfda1fSAndroid Build Coastguard Worker "Write given patten data in file_path\n"		\
786*59bfda1fSAndroid Build Coastguard Worker "pattern can be\n"					\
787*59bfda1fSAndroid Build Coastguard Worker "  zero          : zeros\n"				\
788*59bfda1fSAndroid Build Coastguard Worker "  inc_num       : incrementing numbers\n"		\
789*59bfda1fSAndroid Build Coastguard Worker "  rand          : random numbers\n"			\
790*59bfda1fSAndroid Build Coastguard Worker "IO can be\n"						\
791*59bfda1fSAndroid Build Coastguard Worker "  buffered      : buffered IO\n"			\
792*59bfda1fSAndroid Build Coastguard Worker "  dio           : O_DIRECT\n"				\
793*59bfda1fSAndroid Build Coastguard Worker "  dsync         : O_DIRECT | O_DSYNC\n"		\
794*59bfda1fSAndroid Build Coastguard Worker "  osync         : O_SYNC\n"				\
795*59bfda1fSAndroid Build Coastguard Worker "  atomic_commit : atomic write & commit\n"		\
796*59bfda1fSAndroid Build Coastguard Worker "  atomic_abort  : atomic write & abort\n"		\
797*59bfda1fSAndroid Build Coastguard Worker "  atomic_rcommit: atomic replace & commit\n"		\
798*59bfda1fSAndroid Build Coastguard Worker "  atomic_rabort : atomic replace & abort\n"		\
799*59bfda1fSAndroid Build Coastguard Worker "{delay} is in ms unit and optional only for atomic operations\n"
800*59bfda1fSAndroid Build Coastguard Worker 
do_write(int argc,char ** argv,const struct cmd_desc * cmd)801*59bfda1fSAndroid Build Coastguard Worker static void do_write(int argc, char **argv, const struct cmd_desc *cmd)
802*59bfda1fSAndroid Build Coastguard Worker {
803*59bfda1fSAndroid Build Coastguard Worker 	if (argc < 7 || argc > 8) {
804*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
805*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
806*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
807*59bfda1fSAndroid Build Coastguard Worker 	}
808*59bfda1fSAndroid Build Coastguard Worker 	do_write_with_advice(argc, argv, cmd, false);
809*59bfda1fSAndroid Build Coastguard Worker }
810*59bfda1fSAndroid Build Coastguard Worker 
811*59bfda1fSAndroid Build Coastguard Worker #define write_advice_desc "write data into file with a hint"
812*59bfda1fSAndroid Build Coastguard Worker #define write_advice_help					\
813*59bfda1fSAndroid Build Coastguard Worker "f2fs_io write_advice [chunk_size in 4kb] [offset in chunk_size] [count] [pattern] [IO] [advise] [file_path] {delay}\n\n"	\
814*59bfda1fSAndroid Build Coastguard Worker "Write given patten data in file_path\n"		\
815*59bfda1fSAndroid Build Coastguard Worker "pattern can be\n"					\
816*59bfda1fSAndroid Build Coastguard Worker "  zero          : zeros\n"				\
817*59bfda1fSAndroid Build Coastguard Worker "  inc_num       : incrementing numbers\n"		\
818*59bfda1fSAndroid Build Coastguard Worker "  rand          : random numbers\n"			\
819*59bfda1fSAndroid Build Coastguard Worker "IO can be\n"						\
820*59bfda1fSAndroid Build Coastguard Worker "  buffered      : buffered IO\n"			\
821*59bfda1fSAndroid Build Coastguard Worker "  dio           : O_DIRECT\n"				\
822*59bfda1fSAndroid Build Coastguard Worker "  dsync         : O_DIRECT | O_DSYNC\n"		\
823*59bfda1fSAndroid Build Coastguard Worker "  osync         : O_SYNC\n"				\
824*59bfda1fSAndroid Build Coastguard Worker "  atomic_commit : atomic write & commit\n"		\
825*59bfda1fSAndroid Build Coastguard Worker "  atomic_abort  : atomic write & abort\n"		\
826*59bfda1fSAndroid Build Coastguard Worker "  atomic_rcommit: atomic replace & commit\n"		\
827*59bfda1fSAndroid Build Coastguard Worker "  atomic_rabort : atomic replace & abort\n"		\
828*59bfda1fSAndroid Build Coastguard Worker "advise can be\n"					\
829*59bfda1fSAndroid Build Coastguard Worker "  cold : indicate a cold file\n"			\
830*59bfda1fSAndroid Build Coastguard Worker "  hot  : indicate a hot file\n"			\
831*59bfda1fSAndroid Build Coastguard Worker "{delay} is in ms unit and optional only for atomic operations\n"
832*59bfda1fSAndroid Build Coastguard Worker 
do_write_advice(int argc,char ** argv,const struct cmd_desc * cmd)833*59bfda1fSAndroid Build Coastguard Worker static void do_write_advice(int argc, char **argv, const struct cmd_desc *cmd)
834*59bfda1fSAndroid Build Coastguard Worker {
835*59bfda1fSAndroid Build Coastguard Worker 	if (argc < 8 || argc > 9) {
836*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
837*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
838*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
839*59bfda1fSAndroid Build Coastguard Worker 	}
840*59bfda1fSAndroid Build Coastguard Worker 	do_write_with_advice(argc, argv, cmd, true);
841*59bfda1fSAndroid Build Coastguard Worker }
842*59bfda1fSAndroid Build Coastguard Worker 
843*59bfda1fSAndroid Build Coastguard Worker #define read_desc "read data from file"
844*59bfda1fSAndroid Build Coastguard Worker #define read_help					\
845*59bfda1fSAndroid Build Coastguard Worker "f2fs_io read [chunk_size in 4kb] [offset in chunk_size] [count] [IO] [advice] [print_nbytes] [file_path]\n\n"	\
846*59bfda1fSAndroid Build Coastguard Worker "Read data in file_path and print nbytes\n"		\
847*59bfda1fSAndroid Build Coastguard Worker "IO can be\n"						\
848*59bfda1fSAndroid Build Coastguard Worker "  buffered : buffered IO\n"				\
849*59bfda1fSAndroid Build Coastguard Worker "  dio      : direct IO\n"				\
850*59bfda1fSAndroid Build Coastguard Worker "  mmap     : mmap IO\n"				\
851*59bfda1fSAndroid Build Coastguard Worker "advice can be\n"					\
852*59bfda1fSAndroid Build Coastguard Worker " 1 : set sequential|willneed\n"			\
853*59bfda1fSAndroid Build Coastguard Worker " 0 : none\n"						\
854*59bfda1fSAndroid Build Coastguard Worker 
do_read(int argc,char ** argv,const struct cmd_desc * cmd)855*59bfda1fSAndroid Build Coastguard Worker static void do_read(int argc, char **argv, const struct cmd_desc *cmd)
856*59bfda1fSAndroid Build Coastguard Worker {
857*59bfda1fSAndroid Build Coastguard Worker 	u64 buf_size = 0, ret = 0, read_cnt = 0;
858*59bfda1fSAndroid Build Coastguard Worker 	u64 offset;
859*59bfda1fSAndroid Build Coastguard Worker 	char *buf = NULL;
860*59bfda1fSAndroid Build Coastguard Worker 	char *data;
861*59bfda1fSAndroid Build Coastguard Worker 	char *print_buf = NULL;
862*59bfda1fSAndroid Build Coastguard Worker 	unsigned bs, count, i, print_bytes;
863*59bfda1fSAndroid Build Coastguard Worker 	u64 total_time = 0;
864*59bfda1fSAndroid Build Coastguard Worker 	int flags = 0;
865*59bfda1fSAndroid Build Coastguard Worker 	int do_mmap = 0;
866*59bfda1fSAndroid Build Coastguard Worker 	int fd, advice;
867*59bfda1fSAndroid Build Coastguard Worker 
868*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 8) {
869*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
870*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
871*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
872*59bfda1fSAndroid Build Coastguard Worker 	}
873*59bfda1fSAndroid Build Coastguard Worker 
874*59bfda1fSAndroid Build Coastguard Worker 	bs = atoi(argv[1]);
875*59bfda1fSAndroid Build Coastguard Worker 	if (bs > 256 * 1024)
876*59bfda1fSAndroid Build Coastguard Worker 		die("Too big chunk size - limit: 1GB");
877*59bfda1fSAndroid Build Coastguard Worker 	buf_size = bs * F2FS_DEFAULT_BLKSIZE;
878*59bfda1fSAndroid Build Coastguard Worker 
879*59bfda1fSAndroid Build Coastguard Worker 	offset = atoi(argv[2]) * buf_size;
880*59bfda1fSAndroid Build Coastguard Worker 
881*59bfda1fSAndroid Build Coastguard Worker 	buf = aligned_xalloc(F2FS_DEFAULT_BLKSIZE, buf_size);
882*59bfda1fSAndroid Build Coastguard Worker 
883*59bfda1fSAndroid Build Coastguard Worker 	count = atoi(argv[3]);
884*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[4], "dio"))
885*59bfda1fSAndroid Build Coastguard Worker 		flags |= O_DIRECT;
886*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[4], "mmap"))
887*59bfda1fSAndroid Build Coastguard Worker 		do_mmap = 1;
888*59bfda1fSAndroid Build Coastguard Worker 	else if (strcmp(argv[4], "buffered"))
889*59bfda1fSAndroid Build Coastguard Worker 		die("Wrong IO type");
890*59bfda1fSAndroid Build Coastguard Worker 
891*59bfda1fSAndroid Build Coastguard Worker 	print_bytes = atoi(argv[6]);
892*59bfda1fSAndroid Build Coastguard Worker 	if (print_bytes > buf_size)
893*59bfda1fSAndroid Build Coastguard Worker 		die("Print_nbytes should be less then chunk_size in kb");
894*59bfda1fSAndroid Build Coastguard Worker 
895*59bfda1fSAndroid Build Coastguard Worker 	print_buf = xmalloc(print_bytes);
896*59bfda1fSAndroid Build Coastguard Worker 
897*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[7], O_RDONLY | flags, 0);
898*59bfda1fSAndroid Build Coastguard Worker 
899*59bfda1fSAndroid Build Coastguard Worker 	advice = atoi(argv[5]);
900*59bfda1fSAndroid Build Coastguard Worker 	if (advice) {
901*59bfda1fSAndroid Build Coastguard Worker 		if (posix_fadvise(fd, 0, F2FS_DEFAULT_BLKSIZE,
902*59bfda1fSAndroid Build Coastguard Worker 				POSIX_FADV_SEQUENTIAL) != 0)
903*59bfda1fSAndroid Build Coastguard Worker 			die_errno("fadvise failed");
904*59bfda1fSAndroid Build Coastguard Worker 		if (posix_fadvise(fd, 0, F2FS_DEFAULT_BLKSIZE,
905*59bfda1fSAndroid Build Coastguard Worker 				POSIX_FADV_WILLNEED) != 0)
906*59bfda1fSAndroid Build Coastguard Worker 			die_errno("fadvise failed");
907*59bfda1fSAndroid Build Coastguard Worker 		printf("fadvise SEQUENTIAL|WILLNEED to a file: %s\n", argv[7]);
908*59bfda1fSAndroid Build Coastguard Worker 	}
909*59bfda1fSAndroid Build Coastguard Worker 
910*59bfda1fSAndroid Build Coastguard Worker 	total_time = get_current_us();
911*59bfda1fSAndroid Build Coastguard Worker 	if (do_mmap) {
912*59bfda1fSAndroid Build Coastguard Worker 		data = mmap(NULL, count * buf_size, PROT_READ,
913*59bfda1fSAndroid Build Coastguard Worker 						MAP_SHARED | MAP_POPULATE, fd, offset);
914*59bfda1fSAndroid Build Coastguard Worker 		if (data == MAP_FAILED)
915*59bfda1fSAndroid Build Coastguard Worker 			die("Mmap failed");
916*59bfda1fSAndroid Build Coastguard Worker 	}
917*59bfda1fSAndroid Build Coastguard Worker 	if (!do_mmap) {
918*59bfda1fSAndroid Build Coastguard Worker 		for (i = 0; i < count; i++) {
919*59bfda1fSAndroid Build Coastguard Worker 			ret = pread(fd, buf, buf_size, offset + buf_size * i);
920*59bfda1fSAndroid Build Coastguard Worker 			if (ret != buf_size) {
921*59bfda1fSAndroid Build Coastguard Worker 				printf("pread expected: %"PRIu64", readed: %"PRIu64"\n",
922*59bfda1fSAndroid Build Coastguard Worker 						buf_size, ret);
923*59bfda1fSAndroid Build Coastguard Worker 				if (ret > 0) {
924*59bfda1fSAndroid Build Coastguard Worker 					read_cnt += ret;
925*59bfda1fSAndroid Build Coastguard Worker 					memcpy(print_buf, buf, print_bytes);
926*59bfda1fSAndroid Build Coastguard Worker 				}
927*59bfda1fSAndroid Build Coastguard Worker 				break;
928*59bfda1fSAndroid Build Coastguard Worker 			}
929*59bfda1fSAndroid Build Coastguard Worker 
930*59bfda1fSAndroid Build Coastguard Worker 			read_cnt += ret;
931*59bfda1fSAndroid Build Coastguard Worker 			if (i == 0)
932*59bfda1fSAndroid Build Coastguard Worker 				memcpy(print_buf, buf, print_bytes);
933*59bfda1fSAndroid Build Coastguard Worker 		}
934*59bfda1fSAndroid Build Coastguard Worker 	} else {
935*59bfda1fSAndroid Build Coastguard Worker 		read_cnt = count * buf_size;
936*59bfda1fSAndroid Build Coastguard Worker 		memcpy(print_buf, data, print_bytes);
937*59bfda1fSAndroid Build Coastguard Worker 	}
938*59bfda1fSAndroid Build Coastguard Worker 	printf("Read %"PRIu64" bytes total_time = %"PRIu64" us, BW = %.Lf MB/s print %u bytes:\n",
939*59bfda1fSAndroid Build Coastguard Worker 		read_cnt, get_current_us() - total_time,
940*59bfda1fSAndroid Build Coastguard Worker 		((long double)read_cnt / (get_current_us() - total_time)), print_bytes);
941*59bfda1fSAndroid Build Coastguard Worker 	printf("%08"PRIx64" : ", offset);
942*59bfda1fSAndroid Build Coastguard Worker 	for (i = 1; i <= print_bytes; i++) {
943*59bfda1fSAndroid Build Coastguard Worker 		printf("%02x", print_buf[i - 1]);
944*59bfda1fSAndroid Build Coastguard Worker 		if (i % 16 == 0)
945*59bfda1fSAndroid Build Coastguard Worker 			printf("\n%08"PRIx64" : ", offset + 16 * i);
946*59bfda1fSAndroid Build Coastguard Worker 		else if (i % 2 == 0)
947*59bfda1fSAndroid Build Coastguard Worker 			printf(" ");
948*59bfda1fSAndroid Build Coastguard Worker 	}
949*59bfda1fSAndroid Build Coastguard Worker 	printf("\n");
950*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
951*59bfda1fSAndroid Build Coastguard Worker }
952*59bfda1fSAndroid Build Coastguard Worker 
953*59bfda1fSAndroid Build Coastguard Worker #define randread_desc "random read data from file"
954*59bfda1fSAndroid Build Coastguard Worker #define randread_help					\
955*59bfda1fSAndroid Build Coastguard Worker "f2fs_io randread [chunk_size in 4kb] [count] [IO] [advise] [file_path]\n\n"	\
956*59bfda1fSAndroid Build Coastguard Worker "Do random read data in file_path\n"		\
957*59bfda1fSAndroid Build Coastguard Worker "IO can be\n"						\
958*59bfda1fSAndroid Build Coastguard Worker "  buffered : buffered IO\n"				\
959*59bfda1fSAndroid Build Coastguard Worker "  dio      : direct IO\n"				\
960*59bfda1fSAndroid Build Coastguard Worker "  mmap     : mmap IO\n"				\
961*59bfda1fSAndroid Build Coastguard Worker "advice can be\n"					\
962*59bfda1fSAndroid Build Coastguard Worker " 1 : set random|willneed\n"				\
963*59bfda1fSAndroid Build Coastguard Worker " 0 : none\n"						\
964*59bfda1fSAndroid Build Coastguard Worker 
do_randread(int argc,char ** argv,const struct cmd_desc * cmd)965*59bfda1fSAndroid Build Coastguard Worker static void do_randread(int argc, char **argv, const struct cmd_desc *cmd)
966*59bfda1fSAndroid Build Coastguard Worker {
967*59bfda1fSAndroid Build Coastguard Worker 	u64 buf_size = 0, ret = 0, read_cnt = 0;
968*59bfda1fSAndroid Build Coastguard Worker 	u64 idx, end_idx, aligned_size;
969*59bfda1fSAndroid Build Coastguard Worker 	char *buf = NULL;
970*59bfda1fSAndroid Build Coastguard Worker 	char *data;
971*59bfda1fSAndroid Build Coastguard Worker 	unsigned bs, count, i, j;
972*59bfda1fSAndroid Build Coastguard Worker 	u64 total_time = 0, elapsed_time = 0;
973*59bfda1fSAndroid Build Coastguard Worker 	int flags = 0;
974*59bfda1fSAndroid Build Coastguard Worker 	int do_mmap = 0;
975*59bfda1fSAndroid Build Coastguard Worker 	int fd, advice;
976*59bfda1fSAndroid Build Coastguard Worker 	time_t t;
977*59bfda1fSAndroid Build Coastguard Worker 	struct stat stbuf;
978*59bfda1fSAndroid Build Coastguard Worker 
979*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 6) {
980*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
981*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
982*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
983*59bfda1fSAndroid Build Coastguard Worker 	}
984*59bfda1fSAndroid Build Coastguard Worker 
985*59bfda1fSAndroid Build Coastguard Worker 	bs = atoi(argv[1]);
986*59bfda1fSAndroid Build Coastguard Worker 	if (bs > 1024)
987*59bfda1fSAndroid Build Coastguard Worker 		die("Too big chunk size - limit: 4MB");
988*59bfda1fSAndroid Build Coastguard Worker 	buf_size = bs * F2FS_DEFAULT_BLKSIZE;
989*59bfda1fSAndroid Build Coastguard Worker 
990*59bfda1fSAndroid Build Coastguard Worker 	buf = aligned_xalloc(F2FS_DEFAULT_BLKSIZE, buf_size);
991*59bfda1fSAndroid Build Coastguard Worker 
992*59bfda1fSAndroid Build Coastguard Worker 	count = atoi(argv[2]);
993*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[3], "dio"))
994*59bfda1fSAndroid Build Coastguard Worker 		flags |= O_DIRECT;
995*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[3], "mmap"))
996*59bfda1fSAndroid Build Coastguard Worker 		do_mmap = 1;
997*59bfda1fSAndroid Build Coastguard Worker 	else if (strcmp(argv[3], "buffered"))
998*59bfda1fSAndroid Build Coastguard Worker 		die("Wrong IO type");
999*59bfda1fSAndroid Build Coastguard Worker 
1000*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[5], O_RDONLY | flags, 0);
1001*59bfda1fSAndroid Build Coastguard Worker 
1002*59bfda1fSAndroid Build Coastguard Worker 	advice = atoi(argv[4]);
1003*59bfda1fSAndroid Build Coastguard Worker 	if (advice) {
1004*59bfda1fSAndroid Build Coastguard Worker 		if (posix_fadvise(fd, 0, stbuf.st_size, POSIX_FADV_RANDOM) != 0)
1005*59bfda1fSAndroid Build Coastguard Worker 			die_errno("fadvise failed");
1006*59bfda1fSAndroid Build Coastguard Worker 		if (posix_fadvise(fd, 0, 4096, POSIX_FADV_WILLNEED) != 0)
1007*59bfda1fSAndroid Build Coastguard Worker 			die_errno("fadvise failed");
1008*59bfda1fSAndroid Build Coastguard Worker 		printf("fadvise RANDOM|WILLNEED to a file: %s\n", argv[5]);
1009*59bfda1fSAndroid Build Coastguard Worker 	}
1010*59bfda1fSAndroid Build Coastguard Worker 
1011*59bfda1fSAndroid Build Coastguard Worker 	if (fstat(fd, &stbuf) != 0)
1012*59bfda1fSAndroid Build Coastguard Worker 		die_errno("fstat of source file failed");
1013*59bfda1fSAndroid Build Coastguard Worker 
1014*59bfda1fSAndroid Build Coastguard Worker 	aligned_size = (u64)stbuf.st_size & ~((u64)(F2FS_DEFAULT_BLKSIZE - 1));
1015*59bfda1fSAndroid Build Coastguard Worker 	if (aligned_size < buf_size)
1016*59bfda1fSAndroid Build Coastguard Worker 		die("File is too small to random read");
1017*59bfda1fSAndroid Build Coastguard Worker 	end_idx = (u64)(aligned_size - buf_size) / (u64)F2FS_DEFAULT_BLKSIZE + 1;
1018*59bfda1fSAndroid Build Coastguard Worker 
1019*59bfda1fSAndroid Build Coastguard Worker 	if (do_mmap) {
1020*59bfda1fSAndroid Build Coastguard Worker 		data = mmap(NULL, stbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
1021*59bfda1fSAndroid Build Coastguard Worker 		if (data == MAP_FAILED)
1022*59bfda1fSAndroid Build Coastguard Worker 			die("Mmap failed");
1023*59bfda1fSAndroid Build Coastguard Worker 		if (madvise((void *)data, stbuf.st_size, MADV_RANDOM) != 0)
1024*59bfda1fSAndroid Build Coastguard Worker 			die_errno("madvise failed");
1025*59bfda1fSAndroid Build Coastguard Worker 	}
1026*59bfda1fSAndroid Build Coastguard Worker 
1027*59bfda1fSAndroid Build Coastguard Worker 	srand((unsigned) time(&t));
1028*59bfda1fSAndroid Build Coastguard Worker 
1029*59bfda1fSAndroid Build Coastguard Worker 	total_time = get_current_us();
1030*59bfda1fSAndroid Build Coastguard Worker 
1031*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < count; i++) {
1032*59bfda1fSAndroid Build Coastguard Worker 		idx = rand() % end_idx;
1033*59bfda1fSAndroid Build Coastguard Worker 
1034*59bfda1fSAndroid Build Coastguard Worker 		if (!do_mmap) {
1035*59bfda1fSAndroid Build Coastguard Worker 			ret = pread(fd, buf, buf_size, 4096 * idx);
1036*59bfda1fSAndroid Build Coastguard Worker 			if (ret != buf_size)
1037*59bfda1fSAndroid Build Coastguard Worker 				break;
1038*59bfda1fSAndroid Build Coastguard Worker 		} else {
1039*59bfda1fSAndroid Build Coastguard Worker 			for (j = 0; j < bs; j++)
1040*59bfda1fSAndroid Build Coastguard Worker 				*buf = data[4096 * (idx + j)];
1041*59bfda1fSAndroid Build Coastguard Worker 		}
1042*59bfda1fSAndroid Build Coastguard Worker 		read_cnt += buf_size;
1043*59bfda1fSAndroid Build Coastguard Worker 	}
1044*59bfda1fSAndroid Build Coastguard Worker 	elapsed_time = get_current_us() - total_time;
1045*59bfda1fSAndroid Build Coastguard Worker 
1046*59bfda1fSAndroid Build Coastguard Worker 	printf("Read %"PRIu64" bytes total_time = %"PRIu64" us, avg. latency = %.Lf us, IOPs= %.Lf, BW = %.Lf MB/s\n",
1047*59bfda1fSAndroid Build Coastguard Worker 		read_cnt, elapsed_time,
1048*59bfda1fSAndroid Build Coastguard Worker 		(long double)elapsed_time / count,
1049*59bfda1fSAndroid Build Coastguard Worker 		(long double)count * 1000 * 1000 / elapsed_time,
1050*59bfda1fSAndroid Build Coastguard Worker 		(long double)read_cnt / elapsed_time);
1051*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1052*59bfda1fSAndroid Build Coastguard Worker }
1053*59bfda1fSAndroid Build Coastguard Worker 
1054*59bfda1fSAndroid Build Coastguard Worker #define fiemap_desc "get block address in file"
1055*59bfda1fSAndroid Build Coastguard Worker #define fiemap_help					\
1056*59bfda1fSAndroid Build Coastguard Worker "f2fs_io fiemap [offset in 4kb] [count in 4kb] [file_path]\n\n"\
1057*59bfda1fSAndroid Build Coastguard Worker 
1058*59bfda1fSAndroid Build Coastguard Worker #if defined(HAVE_LINUX_FIEMAP_H) && defined(HAVE_LINUX_FS_H)
do_fiemap(int argc,char ** argv,const struct cmd_desc * cmd)1059*59bfda1fSAndroid Build Coastguard Worker static void do_fiemap(int argc, char **argv, const struct cmd_desc *cmd)
1060*59bfda1fSAndroid Build Coastguard Worker {
1061*59bfda1fSAndroid Build Coastguard Worker 	unsigned int i;
1062*59bfda1fSAndroid Build Coastguard Worker 	int fd, extents_mem_size;
1063*59bfda1fSAndroid Build Coastguard Worker 	u64 start, length;
1064*59bfda1fSAndroid Build Coastguard Worker 	u32 mapped_extents;
1065*59bfda1fSAndroid Build Coastguard Worker 	struct fiemap *fm = xmalloc(sizeof(struct fiemap));
1066*59bfda1fSAndroid Build Coastguard Worker 
1067*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 4) {
1068*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1069*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1070*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1071*59bfda1fSAndroid Build Coastguard Worker 	}
1072*59bfda1fSAndroid Build Coastguard Worker 
1073*59bfda1fSAndroid Build Coastguard Worker 	memset(fm, 0, sizeof(struct fiemap));
1074*59bfda1fSAndroid Build Coastguard Worker 	start = (u64)atoi(argv[1]) * F2FS_DEFAULT_BLKSIZE;
1075*59bfda1fSAndroid Build Coastguard Worker 	length = (u64)atoi(argv[2]) * F2FS_DEFAULT_BLKSIZE;
1076*59bfda1fSAndroid Build Coastguard Worker 	fm->fm_start = start;
1077*59bfda1fSAndroid Build Coastguard Worker 	fm->fm_length = length;
1078*59bfda1fSAndroid Build Coastguard Worker 
1079*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[3], O_RDONLY | O_LARGEFILE, 0);
1080*59bfda1fSAndroid Build Coastguard Worker 
1081*59bfda1fSAndroid Build Coastguard Worker 	printf("Fiemap: offset = %"PRIu64" len = %"PRIu64"\n",
1082*59bfda1fSAndroid Build Coastguard Worker 				start / F2FS_DEFAULT_BLKSIZE,
1083*59bfda1fSAndroid Build Coastguard Worker 				length / F2FS_DEFAULT_BLKSIZE);
1084*59bfda1fSAndroid Build Coastguard Worker 	if (ioctl(fd, FS_IOC_FIEMAP, fm) < 0)
1085*59bfda1fSAndroid Build Coastguard Worker 		die_errno("FIEMAP failed");
1086*59bfda1fSAndroid Build Coastguard Worker 
1087*59bfda1fSAndroid Build Coastguard Worker 	mapped_extents = fm->fm_mapped_extents;
1088*59bfda1fSAndroid Build Coastguard Worker 	extents_mem_size = sizeof(struct fiemap_extent) * mapped_extents;
1089*59bfda1fSAndroid Build Coastguard Worker 	free(fm);
1090*59bfda1fSAndroid Build Coastguard Worker 	fm = xmalloc(sizeof(struct fiemap) + extents_mem_size);
1091*59bfda1fSAndroid Build Coastguard Worker 
1092*59bfda1fSAndroid Build Coastguard Worker 	memset(fm, 0, sizeof(struct fiemap) + extents_mem_size);
1093*59bfda1fSAndroid Build Coastguard Worker 	fm->fm_start = start;
1094*59bfda1fSAndroid Build Coastguard Worker 	fm->fm_length = length;
1095*59bfda1fSAndroid Build Coastguard Worker 	fm->fm_extent_count = mapped_extents;
1096*59bfda1fSAndroid Build Coastguard Worker 
1097*59bfda1fSAndroid Build Coastguard Worker 	if (ioctl(fd, FS_IOC_FIEMAP, fm) < 0)
1098*59bfda1fSAndroid Build Coastguard Worker 		die_errno("FIEMAP failed");
1099*59bfda1fSAndroid Build Coastguard Worker 
1100*59bfda1fSAndroid Build Coastguard Worker 	printf("\t%-17s%-17s%-17s%s\n", "logical addr.", "physical addr.", "length", "flags");
1101*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < fm->fm_mapped_extents; i++) {
1102*59bfda1fSAndroid Build Coastguard Worker 		printf("%d\t%.16llx %.16llx %.16llx %.8x\n", i,
1103*59bfda1fSAndroid Build Coastguard Worker 		    fm->fm_extents[i].fe_logical, fm->fm_extents[i].fe_physical,
1104*59bfda1fSAndroid Build Coastguard Worker 		    fm->fm_extents[i].fe_length, fm->fm_extents[i].fe_flags);
1105*59bfda1fSAndroid Build Coastguard Worker 
1106*59bfda1fSAndroid Build Coastguard Worker 		if (fm->fm_extents[i].fe_flags & FIEMAP_EXTENT_LAST)
1107*59bfda1fSAndroid Build Coastguard Worker 			break;
1108*59bfda1fSAndroid Build Coastguard Worker 	}
1109*59bfda1fSAndroid Build Coastguard Worker 	printf("\n");
1110*59bfda1fSAndroid Build Coastguard Worker 	free(fm);
1111*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1112*59bfda1fSAndroid Build Coastguard Worker }
1113*59bfda1fSAndroid Build Coastguard Worker #else
do_fiemap(int UNUSED (argc),char ** UNUSED (argv),const struct cmd_desc * UNUSED (cmd))1114*59bfda1fSAndroid Build Coastguard Worker static void do_fiemap(int UNUSED(argc), char **UNUSED(argv),
1115*59bfda1fSAndroid Build Coastguard Worker 			const struct cmd_desc *UNUSED(cmd))
1116*59bfda1fSAndroid Build Coastguard Worker {
1117*59bfda1fSAndroid Build Coastguard Worker 	die("Not support for this platform");
1118*59bfda1fSAndroid Build Coastguard Worker }
1119*59bfda1fSAndroid Build Coastguard Worker #endif
1120*59bfda1fSAndroid Build Coastguard Worker 
1121*59bfda1fSAndroid Build Coastguard Worker #define gc_urgent_desc "start/end/run gc_urgent for given time period"
1122*59bfda1fSAndroid Build Coastguard Worker #define gc_urgent_help					\
1123*59bfda1fSAndroid Build Coastguard Worker "f2fs_io gc_urgent $dev [start/end/run] [time in sec]\n\n"\
1124*59bfda1fSAndroid Build Coastguard Worker " - f2fs_io gc_urgent sda21 start\n"		\
1125*59bfda1fSAndroid Build Coastguard Worker " - f2fs_io gc_urgent sda21 end\n"		\
1126*59bfda1fSAndroid Build Coastguard Worker " - f2fs_io gc_urgent sda21 run 10\n"		\
1127*59bfda1fSAndroid Build Coastguard Worker 
do_gc_urgent(int argc,char ** argv,const struct cmd_desc * cmd)1128*59bfda1fSAndroid Build Coastguard Worker static void do_gc_urgent(int argc, char **argv, const struct cmd_desc *cmd)
1129*59bfda1fSAndroid Build Coastguard Worker {
1130*59bfda1fSAndroid Build Coastguard Worker 	char command[255];
1131*59bfda1fSAndroid Build Coastguard Worker 
1132*59bfda1fSAndroid Build Coastguard Worker 	if (argc == 3 && !strcmp(argv[2], "start")) {
1133*59bfda1fSAndroid Build Coastguard Worker 		printf("gc_urgent: start on %s\n", argv[1]);
1134*59bfda1fSAndroid Build Coastguard Worker 		sprintf(command, "echo %d > %s/%s/gc_urgent", 1, "/sys/fs/f2fs/", argv[1]);
1135*59bfda1fSAndroid Build Coastguard Worker 		if (system(command))
1136*59bfda1fSAndroid Build Coastguard Worker 			exit(1);
1137*59bfda1fSAndroid Build Coastguard Worker 	} else if (argc == 3 && !strcmp(argv[2], "end")) {
1138*59bfda1fSAndroid Build Coastguard Worker 		printf("gc_urgent: end on %s\n", argv[1]);
1139*59bfda1fSAndroid Build Coastguard Worker 		sprintf(command, "echo %d > %s/%s/gc_urgent", 0, "/sys/fs/f2fs/", argv[1]);
1140*59bfda1fSAndroid Build Coastguard Worker 		if (system(command))
1141*59bfda1fSAndroid Build Coastguard Worker 			exit(1);
1142*59bfda1fSAndroid Build Coastguard Worker 	} else if (argc == 4 && !strcmp(argv[2], "run")) {
1143*59bfda1fSAndroid Build Coastguard Worker 		printf("gc_urgent: start on %s for %d secs\n", argv[1], atoi(argv[3]));
1144*59bfda1fSAndroid Build Coastguard Worker 		sprintf(command, "echo %d > %s/%s/gc_urgent", 1, "/sys/fs/f2fs/", argv[1]);
1145*59bfda1fSAndroid Build Coastguard Worker 		if (system(command))
1146*59bfda1fSAndroid Build Coastguard Worker 			exit(1);
1147*59bfda1fSAndroid Build Coastguard Worker 		sleep(atoi(argv[3]));
1148*59bfda1fSAndroid Build Coastguard Worker 		printf("gc_urgent: end on %s for %d secs\n", argv[1], atoi(argv[3]));
1149*59bfda1fSAndroid Build Coastguard Worker 		sprintf(command, "echo %d > %s/%s/gc_urgent", 0, "/sys/fs/f2fs/", argv[1]);
1150*59bfda1fSAndroid Build Coastguard Worker 		if (system(command))
1151*59bfda1fSAndroid Build Coastguard Worker 			exit(1);
1152*59bfda1fSAndroid Build Coastguard Worker 	} else {
1153*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1154*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1155*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1156*59bfda1fSAndroid Build Coastguard Worker 	}
1157*59bfda1fSAndroid Build Coastguard Worker }
1158*59bfda1fSAndroid Build Coastguard Worker 
1159*59bfda1fSAndroid Build Coastguard Worker #define defrag_file_desc "do defragment on file"
1160*59bfda1fSAndroid Build Coastguard Worker #define defrag_file_help						\
1161*59bfda1fSAndroid Build Coastguard Worker "f2fs_io defrag_file [start] [length] [file_path]\n\n"		\
1162*59bfda1fSAndroid Build Coastguard Worker "  start     : start offset of defragment region, unit: bytes\n"	\
1163*59bfda1fSAndroid Build Coastguard Worker "  length    : bytes number of defragment region\n"			\
1164*59bfda1fSAndroid Build Coastguard Worker 
do_defrag_file(int argc,char ** argv,const struct cmd_desc * cmd)1165*59bfda1fSAndroid Build Coastguard Worker static void do_defrag_file(int argc, char **argv, const struct cmd_desc *cmd)
1166*59bfda1fSAndroid Build Coastguard Worker {
1167*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_defragment df;
1168*59bfda1fSAndroid Build Coastguard Worker 	u64 len;
1169*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
1170*59bfda1fSAndroid Build Coastguard Worker 
1171*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 4) {
1172*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1173*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1174*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1175*59bfda1fSAndroid Build Coastguard Worker 	}
1176*59bfda1fSAndroid Build Coastguard Worker 
1177*59bfda1fSAndroid Build Coastguard Worker 	df.start = atoll(argv[1]);
1178*59bfda1fSAndroid Build Coastguard Worker 	df.len = len = atoll(argv[2]);
1179*59bfda1fSAndroid Build Coastguard Worker 
1180*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[3], O_RDWR, 0);
1181*59bfda1fSAndroid Build Coastguard Worker 
1182*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_DEFRAGMENT, &df);
1183*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1184*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_DEFRAGMENT failed");
1185*59bfda1fSAndroid Build Coastguard Worker 
1186*59bfda1fSAndroid Build Coastguard Worker 	printf("defrag %s in region[%"PRIu64", %"PRIu64"]\n",
1187*59bfda1fSAndroid Build Coastguard Worker 			argv[3], df.start, df.start + len);
1188*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1189*59bfda1fSAndroid Build Coastguard Worker }
1190*59bfda1fSAndroid Build Coastguard Worker 
1191*59bfda1fSAndroid Build Coastguard Worker #define copy_desc "copy a file"
1192*59bfda1fSAndroid Build Coastguard Worker #define copy_help							\
1193*59bfda1fSAndroid Build Coastguard Worker "f2fs_io copy [-d] [-m] [-s] src_path dst_path\n\n"			\
1194*59bfda1fSAndroid Build Coastguard Worker "  src_path  : path to source file\n"					\
1195*59bfda1fSAndroid Build Coastguard Worker "  dst_path  : path to destination file\n"				\
1196*59bfda1fSAndroid Build Coastguard Worker "  -d        : use direct I/O\n"					\
1197*59bfda1fSAndroid Build Coastguard Worker "  -m        : mmap the source file\n"					\
1198*59bfda1fSAndroid Build Coastguard Worker "  -s        : use sendfile\n"						\
1199*59bfda1fSAndroid Build Coastguard Worker 
do_copy(int argc,char ** argv,const struct cmd_desc * cmd)1200*59bfda1fSAndroid Build Coastguard Worker static void do_copy(int argc, char **argv, const struct cmd_desc *cmd)
1201*59bfda1fSAndroid Build Coastguard Worker {
1202*59bfda1fSAndroid Build Coastguard Worker 	int c;
1203*59bfda1fSAndroid Build Coastguard Worker 	int src_fd;
1204*59bfda1fSAndroid Build Coastguard Worker 	int dst_fd;
1205*59bfda1fSAndroid Build Coastguard Worker 	int open_flags = 0;
1206*59bfda1fSAndroid Build Coastguard Worker 	bool mmap_source_file = false;
1207*59bfda1fSAndroid Build Coastguard Worker 	bool use_sendfile = false;
1208*59bfda1fSAndroid Build Coastguard Worker 	ssize_t ret;
1209*59bfda1fSAndroid Build Coastguard Worker 
1210*59bfda1fSAndroid Build Coastguard Worker 	while ((c = getopt(argc, argv, "dms")) != -1) {
1211*59bfda1fSAndroid Build Coastguard Worker 		switch (c) {
1212*59bfda1fSAndroid Build Coastguard Worker 		case 'd':
1213*59bfda1fSAndroid Build Coastguard Worker 			open_flags |= O_DIRECT;
1214*59bfda1fSAndroid Build Coastguard Worker 			break;
1215*59bfda1fSAndroid Build Coastguard Worker 		case 'm':
1216*59bfda1fSAndroid Build Coastguard Worker 			mmap_source_file = true;
1217*59bfda1fSAndroid Build Coastguard Worker 			break;
1218*59bfda1fSAndroid Build Coastguard Worker 		case 's':
1219*59bfda1fSAndroid Build Coastguard Worker 			use_sendfile = true;
1220*59bfda1fSAndroid Build Coastguard Worker 			break;
1221*59bfda1fSAndroid Build Coastguard Worker 		default:
1222*59bfda1fSAndroid Build Coastguard Worker 			fputs(cmd->cmd_help, stderr);
1223*59bfda1fSAndroid Build Coastguard Worker 			exit(2);
1224*59bfda1fSAndroid Build Coastguard Worker 		}
1225*59bfda1fSAndroid Build Coastguard Worker 	}
1226*59bfda1fSAndroid Build Coastguard Worker 	argc -= optind;
1227*59bfda1fSAndroid Build Coastguard Worker 	argv += optind;
1228*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1229*59bfda1fSAndroid Build Coastguard Worker 		fputs("Wrong number of arguments\n\n", stderr);
1230*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1231*59bfda1fSAndroid Build Coastguard Worker 		exit(2);
1232*59bfda1fSAndroid Build Coastguard Worker 	}
1233*59bfda1fSAndroid Build Coastguard Worker 	if (mmap_source_file && use_sendfile)
1234*59bfda1fSAndroid Build Coastguard Worker 		die("-m and -s are mutually exclusive");
1235*59bfda1fSAndroid Build Coastguard Worker 
1236*59bfda1fSAndroid Build Coastguard Worker 	src_fd = xopen(argv[0], O_RDONLY | open_flags, 0);
1237*59bfda1fSAndroid Build Coastguard Worker 	dst_fd = xopen(argv[1], O_WRONLY | O_CREAT | O_TRUNC | open_flags, 0644);
1238*59bfda1fSAndroid Build Coastguard Worker 
1239*59bfda1fSAndroid Build Coastguard Worker 	if (mmap_source_file) {
1240*59bfda1fSAndroid Build Coastguard Worker 		struct stat stbuf;
1241*59bfda1fSAndroid Build Coastguard Worker 		void *src_addr;
1242*59bfda1fSAndroid Build Coastguard Worker 
1243*59bfda1fSAndroid Build Coastguard Worker 		if (fstat(src_fd, &stbuf) != 0)
1244*59bfda1fSAndroid Build Coastguard Worker 			die_errno("fstat of source file failed");
1245*59bfda1fSAndroid Build Coastguard Worker 
1246*59bfda1fSAndroid Build Coastguard Worker 		if ((size_t)stbuf.st_size != stbuf.st_size)
1247*59bfda1fSAndroid Build Coastguard Worker 			die("Source file is too large");
1248*59bfda1fSAndroid Build Coastguard Worker 
1249*59bfda1fSAndroid Build Coastguard Worker 		src_addr = mmap(NULL, stbuf.st_size, PROT_READ, MAP_SHARED,
1250*59bfda1fSAndroid Build Coastguard Worker 				src_fd, 0);
1251*59bfda1fSAndroid Build Coastguard Worker 		if (src_addr == MAP_FAILED)
1252*59bfda1fSAndroid Build Coastguard Worker 			die("mmap of source file failed");
1253*59bfda1fSAndroid Build Coastguard Worker 
1254*59bfda1fSAndroid Build Coastguard Worker 		full_write(dst_fd, src_addr, stbuf.st_size);
1255*59bfda1fSAndroid Build Coastguard Worker 
1256*59bfda1fSAndroid Build Coastguard Worker 		munmap(src_addr, stbuf.st_size);
1257*59bfda1fSAndroid Build Coastguard Worker 	} else if (use_sendfile) {
1258*59bfda1fSAndroid Build Coastguard Worker 		while ((ret = sendfile(dst_fd, src_fd, NULL, INT_MAX)) > 0)
1259*59bfda1fSAndroid Build Coastguard Worker 			;
1260*59bfda1fSAndroid Build Coastguard Worker 		if (ret < 0)
1261*59bfda1fSAndroid Build Coastguard Worker 			die_errno("sendfile failed");
1262*59bfda1fSAndroid Build Coastguard Worker 	} else {
1263*59bfda1fSAndroid Build Coastguard Worker 		char *buf = aligned_xalloc(F2FS_DEFAULT_BLKSIZE, F2FS_DEFAULT_BLKSIZE);
1264*59bfda1fSAndroid Build Coastguard Worker 
1265*59bfda1fSAndroid Build Coastguard Worker 		while ((ret = xread(src_fd, buf, F2FS_DEFAULT_BLKSIZE)) > 0)
1266*59bfda1fSAndroid Build Coastguard Worker 			full_write(dst_fd, buf, ret);
1267*59bfda1fSAndroid Build Coastguard Worker 		free(buf);
1268*59bfda1fSAndroid Build Coastguard Worker 	}
1269*59bfda1fSAndroid Build Coastguard Worker 	close(src_fd);
1270*59bfda1fSAndroid Build Coastguard Worker 	close(dst_fd);
1271*59bfda1fSAndroid Build Coastguard Worker }
1272*59bfda1fSAndroid Build Coastguard Worker 
1273*59bfda1fSAndroid Build Coastguard Worker #define get_cblocks_desc "get number of reserved blocks on compress inode"
1274*59bfda1fSAndroid Build Coastguard Worker #define get_cblocks_help "f2fs_io get_cblocks [file]\n\n"
1275*59bfda1fSAndroid Build Coastguard Worker 
do_get_cblocks(int argc,char ** argv,const struct cmd_desc * cmd)1276*59bfda1fSAndroid Build Coastguard Worker static void do_get_cblocks(int argc, char **argv, const struct cmd_desc *cmd)
1277*59bfda1fSAndroid Build Coastguard Worker {
1278*59bfda1fSAndroid Build Coastguard Worker 	unsigned long long blkcnt;
1279*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
1280*59bfda1fSAndroid Build Coastguard Worker 
1281*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1282*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1283*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1284*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1285*59bfda1fSAndroid Build Coastguard Worker 	}
1286*59bfda1fSAndroid Build Coastguard Worker 
1287*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_RDONLY, 0);
1288*59bfda1fSAndroid Build Coastguard Worker 
1289*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_GET_COMPRESS_BLOCKS, &blkcnt);
1290*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1291*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_GET_COMPRESS_BLOCKS failed");
1292*59bfda1fSAndroid Build Coastguard Worker 
1293*59bfda1fSAndroid Build Coastguard Worker 	printf("%llu\n", blkcnt);
1294*59bfda1fSAndroid Build Coastguard Worker 
1295*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1296*59bfda1fSAndroid Build Coastguard Worker }
1297*59bfda1fSAndroid Build Coastguard Worker 
1298*59bfda1fSAndroid Build Coastguard Worker #define release_cblocks_desc "release reserved blocks on compress inode"
1299*59bfda1fSAndroid Build Coastguard Worker #define release_cblocks_help "f2fs_io release_cblocks [file]\n\n"
1300*59bfda1fSAndroid Build Coastguard Worker 
do_release_cblocks(int argc,char ** argv,const struct cmd_desc * cmd)1301*59bfda1fSAndroid Build Coastguard Worker static void do_release_cblocks(int argc, char **argv, const struct cmd_desc *cmd)
1302*59bfda1fSAndroid Build Coastguard Worker {
1303*59bfda1fSAndroid Build Coastguard Worker 	unsigned long long blkcnt;
1304*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
1305*59bfda1fSAndroid Build Coastguard Worker 
1306*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1307*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1308*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1309*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1310*59bfda1fSAndroid Build Coastguard Worker 	}
1311*59bfda1fSAndroid Build Coastguard Worker 
1312*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_RDONLY, 0);
1313*59bfda1fSAndroid Build Coastguard Worker 
1314*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_RELEASE_COMPRESS_BLOCKS, &blkcnt);
1315*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1316*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_RELEASE_COMPRESS_BLOCKS failed");
1317*59bfda1fSAndroid Build Coastguard Worker 
1318*59bfda1fSAndroid Build Coastguard Worker 	printf("%llu\n", blkcnt);
1319*59bfda1fSAndroid Build Coastguard Worker 
1320*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1321*59bfda1fSAndroid Build Coastguard Worker }
1322*59bfda1fSAndroid Build Coastguard Worker 
1323*59bfda1fSAndroid Build Coastguard Worker #define reserve_cblocks_desc "reserve blocks on compress inode"
1324*59bfda1fSAndroid Build Coastguard Worker #define reserve_cblocks_help "f2fs_io reserve_cblocks [file]\n\n"
1325*59bfda1fSAndroid Build Coastguard Worker 
do_reserve_cblocks(int argc,char ** argv,const struct cmd_desc * cmd)1326*59bfda1fSAndroid Build Coastguard Worker static void do_reserve_cblocks(int argc, char **argv, const struct cmd_desc *cmd)
1327*59bfda1fSAndroid Build Coastguard Worker {
1328*59bfda1fSAndroid Build Coastguard Worker 	unsigned long long blkcnt;
1329*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
1330*59bfda1fSAndroid Build Coastguard Worker 
1331*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1332*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1333*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1334*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1335*59bfda1fSAndroid Build Coastguard Worker 	}
1336*59bfda1fSAndroid Build Coastguard Worker 
1337*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_RDONLY, 0);
1338*59bfda1fSAndroid Build Coastguard Worker 
1339*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_RESERVE_COMPRESS_BLOCKS, &blkcnt);
1340*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1341*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed");
1342*59bfda1fSAndroid Build Coastguard Worker 
1343*59bfda1fSAndroid Build Coastguard Worker 	printf("%llu\n", blkcnt);
1344*59bfda1fSAndroid Build Coastguard Worker 
1345*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1346*59bfda1fSAndroid Build Coastguard Worker }
1347*59bfda1fSAndroid Build Coastguard Worker 
1348*59bfda1fSAndroid Build Coastguard Worker #define get_coption_desc "get compression option of a compressed file"
1349*59bfda1fSAndroid Build Coastguard Worker #define get_coption_help						\
1350*59bfda1fSAndroid Build Coastguard Worker "f2fs_io get_coption [file]\n\n"	\
1351*59bfda1fSAndroid Build Coastguard Worker "  algorithm        : compression algorithm (0:lzo, 1: lz4, 2:zstd, 3:lzorle)\n"	\
1352*59bfda1fSAndroid Build Coastguard Worker "  log_cluster_size : compression cluster log size (2 <= log_size <= 8)\n"
1353*59bfda1fSAndroid Build Coastguard Worker 
do_get_coption(int argc,char ** argv,const struct cmd_desc * cmd)1354*59bfda1fSAndroid Build Coastguard Worker static void do_get_coption(int argc, char **argv, const struct cmd_desc *cmd)
1355*59bfda1fSAndroid Build Coastguard Worker {
1356*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_comp_option option;
1357*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
1358*59bfda1fSAndroid Build Coastguard Worker 
1359*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1360*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1361*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1362*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1363*59bfda1fSAndroid Build Coastguard Worker 	}
1364*59bfda1fSAndroid Build Coastguard Worker 
1365*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_RDONLY, 0);
1366*59bfda1fSAndroid Build Coastguard Worker 
1367*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_GET_COMPRESS_OPTION, &option);
1368*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1369*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_GET_COMPRESS_OPTION failed");
1370*59bfda1fSAndroid Build Coastguard Worker 
1371*59bfda1fSAndroid Build Coastguard Worker 	printf("compression algorithm:%u\n", option.algorithm);
1372*59bfda1fSAndroid Build Coastguard Worker 	printf("compression cluster log size:%u\n", option.log_cluster_size);
1373*59bfda1fSAndroid Build Coastguard Worker 
1374*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1375*59bfda1fSAndroid Build Coastguard Worker }
1376*59bfda1fSAndroid Build Coastguard Worker 
1377*59bfda1fSAndroid Build Coastguard Worker #define set_coption_desc "set compression option of a compressed file"
1378*59bfda1fSAndroid Build Coastguard Worker #define set_coption_help						\
1379*59bfda1fSAndroid Build Coastguard Worker "f2fs_io set_coption [algorithm] [log_cluster_size] [file_path]\n\n"	\
1380*59bfda1fSAndroid Build Coastguard Worker "  algorithm        : compression algorithm (0:lzo, 1: lz4, 2:zstd, 3:lzorle)\n"	\
1381*59bfda1fSAndroid Build Coastguard Worker "  log_cluster_size : compression cluster log size (2 <= log_size <= 8)\n"
1382*59bfda1fSAndroid Build Coastguard Worker 
do_set_coption(int argc,char ** argv,const struct cmd_desc * cmd)1383*59bfda1fSAndroid Build Coastguard Worker static void do_set_coption(int argc, char **argv, const struct cmd_desc *cmd)
1384*59bfda1fSAndroid Build Coastguard Worker {
1385*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_comp_option option;
1386*59bfda1fSAndroid Build Coastguard Worker 	int fd, ret;
1387*59bfda1fSAndroid Build Coastguard Worker 
1388*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 4) {
1389*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1390*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1391*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1392*59bfda1fSAndroid Build Coastguard Worker 	}
1393*59bfda1fSAndroid Build Coastguard Worker 
1394*59bfda1fSAndroid Build Coastguard Worker 	option.algorithm = atoi(argv[1]);
1395*59bfda1fSAndroid Build Coastguard Worker 	option.log_cluster_size = atoi(argv[2]);
1396*59bfda1fSAndroid Build Coastguard Worker 
1397*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[3], O_WRONLY, 0);
1398*59bfda1fSAndroid Build Coastguard Worker 
1399*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_SET_COMPRESS_OPTION, &option);
1400*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1401*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_SET_COMPRESS_OPTION failed");
1402*59bfda1fSAndroid Build Coastguard Worker 
1403*59bfda1fSAndroid Build Coastguard Worker 	printf("set compression option: algorithm=%u, log_cluster_size=%u\n",
1404*59bfda1fSAndroid Build Coastguard Worker 			option.algorithm, option.log_cluster_size);
1405*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1406*59bfda1fSAndroid Build Coastguard Worker }
1407*59bfda1fSAndroid Build Coastguard Worker 
1408*59bfda1fSAndroid Build Coastguard Worker #define decompress_desc "decompress an already compressed file"
1409*59bfda1fSAndroid Build Coastguard Worker #define decompress_help "f2fs_io decompress [file_path]\n\n"
1410*59bfda1fSAndroid Build Coastguard Worker 
do_decompress(int argc,char ** argv,const struct cmd_desc * cmd)1411*59bfda1fSAndroid Build Coastguard Worker static void do_decompress(int argc, char **argv, const struct cmd_desc *cmd)
1412*59bfda1fSAndroid Build Coastguard Worker {
1413*59bfda1fSAndroid Build Coastguard Worker 	int fd, ret;
1414*59bfda1fSAndroid Build Coastguard Worker 
1415*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1416*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1417*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1418*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1419*59bfda1fSAndroid Build Coastguard Worker 	}
1420*59bfda1fSAndroid Build Coastguard Worker 
1421*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_WRONLY, 0);
1422*59bfda1fSAndroid Build Coastguard Worker 
1423*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_DECOMPRESS_FILE);
1424*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1425*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_DECOMPRESS_FILE failed");
1426*59bfda1fSAndroid Build Coastguard Worker 
1427*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1428*59bfda1fSAndroid Build Coastguard Worker }
1429*59bfda1fSAndroid Build Coastguard Worker 
1430*59bfda1fSAndroid Build Coastguard Worker #define compress_desc "compress a compression enabled file"
1431*59bfda1fSAndroid Build Coastguard Worker #define compress_help "f2fs_io compress [file_path]\n\n"
1432*59bfda1fSAndroid Build Coastguard Worker 
do_compress(int argc,char ** argv,const struct cmd_desc * cmd)1433*59bfda1fSAndroid Build Coastguard Worker static void do_compress(int argc, char **argv, const struct cmd_desc *cmd)
1434*59bfda1fSAndroid Build Coastguard Worker {
1435*59bfda1fSAndroid Build Coastguard Worker 	int fd, ret;
1436*59bfda1fSAndroid Build Coastguard Worker 
1437*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1438*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1439*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1440*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1441*59bfda1fSAndroid Build Coastguard Worker 	}
1442*59bfda1fSAndroid Build Coastguard Worker 
1443*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_WRONLY, 0);
1444*59bfda1fSAndroid Build Coastguard Worker 
1445*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_COMPRESS_FILE);
1446*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1447*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_COMPRESS_FILE failed");
1448*59bfda1fSAndroid Build Coastguard Worker 
1449*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1450*59bfda1fSAndroid Build Coastguard Worker }
1451*59bfda1fSAndroid Build Coastguard Worker 
1452*59bfda1fSAndroid Build Coastguard Worker #define get_filename_encrypt_mode_desc "get file name encrypt mode"
1453*59bfda1fSAndroid Build Coastguard Worker #define get_filename_encrypt_mode_help					\
1454*59bfda1fSAndroid Build Coastguard Worker "f2fs_io filename_encrypt_mode [file or directory path]\n\n"		\
1455*59bfda1fSAndroid Build Coastguard Worker "Get the file name encription mode of the given file/directory.\n"	\
1456*59bfda1fSAndroid Build Coastguard Worker 
do_get_filename_encrypt_mode(int argc,char ** argv,const struct cmd_desc * cmd)1457*59bfda1fSAndroid Build Coastguard Worker static void do_get_filename_encrypt_mode (int argc, char **argv,
1458*59bfda1fSAndroid Build Coastguard Worker 						const struct cmd_desc *cmd)
1459*59bfda1fSAndroid Build Coastguard Worker {
1460*59bfda1fSAndroid Build Coastguard Worker 	static const char *enc_name[] = {
1461*59bfda1fSAndroid Build Coastguard Worker 		"invalid", /* FSCRYPT_MODE_INVALID (0) */
1462*59bfda1fSAndroid Build Coastguard Worker 		"aes-256-xts", /* FSCRYPT_MODE_AES_256_XTS (1) */
1463*59bfda1fSAndroid Build Coastguard Worker 		"aes-256-gcm", /* FSCRYPT_MODE_AES_256_GCM (2) */
1464*59bfda1fSAndroid Build Coastguard Worker 		"aes-256-cbc", /* FSCRYPT_MODE_AES_256_CBC (3) */
1465*59bfda1fSAndroid Build Coastguard Worker 		"aes-256-cts", /* FSCRYPT_MODE_AES_256_CTS (4) */
1466*59bfda1fSAndroid Build Coastguard Worker 		"aes-128-cbc", /* FSCRYPT_MODE_AES_128_CBC (5) */
1467*59bfda1fSAndroid Build Coastguard Worker 		"aes-128-cts", /* FSCRYPT_MODE_AES_128_CTS (6) */
1468*59bfda1fSAndroid Build Coastguard Worker 		"speck128-256-xts", /* FSCRYPT_MODE_SPECK128_256_XTS (7) */
1469*59bfda1fSAndroid Build Coastguard Worker 		"speck128-256-cts", /* FSCRYPT_MODE_SPECK128_256_CTS (8) */
1470*59bfda1fSAndroid Build Coastguard Worker 		"adiantum", /* FSCRYPT_MODE_ADIANTUM (9) */
1471*59bfda1fSAndroid Build Coastguard Worker 		"aes-256-hctr2", /* FSCRYPT_MODE_AES_256_HCTR2 (10) */
1472*59bfda1fSAndroid Build Coastguard Worker 	};
1473*59bfda1fSAndroid Build Coastguard Worker 	int fd, mode, ret;
1474*59bfda1fSAndroid Build Coastguard Worker 	struct fscrypt_get_policy_ex_arg arg;
1475*59bfda1fSAndroid Build Coastguard Worker 
1476*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1477*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1478*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1479*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1480*59bfda1fSAndroid Build Coastguard Worker 	}
1481*59bfda1fSAndroid Build Coastguard Worker 
1482*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_RDONLY, 0);
1483*59bfda1fSAndroid Build Coastguard Worker 	arg.policy_size = sizeof(arg.policy);
1484*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &arg);
1485*59bfda1fSAndroid Build Coastguard Worker 	if (ret != 0 && errno == ENOTTY)
1486*59bfda1fSAndroid Build Coastguard Worker 		ret = ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, arg.policy.v1);
1487*59bfda1fSAndroid Build Coastguard Worker 	close(fd);
1488*59bfda1fSAndroid Build Coastguard Worker 
1489*59bfda1fSAndroid Build Coastguard Worker 	if (ret) {
1490*59bfda1fSAndroid Build Coastguard Worker 		perror("FS_IOC_GET_ENCRYPTION_POLICY|_EX");
1491*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1492*59bfda1fSAndroid Build Coastguard Worker 	}
1493*59bfda1fSAndroid Build Coastguard Worker 
1494*59bfda1fSAndroid Build Coastguard Worker 	switch (arg.policy.version) {
1495*59bfda1fSAndroid Build Coastguard Worker 	case FSCRYPT_POLICY_V1:
1496*59bfda1fSAndroid Build Coastguard Worker 		mode = arg.policy.v1.filenames_encryption_mode;
1497*59bfda1fSAndroid Build Coastguard Worker 		break;
1498*59bfda1fSAndroid Build Coastguard Worker 	case FSCRYPT_POLICY_V2:
1499*59bfda1fSAndroid Build Coastguard Worker 		mode = arg.policy.v2.filenames_encryption_mode;
1500*59bfda1fSAndroid Build Coastguard Worker 		break;
1501*59bfda1fSAndroid Build Coastguard Worker 	default:
1502*59bfda1fSAndroid Build Coastguard Worker 		printf("Do not support policy version: %d\n",
1503*59bfda1fSAndroid Build Coastguard Worker 							arg.policy.version);
1504*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1505*59bfda1fSAndroid Build Coastguard Worker 	}
1506*59bfda1fSAndroid Build Coastguard Worker 
1507*59bfda1fSAndroid Build Coastguard Worker 	if (mode >= sizeof(enc_name)/sizeof(enc_name[0])) {
1508*59bfda1fSAndroid Build Coastguard Worker 		printf("Do not support algorithm: %d\n", mode);
1509*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1510*59bfda1fSAndroid Build Coastguard Worker 	}
1511*59bfda1fSAndroid Build Coastguard Worker 	printf ("%s\n", enc_name[mode]);
1512*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1513*59bfda1fSAndroid Build Coastguard Worker }
1514*59bfda1fSAndroid Build Coastguard Worker 
1515*59bfda1fSAndroid Build Coastguard Worker #define rename_desc "rename source to target file with fsync option"
1516*59bfda1fSAndroid Build Coastguard Worker #define rename_help							\
1517*59bfda1fSAndroid Build Coastguard Worker "f2fs_io rename [src_path] [target_path] [fsync_after_rename]\n\n"	\
1518*59bfda1fSAndroid Build Coastguard Worker "e.g., f2fs_io rename source dest 1\n"					\
1519*59bfda1fSAndroid Build Coastguard Worker "      1. open(source)\n"						\
1520*59bfda1fSAndroid Build Coastguard Worker "      2. rename(source, dest)\n"					\
1521*59bfda1fSAndroid Build Coastguard Worker "      3. fsync(source)\n"						\
1522*59bfda1fSAndroid Build Coastguard Worker "      4. close(source)\n"
1523*59bfda1fSAndroid Build Coastguard Worker 
do_rename(int argc,char ** argv,const struct cmd_desc * cmd)1524*59bfda1fSAndroid Build Coastguard Worker static void do_rename(int argc, char **argv, const struct cmd_desc *cmd)
1525*59bfda1fSAndroid Build Coastguard Worker {
1526*59bfda1fSAndroid Build Coastguard Worker 	int fd = -1;
1527*59bfda1fSAndroid Build Coastguard Worker 	int ret;
1528*59bfda1fSAndroid Build Coastguard Worker 
1529*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 4) {
1530*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1531*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1532*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1533*59bfda1fSAndroid Build Coastguard Worker 	}
1534*59bfda1fSAndroid Build Coastguard Worker 
1535*59bfda1fSAndroid Build Coastguard Worker 	if (atoi(argv[3]))
1536*59bfda1fSAndroid Build Coastguard Worker 		fd = xopen(argv[1], O_WRONLY, 0);
1537*59bfda1fSAndroid Build Coastguard Worker 
1538*59bfda1fSAndroid Build Coastguard Worker 	ret = rename(argv[1], argv[2]);
1539*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1540*59bfda1fSAndroid Build Coastguard Worker 		die_errno("rename failed");
1541*59bfda1fSAndroid Build Coastguard Worker 
1542*59bfda1fSAndroid Build Coastguard Worker 	if (fd >= 0) {
1543*59bfda1fSAndroid Build Coastguard Worker 		if (fsync(fd) != 0)
1544*59bfda1fSAndroid Build Coastguard Worker 			die_errno("fsync failed: %s", argv[1]);
1545*59bfda1fSAndroid Build Coastguard Worker 		close(fd);
1546*59bfda1fSAndroid Build Coastguard Worker 	}
1547*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1548*59bfda1fSAndroid Build Coastguard Worker }
1549*59bfda1fSAndroid Build Coastguard Worker 
1550*59bfda1fSAndroid Build Coastguard Worker #define gc_desc "trigger filesystem GC"
1551*59bfda1fSAndroid Build Coastguard Worker #define gc_help "f2fs_io gc sync_mode [file_path]\n\n"
1552*59bfda1fSAndroid Build Coastguard Worker 
do_gc(int argc,char ** argv,const struct cmd_desc * cmd)1553*59bfda1fSAndroid Build Coastguard Worker static void do_gc(int argc, char **argv, const struct cmd_desc *cmd)
1554*59bfda1fSAndroid Build Coastguard Worker {
1555*59bfda1fSAndroid Build Coastguard Worker 	u32 sync;
1556*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
1557*59bfda1fSAndroid Build Coastguard Worker 
1558*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 3) {
1559*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1560*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1561*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1562*59bfda1fSAndroid Build Coastguard Worker 	}
1563*59bfda1fSAndroid Build Coastguard Worker 
1564*59bfda1fSAndroid Build Coastguard Worker 	sync = atoi(argv[1]);
1565*59bfda1fSAndroid Build Coastguard Worker 
1566*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[2], O_RDONLY, 0);
1567*59bfda1fSAndroid Build Coastguard Worker 
1568*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_GARBAGE_COLLECT, &sync);
1569*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1570*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_GARBAGE_COLLECT failed");
1571*59bfda1fSAndroid Build Coastguard Worker 
1572*59bfda1fSAndroid Build Coastguard Worker 	printf("trigger %s gc ret=%d\n",
1573*59bfda1fSAndroid Build Coastguard Worker 		sync ? "synchronous" : "asynchronous", ret);
1574*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1575*59bfda1fSAndroid Build Coastguard Worker }
1576*59bfda1fSAndroid Build Coastguard Worker 
1577*59bfda1fSAndroid Build Coastguard Worker #define checkpoint_desc "trigger filesystem checkpoint"
1578*59bfda1fSAndroid Build Coastguard Worker #define checkpoint_help "f2fs_io checkpoint [file_path]\n\n"
1579*59bfda1fSAndroid Build Coastguard Worker 
do_checkpoint(int argc,char ** argv,const struct cmd_desc * cmd)1580*59bfda1fSAndroid Build Coastguard Worker static void do_checkpoint(int argc, char **argv, const struct cmd_desc *cmd)
1581*59bfda1fSAndroid Build Coastguard Worker {
1582*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
1583*59bfda1fSAndroid Build Coastguard Worker 
1584*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1585*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1586*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1587*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1588*59bfda1fSAndroid Build Coastguard Worker 	}
1589*59bfda1fSAndroid Build Coastguard Worker 
1590*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_WRONLY, 0);
1591*59bfda1fSAndroid Build Coastguard Worker 
1592*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_WRITE_CHECKPOINT);
1593*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1594*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_WRITE_CHECKPOINT failed");
1595*59bfda1fSAndroid Build Coastguard Worker 
1596*59bfda1fSAndroid Build Coastguard Worker 	printf("trigger filesystem checkpoint ret=%d\n", ret);
1597*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1598*59bfda1fSAndroid Build Coastguard Worker }
1599*59bfda1fSAndroid Build Coastguard Worker 
1600*59bfda1fSAndroid Build Coastguard Worker #define precache_extents_desc "trigger precache extents"
1601*59bfda1fSAndroid Build Coastguard Worker #define precache_extents_help "f2fs_io precache_extents [file_path]\n\n"
1602*59bfda1fSAndroid Build Coastguard Worker 
do_precache_extents(int argc,char ** argv,const struct cmd_desc * cmd)1603*59bfda1fSAndroid Build Coastguard Worker static void do_precache_extents(int argc, char **argv, const struct cmd_desc *cmd)
1604*59bfda1fSAndroid Build Coastguard Worker {
1605*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
1606*59bfda1fSAndroid Build Coastguard Worker 
1607*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1608*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1609*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1610*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1611*59bfda1fSAndroid Build Coastguard Worker 	}
1612*59bfda1fSAndroid Build Coastguard Worker 
1613*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_WRONLY, 0);
1614*59bfda1fSAndroid Build Coastguard Worker 
1615*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_PRECACHE_EXTENTS);
1616*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1617*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_PRECACHE_EXTENTS failed");
1618*59bfda1fSAndroid Build Coastguard Worker 
1619*59bfda1fSAndroid Build Coastguard Worker 	printf("trigger precache extents ret=%d\n", ret);
1620*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1621*59bfda1fSAndroid Build Coastguard Worker }
1622*59bfda1fSAndroid Build Coastguard Worker 
1623*59bfda1fSAndroid Build Coastguard Worker #define move_range_desc "moving a range of data blocks from source file to destination file"
1624*59bfda1fSAndroid Build Coastguard Worker #define move_range_help						\
1625*59bfda1fSAndroid Build Coastguard Worker "f2fs_io move_range [src_path] [dst_path] [src_start] [dst_start] "	\
1626*59bfda1fSAndroid Build Coastguard Worker "[length]\n\n"								\
1627*59bfda1fSAndroid Build Coastguard Worker "  src_path  : path to source file\n"					\
1628*59bfda1fSAndroid Build Coastguard Worker "  dst_path  : path to destination file\n"				\
1629*59bfda1fSAndroid Build Coastguard Worker "  src_start : start offset of src file move region, unit: bytes\n"	\
1630*59bfda1fSAndroid Build Coastguard Worker "  dst_start : start offset of dst file move region, unit: bytes\n"	\
1631*59bfda1fSAndroid Build Coastguard Worker "  length    : size to move\n"						\
1632*59bfda1fSAndroid Build Coastguard Worker 
do_move_range(int argc,char ** argv,const struct cmd_desc * cmd)1633*59bfda1fSAndroid Build Coastguard Worker static void do_move_range(int argc, char **argv, const struct cmd_desc *cmd)
1634*59bfda1fSAndroid Build Coastguard Worker {
1635*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_move_range range;
1636*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
1637*59bfda1fSAndroid Build Coastguard Worker 
1638*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 6) {
1639*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1640*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1641*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1642*59bfda1fSAndroid Build Coastguard Worker 	}
1643*59bfda1fSAndroid Build Coastguard Worker 
1644*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[1], O_RDWR, 0);
1645*59bfda1fSAndroid Build Coastguard Worker 	range.dst_fd = xopen(argv[2], O_RDWR | O_CREAT, 0644);
1646*59bfda1fSAndroid Build Coastguard Worker 	range.pos_in = atoll(argv[3]);
1647*59bfda1fSAndroid Build Coastguard Worker 	range.pos_out = atoll(argv[4]);
1648*59bfda1fSAndroid Build Coastguard Worker 	range.len = atoll(argv[5]);
1649*59bfda1fSAndroid Build Coastguard Worker 
1650*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_MOVE_RANGE, &range);
1651*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1652*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_MOVE_RANGE failed");
1653*59bfda1fSAndroid Build Coastguard Worker 
1654*59bfda1fSAndroid Build Coastguard Worker 	printf("move range ret=%d\n", ret);
1655*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1656*59bfda1fSAndroid Build Coastguard Worker }
1657*59bfda1fSAndroid Build Coastguard Worker 
1658*59bfda1fSAndroid Build Coastguard Worker #define gc_range_desc "trigger filesystem gc_range"
1659*59bfda1fSAndroid Build Coastguard Worker #define gc_range_help "f2fs_io gc_range [sync_mode] [start] [length] [file_path]\n\n"\
1660*59bfda1fSAndroid Build Coastguard Worker "  sync_mode : 0: asynchronous, 1: synchronous\n"			\
1661*59bfda1fSAndroid Build Coastguard Worker "  start     : start offset of defragment region, unit: 4kb\n"	\
1662*59bfda1fSAndroid Build Coastguard Worker "  length    : bytes number of defragment region, unit: 4kb\n"	\
1663*59bfda1fSAndroid Build Coastguard Worker 
do_gc_range(int argc,char ** argv,const struct cmd_desc * cmd)1664*59bfda1fSAndroid Build Coastguard Worker static void do_gc_range(int argc, char **argv, const struct cmd_desc *cmd)
1665*59bfda1fSAndroid Build Coastguard Worker {
1666*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_gc_range range;
1667*59bfda1fSAndroid Build Coastguard Worker 	int ret, fd;
1668*59bfda1fSAndroid Build Coastguard Worker 
1669*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 5) {
1670*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1671*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1672*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1673*59bfda1fSAndroid Build Coastguard Worker 	}
1674*59bfda1fSAndroid Build Coastguard Worker 
1675*59bfda1fSAndroid Build Coastguard Worker 	range.sync = atoi(argv[1]);
1676*59bfda1fSAndroid Build Coastguard Worker 	range.start = (u64)atoi(argv[2]);
1677*59bfda1fSAndroid Build Coastguard Worker 	range.len = (u64)atoi(argv[3]);
1678*59bfda1fSAndroid Build Coastguard Worker 
1679*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[4], O_RDWR, 0);
1680*59bfda1fSAndroid Build Coastguard Worker 
1681*59bfda1fSAndroid Build Coastguard Worker 	ret = ioctl(fd, F2FS_IOC_GARBAGE_COLLECT_RANGE, &range);
1682*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0) {
1683*59bfda1fSAndroid Build Coastguard Worker 		die_errno("F2FS_IOC_GARBAGE_COLLECT_RANGE failed");
1684*59bfda1fSAndroid Build Coastguard Worker 	}
1685*59bfda1fSAndroid Build Coastguard Worker 
1686*59bfda1fSAndroid Build Coastguard Worker 	printf("trigger %s gc_range [%"PRIu64", %"PRIu64"] ret=%d\n",
1687*59bfda1fSAndroid Build Coastguard Worker 		range.sync ? "synchronous" : "asynchronous",
1688*59bfda1fSAndroid Build Coastguard Worker 		range.start, range.len, ret);
1689*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1690*59bfda1fSAndroid Build Coastguard Worker }
1691*59bfda1fSAndroid Build Coastguard Worker 
1692*59bfda1fSAndroid Build Coastguard Worker #define listxattr_desc "listxattr"
1693*59bfda1fSAndroid Build Coastguard Worker #define listxattr_help "f2fs_io listxattr [file_path]\n\n"
1694*59bfda1fSAndroid Build Coastguard Worker 
do_listxattr(int argc,char ** argv,const struct cmd_desc * cmd)1695*59bfda1fSAndroid Build Coastguard Worker static void do_listxattr(int argc, char **argv, const struct cmd_desc *cmd)
1696*59bfda1fSAndroid Build Coastguard Worker {
1697*59bfda1fSAndroid Build Coastguard Worker 	char *buf, *key, *val;
1698*59bfda1fSAndroid Build Coastguard Worker 	ssize_t buflen, vallen, keylen;
1699*59bfda1fSAndroid Build Coastguard Worker 
1700*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1701*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1702*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1703*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1704*59bfda1fSAndroid Build Coastguard Worker 	}
1705*59bfda1fSAndroid Build Coastguard Worker 
1706*59bfda1fSAndroid Build Coastguard Worker 	buflen = listxattr(argv[1], NULL, 0);
1707*59bfda1fSAndroid Build Coastguard Worker 	if (buflen == -1) {
1708*59bfda1fSAndroid Build Coastguard Worker 		perror("listxattr");
1709*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1710*59bfda1fSAndroid Build Coastguard Worker 	}
1711*59bfda1fSAndroid Build Coastguard Worker 	if (buflen == 0) {
1712*59bfda1fSAndroid Build Coastguard Worker 		printf("%s has no attributes.\n", argv[1]);
1713*59bfda1fSAndroid Build Coastguard Worker 		exit(0);
1714*59bfda1fSAndroid Build Coastguard Worker 	}
1715*59bfda1fSAndroid Build Coastguard Worker 	buf = xmalloc(buflen);
1716*59bfda1fSAndroid Build Coastguard Worker 	buflen = listxattr(argv[1], buf, buflen);
1717*59bfda1fSAndroid Build Coastguard Worker 	if (buflen == -1) {
1718*59bfda1fSAndroid Build Coastguard Worker 		perror("listxattr");
1719*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1720*59bfda1fSAndroid Build Coastguard Worker 	}
1721*59bfda1fSAndroid Build Coastguard Worker 
1722*59bfda1fSAndroid Build Coastguard Worker 	key = buf;
1723*59bfda1fSAndroid Build Coastguard Worker 	while (buflen > 0) {
1724*59bfda1fSAndroid Build Coastguard Worker 		printf("%s: ", key);
1725*59bfda1fSAndroid Build Coastguard Worker 		vallen = getxattr(argv[1], key, NULL, 0);
1726*59bfda1fSAndroid Build Coastguard Worker 		if (vallen == -1) {
1727*59bfda1fSAndroid Build Coastguard Worker 			perror("getxattr");
1728*59bfda1fSAndroid Build Coastguard Worker 			exit(1);
1729*59bfda1fSAndroid Build Coastguard Worker 		}
1730*59bfda1fSAndroid Build Coastguard Worker 		if (vallen == 0) {
1731*59bfda1fSAndroid Build Coastguard Worker 			printf("<no value>");
1732*59bfda1fSAndroid Build Coastguard Worker 		} else {
1733*59bfda1fSAndroid Build Coastguard Worker 			val = xmalloc(vallen + 1);
1734*59bfda1fSAndroid Build Coastguard Worker 			vallen = getxattr(argv[1], key, val, vallen);
1735*59bfda1fSAndroid Build Coastguard Worker 			if (vallen == -1) {
1736*59bfda1fSAndroid Build Coastguard Worker 				perror("getxattr");
1737*59bfda1fSAndroid Build Coastguard Worker 				exit(1);
1738*59bfda1fSAndroid Build Coastguard Worker 			}
1739*59bfda1fSAndroid Build Coastguard Worker 			val[vallen] = 0;
1740*59bfda1fSAndroid Build Coastguard Worker 			printf("%s", val);
1741*59bfda1fSAndroid Build Coastguard Worker 			free(val);
1742*59bfda1fSAndroid Build Coastguard Worker 		}
1743*59bfda1fSAndroid Build Coastguard Worker 		printf("\n");
1744*59bfda1fSAndroid Build Coastguard Worker 		keylen = strlen(key) + 1;
1745*59bfda1fSAndroid Build Coastguard Worker 		buflen -= keylen;
1746*59bfda1fSAndroid Build Coastguard Worker 		key += keylen;
1747*59bfda1fSAndroid Build Coastguard Worker 	}
1748*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1749*59bfda1fSAndroid Build Coastguard Worker }
1750*59bfda1fSAndroid Build Coastguard Worker 
1751*59bfda1fSAndroid Build Coastguard Worker #define setxattr_desc "setxattr"
1752*59bfda1fSAndroid Build Coastguard Worker #define setxattr_help "f2fs_io setxattr [name] [value] [file_path]\n\n"
1753*59bfda1fSAndroid Build Coastguard Worker 
do_setxattr(int argc,char ** argv,const struct cmd_desc * cmd)1754*59bfda1fSAndroid Build Coastguard Worker static void do_setxattr(int argc, char **argv, const struct cmd_desc *cmd)
1755*59bfda1fSAndroid Build Coastguard Worker {
1756*59bfda1fSAndroid Build Coastguard Worker 	int ret;
1757*59bfda1fSAndroid Build Coastguard Worker 	char *value;
1758*59bfda1fSAndroid Build Coastguard Worker 	unsigned char tmp;
1759*59bfda1fSAndroid Build Coastguard Worker 
1760*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 4) {
1761*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1762*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1763*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1764*59bfda1fSAndroid Build Coastguard Worker 	}
1765*59bfda1fSAndroid Build Coastguard Worker 
1766*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[1], F2FS_SYSTEM_ADVISE_NAME)) {
1767*59bfda1fSAndroid Build Coastguard Worker 		tmp = strtoul(argv[2], NULL, 0);
1768*59bfda1fSAndroid Build Coastguard Worker 		value = (char *)&tmp;
1769*59bfda1fSAndroid Build Coastguard Worker 	} else {
1770*59bfda1fSAndroid Build Coastguard Worker 		value = argv[2];
1771*59bfda1fSAndroid Build Coastguard Worker 	}
1772*59bfda1fSAndroid Build Coastguard Worker 
1773*59bfda1fSAndroid Build Coastguard Worker 	ret = setxattr(argv[3], argv[1], value, strlen(argv[2]), XATTR_CREATE);
1774*59bfda1fSAndroid Build Coastguard Worker 	printf("setxattr %s CREATE: name: %s, value: %s: ret=%d\n",
1775*59bfda1fSAndroid Build Coastguard Worker 			argv[3], argv[1], argv[2], ret);
1776*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0 && errno == EEXIST) {
1777*59bfda1fSAndroid Build Coastguard Worker 		ret = setxattr(argv[3], argv[1], value, strlen(argv[2]), XATTR_REPLACE);
1778*59bfda1fSAndroid Build Coastguard Worker 		printf("setxattr %s REPLACE: name: %s, value: %s: ret=%d\n",
1779*59bfda1fSAndroid Build Coastguard Worker 				argv[3], argv[1], argv[2], ret);
1780*59bfda1fSAndroid Build Coastguard Worker 	}
1781*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1782*59bfda1fSAndroid Build Coastguard Worker 		perror("setxattr");
1783*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1784*59bfda1fSAndroid Build Coastguard Worker }
1785*59bfda1fSAndroid Build Coastguard Worker 
1786*59bfda1fSAndroid Build Coastguard Worker #define removexattr_desc "removexattr"
1787*59bfda1fSAndroid Build Coastguard Worker #define removexattr_help "f2fs_io removexattr [name] [file_path]\n\n"
1788*59bfda1fSAndroid Build Coastguard Worker 
do_removexattr(int argc,char ** argv,const struct cmd_desc * cmd)1789*59bfda1fSAndroid Build Coastguard Worker static void do_removexattr(int argc, char **argv, const struct cmd_desc *cmd)
1790*59bfda1fSAndroid Build Coastguard Worker {
1791*59bfda1fSAndroid Build Coastguard Worker 	int ret;
1792*59bfda1fSAndroid Build Coastguard Worker 
1793*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 3) {
1794*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1795*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1796*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1797*59bfda1fSAndroid Build Coastguard Worker 	}
1798*59bfda1fSAndroid Build Coastguard Worker 
1799*59bfda1fSAndroid Build Coastguard Worker 	ret = removexattr(argv[2], argv[1]);
1800*59bfda1fSAndroid Build Coastguard Worker 	printf("removexattr %s REMOVE: name: %s: ret=%d\n", argv[1], argv[2], ret);
1801*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1802*59bfda1fSAndroid Build Coastguard Worker }
1803*59bfda1fSAndroid Build Coastguard Worker 
1804*59bfda1fSAndroid Build Coastguard Worker #define lseek_desc "do lseek for a file"
1805*59bfda1fSAndroid Build Coastguard Worker #define lseek_help					\
1806*59bfda1fSAndroid Build Coastguard Worker "f2fs_io lseek [whence] [offset] [file_path]\n\n"	\
1807*59bfda1fSAndroid Build Coastguard Worker "Do lseek file data in file_path and return the adjusted file offset\n"	\
1808*59bfda1fSAndroid Build Coastguard Worker "whence can be\n"					\
1809*59bfda1fSAndroid Build Coastguard Worker "  set  : SEEK_SET, The file offset is set to offset bytes\n"	\
1810*59bfda1fSAndroid Build Coastguard Worker "  cur  : SEEK_CUR, The file offset is set to its current location plus offset bytes\n"	\
1811*59bfda1fSAndroid Build Coastguard Worker "  end  : SEEK_END, The file offset is set to the size of the file plus offset bytes\n"	\
1812*59bfda1fSAndroid Build Coastguard Worker "  data : SEEK_DATA, set the file offset to the next data location from offset\n"	\
1813*59bfda1fSAndroid Build Coastguard Worker "  hole : SEEK_HOLE, set the file offset to the next hole from offset\n"
1814*59bfda1fSAndroid Build Coastguard Worker 
do_lseek(int argc,char ** argv,const struct cmd_desc * cmd)1815*59bfda1fSAndroid Build Coastguard Worker static void do_lseek(int argc, char **argv, const struct cmd_desc *cmd)
1816*59bfda1fSAndroid Build Coastguard Worker {
1817*59bfda1fSAndroid Build Coastguard Worker 	int fd, whence;
1818*59bfda1fSAndroid Build Coastguard Worker 	off_t offset, ret;
1819*59bfda1fSAndroid Build Coastguard Worker 
1820*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 4) {
1821*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1822*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1823*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1824*59bfda1fSAndroid Build Coastguard Worker 	}
1825*59bfda1fSAndroid Build Coastguard Worker 
1826*59bfda1fSAndroid Build Coastguard Worker 	offset = atoll(argv[2]);
1827*59bfda1fSAndroid Build Coastguard Worker 
1828*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(argv[1], "set"))
1829*59bfda1fSAndroid Build Coastguard Worker 		whence = SEEK_SET;
1830*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "cur"))
1831*59bfda1fSAndroid Build Coastguard Worker 		whence = SEEK_CUR;
1832*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "end"))
1833*59bfda1fSAndroid Build Coastguard Worker 		whence = SEEK_END;
1834*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "data"))
1835*59bfda1fSAndroid Build Coastguard Worker 		whence = SEEK_DATA;
1836*59bfda1fSAndroid Build Coastguard Worker 	else if (!strcmp(argv[1], "hole"))
1837*59bfda1fSAndroid Build Coastguard Worker 		whence = SEEK_HOLE;
1838*59bfda1fSAndroid Build Coastguard Worker 	else
1839*59bfda1fSAndroid Build Coastguard Worker 		die("Wrong whence type");
1840*59bfda1fSAndroid Build Coastguard Worker 
1841*59bfda1fSAndroid Build Coastguard Worker 	fd = xopen(argv[3], O_RDONLY, 0);
1842*59bfda1fSAndroid Build Coastguard Worker 
1843*59bfda1fSAndroid Build Coastguard Worker 	ret = lseek(fd, offset, whence);
1844*59bfda1fSAndroid Build Coastguard Worker 	if (ret < 0)
1845*59bfda1fSAndroid Build Coastguard Worker 		die_errno("lseek failed");
1846*59bfda1fSAndroid Build Coastguard Worker 	printf("returned offset=%lld\n", (long long)ret);
1847*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1848*59bfda1fSAndroid Build Coastguard Worker }
1849*59bfda1fSAndroid Build Coastguard Worker 
1850*59bfda1fSAndroid Build Coastguard Worker #define get_advise_desc "get_advise"
1851*59bfda1fSAndroid Build Coastguard Worker #define get_advise_help "f2fs_io get_advise [file_path]\n\n"
1852*59bfda1fSAndroid Build Coastguard Worker 
do_get_advise(int argc,char ** argv,const struct cmd_desc * cmd)1853*59bfda1fSAndroid Build Coastguard Worker static void do_get_advise(int argc, char **argv, const struct cmd_desc *cmd)
1854*59bfda1fSAndroid Build Coastguard Worker {
1855*59bfda1fSAndroid Build Coastguard Worker 	int ret;
1856*59bfda1fSAndroid Build Coastguard Worker 	unsigned char value;
1857*59bfda1fSAndroid Build Coastguard Worker 
1858*59bfda1fSAndroid Build Coastguard Worker 	if (argc != 2) {
1859*59bfda1fSAndroid Build Coastguard Worker 		fputs("Excess arguments\n\n", stderr);
1860*59bfda1fSAndroid Build Coastguard Worker 		fputs(cmd->cmd_help, stderr);
1861*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1862*59bfda1fSAndroid Build Coastguard Worker 	}
1863*59bfda1fSAndroid Build Coastguard Worker 
1864*59bfda1fSAndroid Build Coastguard Worker 	ret = getxattr(argv[1], F2FS_SYSTEM_ADVISE_NAME, &value, sizeof(value));
1865*59bfda1fSAndroid Build Coastguard Worker 	if (ret != sizeof(value)) {
1866*59bfda1fSAndroid Build Coastguard Worker 		perror("getxattr");
1867*59bfda1fSAndroid Build Coastguard Worker 		exit(1);
1868*59bfda1fSAndroid Build Coastguard Worker 	}
1869*59bfda1fSAndroid Build Coastguard Worker 
1870*59bfda1fSAndroid Build Coastguard Worker 	printf("i_advise=0x%x, advise_type: ", value);
1871*59bfda1fSAndroid Build Coastguard Worker 	if (value & FADVISE_COLD_BIT)
1872*59bfda1fSAndroid Build Coastguard Worker 		printf("cold ");
1873*59bfda1fSAndroid Build Coastguard Worker 	if (value & FADVISE_LOST_PINO_BIT)
1874*59bfda1fSAndroid Build Coastguard Worker 		printf("lost_pino ");
1875*59bfda1fSAndroid Build Coastguard Worker 	if (value & FADVISE_ENCRYPT_BIT)
1876*59bfda1fSAndroid Build Coastguard Worker 		printf("encrypt ");
1877*59bfda1fSAndroid Build Coastguard Worker 	if (value & FADVISE_ENC_NAME_BIT)
1878*59bfda1fSAndroid Build Coastguard Worker 		printf("enc_name ");
1879*59bfda1fSAndroid Build Coastguard Worker 	if (value & FADVISE_KEEP_SIZE_BIT)
1880*59bfda1fSAndroid Build Coastguard Worker 		printf("keep_size ");
1881*59bfda1fSAndroid Build Coastguard Worker 	if (value & FADVISE_HOT_BIT)
1882*59bfda1fSAndroid Build Coastguard Worker 		printf("hot ");
1883*59bfda1fSAndroid Build Coastguard Worker 	if (value & FADVISE_VERITY_BIT)
1884*59bfda1fSAndroid Build Coastguard Worker 		printf("verity ");
1885*59bfda1fSAndroid Build Coastguard Worker 	if (value & FADVISE_TRUNC_BIT)
1886*59bfda1fSAndroid Build Coastguard Worker 		printf("trunc ");
1887*59bfda1fSAndroid Build Coastguard Worker 	printf("\n");
1888*59bfda1fSAndroid Build Coastguard Worker }
1889*59bfda1fSAndroid Build Coastguard Worker 
1890*59bfda1fSAndroid Build Coastguard Worker #define CMD_HIDDEN 	0x0001
1891*59bfda1fSAndroid Build Coastguard Worker #define CMD(name) { #name, do_##name, name##_desc, name##_help, 0 }
1892*59bfda1fSAndroid Build Coastguard Worker #define _CMD(name) { #name, do_##name, NULL, NULL, CMD_HIDDEN }
1893*59bfda1fSAndroid Build Coastguard Worker 
1894*59bfda1fSAndroid Build Coastguard Worker static void do_help(int argc, char **argv, const struct cmd_desc *cmd);
1895*59bfda1fSAndroid Build Coastguard Worker const struct cmd_desc cmd_list[] = {
1896*59bfda1fSAndroid Build Coastguard Worker 	_CMD(help),
1897*59bfda1fSAndroid Build Coastguard Worker 	CMD(fsync),
1898*59bfda1fSAndroid Build Coastguard Worker 	CMD(fdatasync),
1899*59bfda1fSAndroid Build Coastguard Worker 	CMD(set_verity),
1900*59bfda1fSAndroid Build Coastguard Worker 	CMD(getflags),
1901*59bfda1fSAndroid Build Coastguard Worker 	CMD(setflags),
1902*59bfda1fSAndroid Build Coastguard Worker 	CMD(clearflags),
1903*59bfda1fSAndroid Build Coastguard Worker 	CMD(shutdown),
1904*59bfda1fSAndroid Build Coastguard Worker 	CMD(pinfile),
1905*59bfda1fSAndroid Build Coastguard Worker 	CMD(fadvise),
1906*59bfda1fSAndroid Build Coastguard Worker 	CMD(fallocate),
1907*59bfda1fSAndroid Build Coastguard Worker 	CMD(erase),
1908*59bfda1fSAndroid Build Coastguard Worker 	CMD(write),
1909*59bfda1fSAndroid Build Coastguard Worker 	CMD(write_advice),
1910*59bfda1fSAndroid Build Coastguard Worker 	CMD(read),
1911*59bfda1fSAndroid Build Coastguard Worker 	CMD(randread),
1912*59bfda1fSAndroid Build Coastguard Worker 	CMD(fiemap),
1913*59bfda1fSAndroid Build Coastguard Worker 	CMD(gc_urgent),
1914*59bfda1fSAndroid Build Coastguard Worker 	CMD(defrag_file),
1915*59bfda1fSAndroid Build Coastguard Worker 	CMD(copy),
1916*59bfda1fSAndroid Build Coastguard Worker 	CMD(get_cblocks),
1917*59bfda1fSAndroid Build Coastguard Worker 	CMD(release_cblocks),
1918*59bfda1fSAndroid Build Coastguard Worker 	CMD(reserve_cblocks),
1919*59bfda1fSAndroid Build Coastguard Worker 	CMD(get_coption),
1920*59bfda1fSAndroid Build Coastguard Worker 	CMD(set_coption),
1921*59bfda1fSAndroid Build Coastguard Worker 	CMD(decompress),
1922*59bfda1fSAndroid Build Coastguard Worker 	CMD(compress),
1923*59bfda1fSAndroid Build Coastguard Worker 	CMD(get_filename_encrypt_mode),
1924*59bfda1fSAndroid Build Coastguard Worker 	CMD(rename),
1925*59bfda1fSAndroid Build Coastguard Worker 	CMD(gc),
1926*59bfda1fSAndroid Build Coastguard Worker 	CMD(checkpoint),
1927*59bfda1fSAndroid Build Coastguard Worker 	CMD(precache_extents),
1928*59bfda1fSAndroid Build Coastguard Worker 	CMD(move_range),
1929*59bfda1fSAndroid Build Coastguard Worker 	CMD(gc_range),
1930*59bfda1fSAndroid Build Coastguard Worker 	CMD(listxattr),
1931*59bfda1fSAndroid Build Coastguard Worker 	CMD(setxattr),
1932*59bfda1fSAndroid Build Coastguard Worker 	CMD(removexattr),
1933*59bfda1fSAndroid Build Coastguard Worker 	CMD(lseek),
1934*59bfda1fSAndroid Build Coastguard Worker 	CMD(get_advise),
1935*59bfda1fSAndroid Build Coastguard Worker 	{ NULL, NULL, NULL, NULL, 0 }
1936*59bfda1fSAndroid Build Coastguard Worker };
1937*59bfda1fSAndroid Build Coastguard Worker 
do_help(int argc,char ** argv,const struct cmd_desc * UNUSED (cmd))1938*59bfda1fSAndroid Build Coastguard Worker static void do_help(int argc, char **argv, const struct cmd_desc *UNUSED(cmd))
1939*59bfda1fSAndroid Build Coastguard Worker {
1940*59bfda1fSAndroid Build Coastguard Worker 	const struct cmd_desc *p;
1941*59bfda1fSAndroid Build Coastguard Worker 
1942*59bfda1fSAndroid Build Coastguard Worker 	if (argc > 1) {
1943*59bfda1fSAndroid Build Coastguard Worker 		for (p = cmd_list; p->cmd_name; p++) {
1944*59bfda1fSAndroid Build Coastguard Worker 			if (p->cmd_flags & CMD_HIDDEN)
1945*59bfda1fSAndroid Build Coastguard Worker 				continue;
1946*59bfda1fSAndroid Build Coastguard Worker 			if (strcmp(p->cmd_name, argv[1]) == 0) {
1947*59bfda1fSAndroid Build Coastguard Worker 				putc('\n', stdout);
1948*59bfda1fSAndroid Build Coastguard Worker 				fputs("USAGE:\n  ", stdout);
1949*59bfda1fSAndroid Build Coastguard Worker 				fputs(p->cmd_help, stdout);
1950*59bfda1fSAndroid Build Coastguard Worker 				exit(0);
1951*59bfda1fSAndroid Build Coastguard Worker 			}
1952*59bfda1fSAndroid Build Coastguard Worker 		}
1953*59bfda1fSAndroid Build Coastguard Worker 		printf("Unknown command: %s\n\n", argv[1]);
1954*59bfda1fSAndroid Build Coastguard Worker 	}
1955*59bfda1fSAndroid Build Coastguard Worker 
1956*59bfda1fSAndroid Build Coastguard Worker 	fputs("Available commands:\n", stdout);
1957*59bfda1fSAndroid Build Coastguard Worker 	for (p = cmd_list; p->cmd_name; p++) {
1958*59bfda1fSAndroid Build Coastguard Worker 		if (p->cmd_flags & CMD_HIDDEN)
1959*59bfda1fSAndroid Build Coastguard Worker 			continue;
1960*59bfda1fSAndroid Build Coastguard Worker 		printf("  %-20s %s\n", p->cmd_name, p->cmd_desc);
1961*59bfda1fSAndroid Build Coastguard Worker 	}
1962*59bfda1fSAndroid Build Coastguard Worker 	printf("\nTo get more information on a command, "
1963*59bfda1fSAndroid Build Coastguard Worker 	       "type 'f2fs_io help cmd'\n");
1964*59bfda1fSAndroid Build Coastguard Worker 	exit(0);
1965*59bfda1fSAndroid Build Coastguard Worker }
1966*59bfda1fSAndroid Build Coastguard Worker 
die_signal_handler(int UNUSED (signum),siginfo_t * UNUSED (siginfo),void * UNUSED (context))1967*59bfda1fSAndroid Build Coastguard Worker static void die_signal_handler(int UNUSED(signum), siginfo_t *UNUSED(siginfo),
1968*59bfda1fSAndroid Build Coastguard Worker 				void *UNUSED(context))
1969*59bfda1fSAndroid Build Coastguard Worker {
1970*59bfda1fSAndroid Build Coastguard Worker 	exit(-1);
1971*59bfda1fSAndroid Build Coastguard Worker }
1972*59bfda1fSAndroid Build Coastguard Worker 
sigcatcher_setup(void)1973*59bfda1fSAndroid Build Coastguard Worker static void sigcatcher_setup(void)
1974*59bfda1fSAndroid Build Coastguard Worker {
1975*59bfda1fSAndroid Build Coastguard Worker 	struct sigaction	sa;
1976*59bfda1fSAndroid Build Coastguard Worker 
1977*59bfda1fSAndroid Build Coastguard Worker 	memset(&sa, 0, sizeof(struct sigaction));
1978*59bfda1fSAndroid Build Coastguard Worker 	sa.sa_sigaction = die_signal_handler;
1979*59bfda1fSAndroid Build Coastguard Worker 	sa.sa_flags = SA_SIGINFO;
1980*59bfda1fSAndroid Build Coastguard Worker 
1981*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGHUP, &sa, 0);
1982*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGINT, &sa, 0);
1983*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGQUIT, &sa, 0);
1984*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGFPE, &sa, 0);
1985*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGILL, &sa, 0);
1986*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGBUS, &sa, 0);
1987*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGSEGV, &sa, 0);
1988*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGABRT, &sa, 0);
1989*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGPIPE, &sa, 0);
1990*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGALRM, &sa, 0);
1991*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGTERM, &sa, 0);
1992*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGUSR1, &sa, 0);
1993*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGUSR2, &sa, 0);
1994*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGPOLL, &sa, 0);
1995*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGPROF, &sa, 0);
1996*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGSYS, &sa, 0);
1997*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGTRAP, &sa, 0);
1998*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGVTALRM, &sa, 0);
1999*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGXCPU, &sa, 0);
2000*59bfda1fSAndroid Build Coastguard Worker 	sigaction(SIGXFSZ, &sa, 0);
2001*59bfda1fSAndroid Build Coastguard Worker }
2002*59bfda1fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)2003*59bfda1fSAndroid Build Coastguard Worker int main(int argc, char **argv)
2004*59bfda1fSAndroid Build Coastguard Worker {
2005*59bfda1fSAndroid Build Coastguard Worker 	const struct cmd_desc *cmd;
2006*59bfda1fSAndroid Build Coastguard Worker 
2007*59bfda1fSAndroid Build Coastguard Worker 	if (argc < 2)
2008*59bfda1fSAndroid Build Coastguard Worker 		do_help(argc, argv, cmd_list);
2009*59bfda1fSAndroid Build Coastguard Worker 
2010*59bfda1fSAndroid Build Coastguard Worker 	sigcatcher_setup();
2011*59bfda1fSAndroid Build Coastguard Worker 	for (cmd = cmd_list; cmd->cmd_name; cmd++) {
2012*59bfda1fSAndroid Build Coastguard Worker 		if (strcmp(cmd->cmd_name, argv[1]) == 0) {
2013*59bfda1fSAndroid Build Coastguard Worker 			cmd->cmd_func(argc - 1, argv + 1, cmd);
2014*59bfda1fSAndroid Build Coastguard Worker 			exit(0);
2015*59bfda1fSAndroid Build Coastguard Worker 		}
2016*59bfda1fSAndroid Build Coastguard Worker 	}
2017*59bfda1fSAndroid Build Coastguard Worker 	printf("Unknown command: %s\n\n", argv[1]);
2018*59bfda1fSAndroid Build Coastguard Worker 	do_help(1, argv, cmd_list);
2019*59bfda1fSAndroid Build Coastguard Worker 	return 0;
2020*59bfda1fSAndroid Build Coastguard Worker }
2021