Merge relevant CXFSQA tests into XFSQA
[xfstests-dev.git] / src / trunc.c
1 /*
2  * Copyright (c) 2000-2003 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <time.h>
25 #include <stdio.h>
26
27 #define O_DIRECT        040000
28
29 #define WAITTIME        60
30 #define BUFSIZE         4096
31 #define ALIGNMENT       16384
32 #define TRUNCSIZE       1000
33
34 /* write data to disk - buffered/sync or direct
35  * write different buffered data to disk
36  * truncate
37  * direct read back, see if server puts stale data down
38  */
39
40 int
41 main(argc, argv)
42 int     argc;
43 char    **argv;
44 {
45         int fd, err, elapsed;
46         char *buf, *goodbuf;
47         time_t starttime;
48         char    ch, *filename="testfile";
49         int c;
50
51 if(argc != 3)
52         {        printf("Usage: trunc -f testfilename\n");
53                 exit(1);
54         }
55
56 while((c=getopt(argc,argv,"f:"))!=EOF) {
57                 ch = (char)c;
58                 switch (c) {
59                 case 'f':
60                         filename = optarg;
61                         break;
62                 default:
63                         fprintf(stderr,"Usage: trunc -f filename\n");
64                         exit(1);
65                 }
66         }
67
68         err = posix_memalign(&buf, ALIGNMENT, BUFSIZE);
69         if (err < 0) perror("posix_memalign failed");
70
71         err = posix_memalign(&goodbuf, ALIGNMENT, BUFSIZE);
72         if (err < 0) perror("posix_memalign failed");
73
74         err = unlink(filename);
75 /*      if (err < 0) perror("unlink failed");*/
76         
77         fd = open(filename, O_CREAT|O_RDWR|O_DIRECT, 0666);
78         if (fd < 0) perror("direct open failed");
79
80         memset(buf, 1, BUFSIZE);
81
82         printf("direct write of 1's into file\n");      
83         err = write(fd, buf, BUFSIZE);
84         if (err < 0) perror("buffered write failed");
85
86         close(fd);
87         
88         fd = open(filename, O_CREAT|O_RDWR, 0666);
89         if (fd < 0) perror("buffered open failed");
90
91         /* 1 now on disk */
92
93         memset(buf, 2, BUFSIZE);
94         memset(goodbuf, 2, BUFSIZE);
95
96         printf("buffered write of 2's into file\n");    
97         err = write(fd, buf, BUFSIZE);
98         if (err < 0) perror("direct write failed");
99
100         /* 1 now on disk, but 2 data is buffered */
101
102         printf("truncate file\n");
103         err = ftruncate(fd, TRUNCSIZE);
104         if (err < 0) perror("ftruncate failed");
105         starttime = time(NULL);
106
107         printf("sync buffered data (2's)\n");
108         err = fdatasync(fd);
109         if (err < 0) perror("fdatasync failed");
110
111         /* during truncate server may have read/modified/written last block */
112
113         close(fd);
114
115         fd = open(filename, O_CREAT|O_RDWR|O_DIRECT, 0666);
116         if (fd < 0) perror("direct open failed");
117
118         /* read what's really on disk now */
119
120         printf("iterate direct reads for %ds or until failure...\n", WAITTIME);
121
122         while ((elapsed = (time(NULL) - starttime)) <= WAITTIME) {
123
124                 /* printf(".");
125                 fflush(stdout);*/
126
127                 err = lseek(fd, 0, SEEK_SET);
128                 if (err < 0) perror("lseek failed");
129
130                 err = read(fd, buf, BUFSIZE);
131                 if (err < 0) perror("read failed");
132
133                 err = memcmp(buf, goodbuf, 100);
134                 if (err) {
135                         printf("\nFailed after %d secs: read %d's\n", elapsed, buf[0]); 
136                         return 1;
137                 }
138
139                 sleep(1);
140         }
141         
142         free(buf);
143         free(goodbuf);
144
145         printf("Passed\n");
146         return 0;
147 }
148
149