1*59bfda1fSAndroid Build Coastguard Worker #include <stdio.h>
2*59bfda1fSAndroid Build Coastguard Worker #include <sys/mman.h>
3*59bfda1fSAndroid Build Coastguard Worker #include <sys/ioctl.h>
4*59bfda1fSAndroid Build Coastguard Worker #include <sys/socket.h>
5*59bfda1fSAndroid Build Coastguard Worker #include <sys/stat.h>
6*59bfda1fSAndroid Build Coastguard Worker #include <sys/types.h>
7*59bfda1fSAndroid Build Coastguard Worker #include <sys/time.h>
8*59bfda1fSAndroid Build Coastguard Worker #include <unistd.h>
9*59bfda1fSAndroid Build Coastguard Worker #include <sys/wait.h>
10*59bfda1fSAndroid Build Coastguard Worker #include <sys/syscall.h>
11*59bfda1fSAndroid Build Coastguard Worker #include <errno.h>
12*59bfda1fSAndroid Build Coastguard Worker #include <fcntl.h>
13*59bfda1fSAndroid Build Coastguard Worker #include <getopt.h>
14*59bfda1fSAndroid Build Coastguard Worker #include <string.h>
15*59bfda1fSAndroid Build Coastguard Worker #include <stdlib.h>
16*59bfda1fSAndroid Build Coastguard Worker
17*59bfda1fSAndroid Build Coastguard Worker #define F2FS_IOCTL_MAGIC 0xf5
18*59bfda1fSAndroid Build Coastguard Worker #define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1)
19*59bfda1fSAndroid Build Coastguard Worker #define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2)
20*59bfda1fSAndroid Build Coastguard Worker #define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3)
21*59bfda1fSAndroid Build Coastguard Worker #define F2FS_IOC_RELEASE_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 4)
22*59bfda1fSAndroid Build Coastguard Worker #define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5)
23*59bfda1fSAndroid Build Coastguard Worker #define F2FS_IOC_GARBAGE_COLLECT _IO(F2FS_IOCTL_MAGIC, 6)
24*59bfda1fSAndroid Build Coastguard Worker
25*59bfda1fSAndroid Build Coastguard Worker #define DB1_PATH "/data/database_file1"
26*59bfda1fSAndroid Build Coastguard Worker #define DB2_PATH "/mnt/androidwritable/0/emulated/0/Android/data/database_file2"
27*59bfda1fSAndroid Build Coastguard Worker #define FILE_PATH "/data/testfile"
28*59bfda1fSAndroid Build Coastguard Worker
29*59bfda1fSAndroid Build Coastguard Worker #define F2FS_BLKSIZE 4096
30*59bfda1fSAndroid Build Coastguard Worker #define BLKS_TO_SECTOR_BITS 3
31*59bfda1fSAndroid Build Coastguard Worker #define BLOCK 4096
32*59bfda1fSAndroid Build Coastguard Worker #define BLOCKS (2 * BLOCK)
33*59bfda1fSAndroid Build Coastguard Worker
34*59bfda1fSAndroid Build Coastguard Worker char buf[BLOCKS];
35*59bfda1fSAndroid Build Coastguard Worker char cmd[BLOCK];
36*59bfda1fSAndroid Build Coastguard Worker
run(const char * cmd)37*59bfda1fSAndroid Build Coastguard Worker static int run(const char *cmd)
38*59bfda1fSAndroid Build Coastguard Worker {
39*59bfda1fSAndroid Build Coastguard Worker int status;
40*59bfda1fSAndroid Build Coastguard Worker
41*59bfda1fSAndroid Build Coastguard Worker fflush(stdout);
42*59bfda1fSAndroid Build Coastguard Worker
43*59bfda1fSAndroid Build Coastguard Worker switch (fork()) {
44*59bfda1fSAndroid Build Coastguard Worker case 0:
45*59bfda1fSAndroid Build Coastguard Worker /* redirect stderr to stdout */
46*59bfda1fSAndroid Build Coastguard Worker dup2(1, 2);
47*59bfda1fSAndroid Build Coastguard Worker execl("/system/bin/sh", "sh", "-c", cmd, (char *) NULL);
48*59bfda1fSAndroid Build Coastguard Worker case -1:
49*59bfda1fSAndroid Build Coastguard Worker printf("fork failed in run() errno:%d\n", errno);
50*59bfda1fSAndroid Build Coastguard Worker return -1;
51*59bfda1fSAndroid Build Coastguard Worker default:
52*59bfda1fSAndroid Build Coastguard Worker wait(&status);
53*59bfda1fSAndroid Build Coastguard Worker }
54*59bfda1fSAndroid Build Coastguard Worker return 0;
55*59bfda1fSAndroid Build Coastguard Worker }
56*59bfda1fSAndroid Build Coastguard Worker
test_atomic_write(char * path)57*59bfda1fSAndroid Build Coastguard Worker static int test_atomic_write(char *path)
58*59bfda1fSAndroid Build Coastguard Worker {
59*59bfda1fSAndroid Build Coastguard Worker int db, ret, written;
60*59bfda1fSAndroid Build Coastguard Worker
61*59bfda1fSAndroid Build Coastguard Worker printf("\tOpen %s... \n", path);
62*59bfda1fSAndroid Build Coastguard Worker db = open(path, O_RDWR|O_CREAT, 0666);
63*59bfda1fSAndroid Build Coastguard Worker if (db < 0) {
64*59bfda1fSAndroid Build Coastguard Worker printf("open failed errno:%d\n", errno);
65*59bfda1fSAndroid Build Coastguard Worker return -1;
66*59bfda1fSAndroid Build Coastguard Worker }
67*59bfda1fSAndroid Build Coastguard Worker printf("\tStart ... \n");
68*59bfda1fSAndroid Build Coastguard Worker ret = ioctl(db, F2FS_IOC_START_ATOMIC_WRITE);
69*59bfda1fSAndroid Build Coastguard Worker if (ret) {
70*59bfda1fSAndroid Build Coastguard Worker printf("ioctl failed errno:%d\n", errno);
71*59bfda1fSAndroid Build Coastguard Worker return -1;
72*59bfda1fSAndroid Build Coastguard Worker }
73*59bfda1fSAndroid Build Coastguard Worker printf("\tWrite to the %dkB ... \n", BLOCKS / 1024);
74*59bfda1fSAndroid Build Coastguard Worker written = write(db, buf, BLOCKS);
75*59bfda1fSAndroid Build Coastguard Worker if (written != BLOCKS) {
76*59bfda1fSAndroid Build Coastguard Worker printf("write fail written:%d, errno:%d\n", written, errno);
77*59bfda1fSAndroid Build Coastguard Worker return -1;
78*59bfda1fSAndroid Build Coastguard Worker }
79*59bfda1fSAndroid Build Coastguard Worker printf("\tCheck : Atomic in-memory count: 2\n");
80*59bfda1fSAndroid Build Coastguard Worker if (access("/dev/sys/fs/by-name/userdata/current_atomic_write", F_OK)
81*59bfda1fSAndroid Build Coastguard Worker == 0) {
82*59bfda1fSAndroid Build Coastguard Worker printf("- inmem: ");
83*59bfda1fSAndroid Build Coastguard Worker run("cat /dev/sys/fs/by-name/userdata/current_atomic_write");
84*59bfda1fSAndroid Build Coastguard Worker } else {
85*59bfda1fSAndroid Build Coastguard Worker run("grep \"atomic IO\" /sys/kernel/debug/f2fs/status");
86*59bfda1fSAndroid Build Coastguard Worker }
87*59bfda1fSAndroid Build Coastguard Worker
88*59bfda1fSAndroid Build Coastguard Worker printf("\tCommit ... \n");
89*59bfda1fSAndroid Build Coastguard Worker ret = ioctl(db, F2FS_IOC_COMMIT_ATOMIC_WRITE);
90*59bfda1fSAndroid Build Coastguard Worker if (ret) {
91*59bfda1fSAndroid Build Coastguard Worker printf("ioctl failed errno:%d\n", errno);
92*59bfda1fSAndroid Build Coastguard Worker return -1;
93*59bfda1fSAndroid Build Coastguard Worker }
94*59bfda1fSAndroid Build Coastguard Worker return 0;
95*59bfda1fSAndroid Build Coastguard Worker }
96*59bfda1fSAndroid Build Coastguard Worker
test_bad_write_call(char * path)97*59bfda1fSAndroid Build Coastguard Worker static int test_bad_write_call(char *path)
98*59bfda1fSAndroid Build Coastguard Worker {
99*59bfda1fSAndroid Build Coastguard Worker int fd, written;
100*59bfda1fSAndroid Build Coastguard Worker struct stat sb;
101*59bfda1fSAndroid Build Coastguard Worker int large_size = 1024 * 1024 * 100; /* 100 MB */
102*59bfda1fSAndroid Build Coastguard Worker int blocks;
103*59bfda1fSAndroid Build Coastguard Worker
104*59bfda1fSAndroid Build Coastguard Worker printf("\tOpen %s... \n", path);
105*59bfda1fSAndroid Build Coastguard Worker fd = open(path, O_RDWR|O_CREAT|O_TRUNC, 0666);
106*59bfda1fSAndroid Build Coastguard Worker if (fd < 0) {
107*59bfda1fSAndroid Build Coastguard Worker printf("open failed errno:%d\n", errno);
108*59bfda1fSAndroid Build Coastguard Worker return -1;
109*59bfda1fSAndroid Build Coastguard Worker }
110*59bfda1fSAndroid Build Coastguard Worker
111*59bfda1fSAndroid Build Coastguard Worker /* 8KB-sized buffer, but submit 100 MB size */
112*59bfda1fSAndroid Build Coastguard Worker printf("\tWrite to the %dkB ... \n", BLOCKS / 1024);
113*59bfda1fSAndroid Build Coastguard Worker written = write(fd, buf, large_size);
114*59bfda1fSAndroid Build Coastguard Worker if (written != BLOCKS)
115*59bfda1fSAndroid Build Coastguard Worker printf("Ok: write fail written:%d, errno:%d\n", written, errno);
116*59bfda1fSAndroid Build Coastguard Worker close(fd);
117*59bfda1fSAndroid Build Coastguard Worker
118*59bfda1fSAndroid Build Coastguard Worker fd = open(path, O_RDONLY);
119*59bfda1fSAndroid Build Coastguard Worker if (fd < 0) {
120*59bfda1fSAndroid Build Coastguard Worker printf("open failed errno:%d\n", errno);
121*59bfda1fSAndroid Build Coastguard Worker return -1;
122*59bfda1fSAndroid Build Coastguard Worker }
123*59bfda1fSAndroid Build Coastguard Worker
124*59bfda1fSAndroid Build Coastguard Worker if (stat(path, &sb) == -1) {
125*59bfda1fSAndroid Build Coastguard Worker printf("stat failed errno:%d\n", errno);
126*59bfda1fSAndroid Build Coastguard Worker return -1;
127*59bfda1fSAndroid Build Coastguard Worker }
128*59bfda1fSAndroid Build Coastguard Worker
129*59bfda1fSAndroid Build Coastguard Worker blocks = (long long)sb.st_size / F2FS_BLKSIZE;
130*59bfda1fSAndroid Build Coastguard Worker if (sb.st_size % F2FS_BLKSIZE)
131*59bfda1fSAndroid Build Coastguard Worker blocks++;
132*59bfda1fSAndroid Build Coastguard Worker
133*59bfda1fSAndroid Build Coastguard Worker if (blocks << BLKS_TO_SECTOR_BITS != (long long)sb.st_blocks) {
134*59bfda1fSAndroid Build Coastguard Worker printf("FAIL: Mismatch i_size and i_blocks: %lld %lld\n",
135*59bfda1fSAndroid Build Coastguard Worker (long long)sb.st_size, (long long)sb.st_blocks);
136*59bfda1fSAndroid Build Coastguard Worker printf("FAIL: missing patch "
137*59bfda1fSAndroid Build Coastguard Worker "\"f2fs: do not preallocate blocks which has wrong buffer\"\n");
138*59bfda1fSAndroid Build Coastguard Worker }
139*59bfda1fSAndroid Build Coastguard Worker close(fd);
140*59bfda1fSAndroid Build Coastguard Worker unlink(path);
141*59bfda1fSAndroid Build Coastguard Worker return 0;
142*59bfda1fSAndroid Build Coastguard Worker }
143*59bfda1fSAndroid Build Coastguard Worker
main(void)144*59bfda1fSAndroid Build Coastguard Worker int main(void)
145*59bfda1fSAndroid Build Coastguard Worker {
146*59bfda1fSAndroid Build Coastguard Worker memset(buf, 0xff, BLOCKS);
147*59bfda1fSAndroid Build Coastguard Worker
148*59bfda1fSAndroid Build Coastguard Worker printf("# Test 0: Check F2FS support\n");
149*59bfda1fSAndroid Build Coastguard Worker run("cat /proc/filesystems");
150*59bfda1fSAndroid Build Coastguard Worker
151*59bfda1fSAndroid Build Coastguard Worker printf("# Test 1: Check F2FS status on /userdata\n");
152*59bfda1fSAndroid Build Coastguard Worker printf("\t= FS type /userdata\n");
153*59bfda1fSAndroid Build Coastguard Worker run("mount | grep data");
154*59bfda1fSAndroid Build Coastguard Worker
155*59bfda1fSAndroid Build Coastguard Worker printf("\n\t= F2FS features\n");
156*59bfda1fSAndroid Build Coastguard Worker run("ls -1 /sys/fs/f2fs/features/");
157*59bfda1fSAndroid Build Coastguard Worker run("find /sys/fs/f2fs -type f -name \"features\" -print -exec cat {} \\;");
158*59bfda1fSAndroid Build Coastguard Worker run("find /sys/fs/f2fs -type f -name \"ipu_policy\" -print -exec cat {} \\;");
159*59bfda1fSAndroid Build Coastguard Worker run("find /sys/fs/f2fs -type f -name \"discard_granularity\" -print -exec cat {} \\;");
160*59bfda1fSAndroid Build Coastguard Worker run("cat /sys/kernel/debug/f2fs/status");
161*59bfda1fSAndroid Build Coastguard Worker
162*59bfda1fSAndroid Build Coastguard Worker printf("\n\n# Test 2: Atomic_write on /userdata\n");
163*59bfda1fSAndroid Build Coastguard Worker if (test_atomic_write(DB1_PATH))
164*59bfda1fSAndroid Build Coastguard Worker return 0;
165*59bfda1fSAndroid Build Coastguard Worker
166*59bfda1fSAndroid Build Coastguard Worker printf("# Test 3: Atomic_write on /sdcard\n");
167*59bfda1fSAndroid Build Coastguard Worker if (test_atomic_write(DB2_PATH))
168*59bfda1fSAndroid Build Coastguard Worker return 0;
169*59bfda1fSAndroid Build Coastguard Worker
170*59bfda1fSAndroid Build Coastguard Worker printf("# Test 4: Bad write(2) call\n");
171*59bfda1fSAndroid Build Coastguard Worker if (test_bad_write_call(FILE_PATH))
172*59bfda1fSAndroid Build Coastguard Worker return 0;
173*59bfda1fSAndroid Build Coastguard Worker return 0;
174*59bfda1fSAndroid Build Coastguard Worker }
175