Home | History | Annotate | Download | only in ext4-inode-version
      1 /******************************************************************************/
      2 /*                                                                            */
      3 /* Copyright (c) 2009 FUJITSU LIMITED                                         */
      4 /*                                                                            */
      5 /* This program is free software;  you can redistribute it and/or modify      */
      6 /* it under the terms of the GNU General Public License as published by       */
      7 /* the Free Software Foundation; either version 2 of the License, or          */
      8 /* (at your option) any later version.                                        */
      9 /*                                                                            */
     10 /* This program is distributed in the hope that it will be useful,            */
     11 /* but WITHOUT ANY WARRANTY;  without even the implied warranty of            */
     12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  */
     13 /* the GNU General Public License for more details.                           */
     14 /*                                                                            */
     15 /* You should have received a copy of the GNU General Public License          */
     16 /* along with this program;  if not, write to the Free Software               */
     17 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA    */
     18 /*                                                                            */
     19 /* Author: Li Zefan <lizf (at) cn.fujitsu.com>                                     */
     20 /*                                                                            */
     21 /******************************************************************************/
     22 
     23 #include <unistd.h>
     24 #include <wait.h>
     25 #include <string.h>
     26 #include <stdlib.h>
     27 #include <stdio.h>
     28 #include <fcntl.h>
     29 #include <sys/types.h>
     30 #include <sys/stat.h>
     31 #include <sys/mman.h>
     32 
     33 char *filename;
     34 char *filepath;
     35 int fd;
     36 
     37 int old_inode_version;
     38 int new_inode_version;
     39 
     40 int get_inode_version(void)
     41 {
     42 	char buf[1024];
     43 
     44 	sprintf(buf, "ext4_get_inode_version.sh %s 1", filename);
     45 
     46 	/* sync before run debugfs to get inode version */
     47 	sync();
     48 
     49 	return WEXITSTATUS(system(buf));
     50 }
     51 
     52 void test_chmod(void)
     53 {
     54 	if (fchmod(fd, S_IRUSR | S_IWUSR)) {
     55 		fprintf(stderr, "fchmod failed\n");
     56 		exit(1);
     57 	}
     58 }
     59 
     60 void test_chown(void)
     61 {
     62 	if (fchown(fd, 1, 1)) {
     63 		fprintf(stderr, "fchown failed\n");
     64 		exit(1);
     65 	}
     66 }
     67 
     68 void test_read(void)
     69 {
     70 	char buf[2];
     71 
     72 	/* write something before read */
     73 	if (write(fd, "abc", 4) == -1) {
     74 		perror("write");
     75 		exit(1);
     76 	}
     77 	close(fd);
     78 
     79 	if (open(filepath, O_RDONLY) == -1) {
     80 		perror("open");
     81 		exit(1);
     82 	}
     83 
     84 	old_inode_version = get_inode_version();
     85 
     86 	if (read(fd, buf, 1) == -1) {
     87 		perror("read");
     88 		exit(1);
     89 	}
     90 }
     91 
     92 void test_write(void)
     93 {
     94 	if (write(fd, "a", 1) == -1) {
     95 		fprintf(stderr, "write failed\n");
     96 		exit(1);
     97 	}
     98 }
     99 
    100 void test_mmap_read(void)
    101 {
    102 	char *p;
    103 	char c;
    104 
    105 	/* write something before read */
    106 	if (write(fd, "abc", 4) == -1) {
    107 		perror("write");
    108 		exit(1);
    109 	}
    110 	close(fd);
    111 
    112 	if (open(filepath, O_RDONLY) == -1) {
    113 		perror("open");
    114 		exit(1);
    115 	}
    116 
    117 	old_inode_version = get_inode_version();
    118 
    119 	p = mmap(NULL, 1, PROT_READ, MAP_PRIVATE | MAP_FILE, fd, 0);
    120 	if (p == (void *)-1) {
    121 		perror("mmap");
    122 		exit(1);
    123 	}
    124 	c = *p;
    125 
    126 	new_inode_version = get_inode_version();
    127 
    128 	msync(p, 1, MS_SYNC);
    129 }
    130 
    131 void test_mmap_write(void)
    132 {
    133 	char *p;
    134 
    135 	if (write(fd, "abc", 4) == -1) {
    136 		perror("write");
    137 		exit(1);
    138 	}
    139 	close(fd);
    140 
    141 	if (open(filepath, O_RDWR) == -1) {
    142 		perror("open");
    143 		exit(1);
    144 	}
    145 
    146 	old_inode_version = get_inode_version();
    147 
    148 	p = mmap(NULL, 1, PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0);
    149 	if (p == (void *)-1) {
    150 		perror("mmap");
    151 		exit(1);
    152 	}
    153 	*p = 'x';
    154 
    155 	new_inode_version = get_inode_version();
    156 
    157 	msync(p, 1, MS_SYNC);
    158 }
    159 
    160 /**
    161  * argv[1]: file operation
    162  * argv[2]: file to test (with path)
    163  * argv[3]: file to test (without path)
    164  */
    165 int main(int argc, char *argv[])
    166 {
    167 	if (argc != 4) {
    168 		fprintf(stderr, "wrong argument number\n");
    169 		return 1;
    170 	}
    171 	filepath = argv[2];
    172 	filename = argv[3];
    173 
    174 	/* create file and get the initial inode version */
    175 	fd = creat(argv[2], O_RDWR);
    176 	if (fd == -1) {
    177 		fprintf(stderr, "failed to create file: %s\n", argv[2]);
    178 		return 1;
    179 	}
    180 
    181 	old_inode_version = get_inode_version();
    182 
    183 	if (strcmp(argv[1], "create") == 0) {
    184 		printf("%d\n", old_inode_version);
    185 		return 0;
    186 	} else if (strcmp(argv[1], "chmod") == 0) {
    187 		test_chmod();
    188 	} else if (strcmp(argv[1], "chown") == 0) {
    189 		test_chown();
    190 	} else if (strcmp(argv[1], "read") == 0) {
    191 		test_read();
    192 	} else if (strcmp(argv[1], "write") == 0) {
    193 		test_write();
    194 	} else if (strcmp(argv[1], "mmap_read") == 0) {
    195 		test_mmap_read();
    196 	} else if (strcmp(argv[1], "mmap_write") == 0) {
    197 		test_mmap_write();
    198 	} else {
    199 		fprintf(stderr, "wrong file operation: %s\n", argv[1]);
    200 		return 1;
    201 	}
    202 
    203 	new_inode_version = get_inode_version();
    204 #if 0
    205 	fprintf(stderr, "test_inode_version: old - %d\n", old_inode_version);
    206 	fprintf(stderr, "test_inode_version: new - %d\n", new_inode_version);
    207 #endif
    208 	/* wrong inode version, test failed */
    209 	if (new_inode_version <= old_inode_version)
    210 		return 1;
    211 
    212 	printf("%d\n", new_inode_version);
    213 
    214 	close(fd);
    215 
    216 	return 0;
    217 }
    218