51a6bdd25ee8518388d86a2eb69a538da0302f44
[yaffs2.git] / direct / tests / nor_stress.c
1 #include "nor_stress.h"
2
3
4 #include "yaffsfs.h"
5 #include "yaffs_fsx.h"
6
7 #include <stdio.h>
8
9
10
11 #if 1
12 #define FSX_INIT(mount_pt) do{ if(interleave_fsx) yaffs_fsx_init(mount_pt); } while(0)
13 #define FSX_COMPLETE() do { if(interleave_fsx) yaffs_fsx_complete(); } while (0)
14
15 #define FSX() \
16 do { \
17   if((myrand() & 0x1) == 0){\
18      if(interleave_fsx) \
19         yaffs_fsx_do_op(); \
20   } \
21 } while(0)
22
23 #else
24 #define FSX_INIT(mount_point) do { } while(0)
25 #define FSX_COMPLETE() do { } while(0)
26 #define FSX() do { } while(0)
27 #endif
28
29
30 static unsigned powerUps;
31 static unsigned cycleStarts;
32 static unsigned cycleEnds;
33
34 static int interleave_fsx;
35
36 char fullPathName[100];
37 char fullPowerUpName[100];
38 char fullStartName[100];
39 char fullEndName[100];
40 char fullMainName[100];
41 char fullTempMainName[100];
42 char fullTempCounterName[100];
43
44
45 extern int random_seed;
46
47 int myrand(void) {
48   random_seed = random_seed * 1103515245 + 12345;
49   return((unsigned)(random_seed/65536) % 32768);
50 }
51
52 void MakeName(char *fullName,const char *prefix, const char *name)
53 {
54   strcpy(fullName,prefix);
55   strcat(fullName,"/");
56   strcat(fullName,name);
57 }
58
59
60 void MakeFullNames(const char *prefix)
61 {
62   MakeName(fullPathName,prefix,"");
63   MakeName(fullPowerUpName,prefix,"powerUps");
64   MakeName(fullStartName,prefix,"starts");
65   MakeName(fullEndName,prefix,"ends");
66   MakeName(fullMainName,prefix,"main");
67   MakeName(fullTempCounterName,prefix,"tmp-counter");
68   MakeName(fullTempMainName,prefix,"tmp-main");
69 }
70
71 static void FatalError(void)
72 {
73   printf("Integrity error\n");
74   while(1){}
75 }
76
77 static void UpdateCounter(const char *name, unsigned *val,  int initialise)
78 {
79   int inh=-1;
80   int outh=-1;
81   unsigned x[2];
82   int nread = 0;
83   int nwritten = 0;
84   
85   x[0] = x[1] = 0;
86   
87   if(initialise){
88     x[0] = 0; 
89     x[1] = 1;
90   } else {
91     inh = yaffs_open(name,O_RDONLY, S_IREAD | S_IWRITE);
92     if(inh >= 0){
93       nread = yaffs_read(inh,x,sizeof(x));
94       yaffs_close(inh);
95     }
96
97     if(nread != sizeof(x) ||
98        x[0] + 1 != x[1]){
99       printf("Error reading counter %s handle %d, x[0] %u x[1] %u last error %d\n",
100               name, inh, x[0], x[1],yaffsfs_GetLastError());
101       FatalError();
102               
103     }
104     x[0]++;
105     x[1]++;
106   }
107   
108   FSX();
109   outh = yaffs_open(fullTempCounterName, O_RDWR | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
110   if(outh >= 0){
111    FSX(); 
112     nwritten = yaffs_write(outh,x,sizeof(x));
113     FSX();
114     yaffs_close(outh);
115     FSX();
116     yaffs_rename(fullTempCounterName,name);
117     FSX();
118   }
119   
120   if(nwritten != sizeof(x)){
121       printf("Error writing counter %s handle %d, x[0] %u x[1] %u\n",
122               name, inh, x[0], x[1]);
123       FatalError();
124   }
125   
126   *val = x[0];
127   
128   printf("##\n"
129          "## Set counter %s to %u\n"
130          "##\n", name,x[0]);
131 }
132
133
134 static void dump_directory_tree_worker(const char *dname,int recursive)
135 {
136         yaffs_DIR *d;
137         yaffs_dirent *de;
138         struct yaffs_stat s;
139         char str[1000];
140                         
141         d = yaffs_opendir(dname);
142         
143         if(!d)
144         {
145                 printf("opendir failed\n");
146         }
147         else
148         {
149                 while((de = yaffs_readdir(d)) != NULL)
150                 {
151                         strcpy(str,dname);
152                         strcat(str,"/");
153                         strcat(str,de->d_name);
154                         
155                         yaffs_lstat(str,&s);
156                         
157                         printf("%s inode %d obj %x length %d mode %X ",str,s.st_ino,de->d_dont_use,(int)s.st_size,s.st_mode);
158                         switch(s.st_mode & S_IFMT)
159                         {
160                                 case S_IFREG: printf("data file"); break;
161                                 case S_IFDIR: printf("directory"); break;
162                                 case S_IFLNK: printf("symlink -->");
163                                                           if(yaffs_readlink(str,str,100) < 0)
164                                                                 printf("no alias");
165                                                           else
166                                                                 printf("\"%s\"",str);    
167                                                           break;
168                                 default: printf("unknown"); break;
169                         }
170                         
171                         printf("\n");
172
173                         if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
174                                 dump_directory_tree_worker(str,1);
175                                 
176                         if(s.st_ino > 10000)
177                           FatalError();
178                                                         
179                 }
180                 
181                 yaffs_closedir(d);
182         }
183
184 }
185
186 static void dump_directory_tree(const char *dname)
187 {
188         dump_directory_tree_worker(dname,1);
189         printf("\n");
190         printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
191 }
192
193
194
195
196 #define XX_SIZE 500
197
198 static unsigned xx[XX_SIZE];
199
200 static int yWriteFile(const char *fname, unsigned sz32)
201 {
202         int h;
203         int r;
204         int i;
205         unsigned checksum = 0;
206         
207         printf("Writing file %s\n",fname);
208
209         FSX();
210         h = yaffs_open(fname,O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
211         FSX();
212
213         if(h < 0){
214                 printf("could not open file %s\n",fname);
215                 return h;
216         }
217
218         xx[0] = sz32;
219         checksum ^= xx[0];
220
221         if((r = yaffs_write(h,xx,sizeof(unsigned))) != sizeof(unsigned)){
222                 goto WRITE_ERROR;
223         }
224         FSX();
225         while(sz32> 0){
226                 for(i = 0; i < XX_SIZE; i++){
227                   xx[i] = sz32 + i;
228                   checksum ^= xx[i];
229                 }
230                 
231                 FSX();
232                 if((r = yaffs_write(h,xx,sizeof(xx))) != sizeof(xx)){
233                         goto WRITE_ERROR;
234                 }
235                 sz32--;
236         }
237
238         xx[0] = checksum;
239         FSX();
240         if((r = yaffs_write(h,xx,sizeof(unsigned))) != sizeof(unsigned)){
241                 goto WRITE_ERROR;
242         }
243         
244         FSX();
245         yaffs_close(h);
246         return 0;
247
248 WRITE_ERROR:
249         printf("ywrite error at position %d\n",(int)yaffs_lseek(h,0,SEEK_END));
250         yaffs_close(h);
251         return -1;
252         
253 }
254
255 static int yVerifyFile(const char *fName)
256 {
257         unsigned checksum = 0;
258         unsigned totalSize;
259         unsigned sz32;
260         unsigned recordedSize = 0;
261         int r;
262         int h;
263         int i;
264         int retval = 0;
265
266
267         printf("Verifying file %s\n",fName);
268                 
269         h = yaffs_open(fName, O_RDONLY,S_IREAD | S_IWRITE);
270
271         if(h < 0){
272                 printf("could not open file %s\n",fName);
273                 return -1;
274         }
275
276         totalSize = yaffs_lseek(h,0,SEEK_END);
277         yaffs_lseek(h,0,SEEK_SET);
278
279         r = yaffs_read(h,&sz32,sizeof(sz32));
280
281         if(r != sizeof(sz32)){
282                 printf("reading size failed ... returned %d\n",r);
283                 yaffs_close(h);
284                 return -1;
285         }
286         
287         recordedSize = sz32 * sizeof(xx) + 8;
288
289         printf("verify %s: file size is %d, recorded size is %d\n", fName, totalSize, recordedSize);
290         if(totalSize != recordedSize){
291                 printf("!!!!!!!!!!!!!!!!!!!!!!!!file size is wrong, should be %d, is %d\n", recordedSize,totalSize);
292                 yaffs_close(h);
293                 return -1;
294         }
295
296         checksum ^= sz32;
297
298
299         while(sz32 > 0){
300                 r = yaffs_read(h,xx,sizeof(xx));
301                 if(r != sizeof(xx)){
302                         printf("!!!!!!!!!!!!!!!!!!!!!!!!!!reading data failed ... returned %d\n",r);
303                         yaffs_close(h);
304                         return -1;
305                 }
306                 for(i = 0; i < XX_SIZE; i++)
307                   checksum ^= xx[i];
308                 sz32--;
309         }
310         r = yaffs_read(h,xx,sizeof(xx[0]));
311         if(r != sizeof(xx[0])){
312                 printf("!!!!!!!!!!!!!!!!!!!!!!!!!!reading data failed ... returned %d\n",r);
313                 yaffs_close(h);
314                 return -1;
315         }
316         
317         checksum ^= xx[0];
318
319         if(checksum != 0){
320                 printf("!!!!!!!!!!!!!!!!!!!!! checksum failed\n");
321                 retval = -1;
322         } else
323                 printf("verified ok\n");
324         yaffs_close(h);
325
326         return retval;
327 }
328
329
330 static void DoUpdateMainFile(void)
331 {
332         int result;
333         int sz32;
334         sz32 = (myrand() % 1000)   + 20;
335         
336         result = yWriteFile(fullTempMainName,sz32);
337         FSX();
338         if(result)
339             FatalError();
340         yaffs_rename(fullTempMainName,fullMainName);
341         FSX();
342 }
343
344 static void DoVerifyMainFile(void)
345 {
346         int result;
347         result = yVerifyFile(fullMainName);
348         if(result)
349             FatalError();
350
351 }
352
353
354 void NorStressTestInitialise(const char *prefix)
355 {
356   MakeFullNames(prefix);
357   
358   UpdateCounter(fullPowerUpName,&powerUps,1);
359   UpdateCounter(fullStartName,&cycleStarts,1);
360   UpdateCounter(fullEndName,&cycleEnds,1);
361   UpdateCounter(fullPowerUpName,&powerUps,1);
362   DoUpdateMainFile();
363   DoVerifyMainFile();
364 }
365
366
367 void NorStressTestRun(const char *prefix, int n_cycles, int do_fsx)
368 {
369   interleave_fsx = do_fsx;
370   MakeFullNames(prefix);
371   FSX_INIT(prefix);
372     
373   dump_directory_tree(fullPathName);
374   
375   UpdateCounter(fullPowerUpName,&powerUps,0);
376   dump_directory_tree(fullPathName);
377   
378   while(n_cycles < 0 || n_cycles > 0){
379     if(n_cycles > 0)
380       n_cycles--;
381     UpdateCounter(fullStartName, &cycleStarts,0);
382     dump_directory_tree(fullPathName);
383     DoVerifyMainFile();
384     DoUpdateMainFile();
385     dump_directory_tree(fullPathName);
386   
387     UpdateCounter(fullEndName,&cycleEnds,0);
388     dump_directory_tree(fullPathName);
389   }
390   FSX_COMPLETE();
391 }