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