1a20ef95e6d9f438eab8e50310798a29326c9c6d
[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 #include <stdlib.h>
27 #include <string.h>
28
29 #define O_DIRECT        040000
30
31 #define WAITTIME        60
32 #define BUFSIZE         4096
33 #define ALIGNMENT       16384
34 #define TRUNCSIZE       1000
35
36 /* write data to disk - buffered/sync or direct
37  * write different buffered data to disk
38  * truncate
39  * direct read back, see if server puts stale data down
40  */
41
42 int
43 main(argc, argv)
44 int     argc;
45 char    **argv;
46 {
47         int fd, err, elapsed;
48         char *buf, *goodbuf;
49         time_t starttime;
50         char    ch, *filename="testfile";
51         int c;
52
53 if(argc != 3)
54         {        printf("Usage: trunc -f testfilename\n");
55                 exit(1);
56         }
57
58 while((c=getopt(argc,argv,"f:"))!=EOF) {
59                 ch = (char)c;
60                 switch (c) {
61                 case 'f':
62                         filename = optarg;
63                         break;
64                 default:
65                         fprintf(stderr,"Usage: trunc -f filename\n");
66                         exit(1);
67                 }
68         }
69
70         err = posix_memalign((void **)&buf, ALIGNMENT, BUFSIZE);
71         if (err < 0) perror("posix_memalign failed");
72
73         err = posix_memalign((void **)&goodbuf, ALIGNMENT, BUFSIZE);
74         if (err < 0) perror("posix_memalign failed");
75
76         err = unlink(filename);
77 /*      if (err < 0) perror("unlink failed");*/
78         
79         fd = open(filename, O_CREAT|O_RDWR|O_DIRECT, 0666);
80         if (fd < 0) perror("direct open failed");
81
82         memset(buf, 1, BUFSIZE);
83
84         printf("direct write of 1's into file\n");      
85         err = write(fd, buf, BUFSIZE);
86         if (err < 0) perror("buffered write failed");
87
88         close(fd);
89         
90         fd = open(filename, O_CREAT|O_RDWR, 0666);
91         if (fd < 0) perror("buffered open failed");
92
93         /* 1 now on disk */
94
95         memset(buf, 2, BUFSIZE);
96         memset(goodbuf, 2, BUFSIZE);
97
98         printf("buffered write of 2's into file\n");    
99         err = write(fd, buf, BUFSIZE);
100         if (err < 0) perror("direct write failed");
101
102         /* 1 now on disk, but 2 data is buffered */
103
104         printf("truncate file\n");
105         err = ftruncate(fd, TRUNCSIZE);
106         if (err < 0) perror("ftruncate failed");
107         starttime = time(NULL);
108
109         printf("sync buffered data (2's)\n");
110         err = fdatasync(fd);
111         if (err < 0) perror("fdatasync failed");
112
113         /* during truncate server may have read/modified/written last block */
114
115         close(fd);
116
117         fd = open(filename, O_CREAT|O_RDWR|O_DIRECT, 0666);
118         if (fd < 0) perror("direct open failed");
119
120         /* read what's really on disk now */
121
122         printf("iterate direct reads for %ds or until failure...\n", WAITTIME);
123
124         while ((elapsed = (time(NULL) - starttime)) <= WAITTIME) {
125
126                 /* printf(".");
127                 fflush(stdout);*/
128
129                 err = lseek(fd, 0, SEEK_SET);
130                 if (err < 0) perror("lseek failed");
131
132                 err = read(fd, buf, BUFSIZE);
133                 if (err < 0) perror("read failed");
134
135                 err = memcmp(buf, goodbuf, 100);
136                 if (err) {
137                         printf("\nFailed after %d secs: read %d's\n", elapsed, buf[0]); 
138                         return 1;
139                 }
140
141                 sleep(1);
142         }
143         
144         free(buf);
145         free(goodbuf);
146
147         printf("Passed\n");
148         return 0;
149 }
150
151