2 * YAFFS: Yet another FFS. A NAND-flash specific file system.
4 * Copyright (C) 2002-2011 Aleph One Ltd.
5 * for Toby Churchill Ltd and Brightstar Engineering
7 * Created by Charles Manning <charles@aleph1.co.uk>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
15 #include "nor_stress.h"
19 #include "yaffs_fsx.h"
28 #define FSX_INIT(mount_pt) do{ if(interleave_fsx) yaffs_fsx_init(mount_pt); } while(0)
29 #define FSX_COMPLETE() do { if(interleave_fsx) yaffs_fsx_complete(); } while (0)
33 if((myrand() & 0x1) == 0){\
40 #define FSX_INIT(mount_point) do { } while(0)
41 #define FSX_COMPLETE() do { } while(0)
42 #define FSX() do { } while(0)
46 void (*ext_fatal)(void) = NULL;
48 static unsigned powerUps;
49 static unsigned cycleStarts;
50 static unsigned cycleEnds;
52 static int interleave_fsx;
54 static int no_verification;
56 char fullPathName[100];
57 char fullPowerUpName[100];
58 char fullStartName[100];
59 char fullEndName[100];
60 char fullMainName[100];
61 char fullTempMainName[100];
62 char fullTempCounterName[100];
65 extern int random_seed;
68 random_seed = random_seed * 1103515245 + 12345;
69 return((unsigned)(random_seed/65536) % 32768);
72 void MakeName(char *fullName,const char *prefix, const char *name)
74 strcpy(fullName,prefix);
76 strcat(fullName,name);
80 void MakeFullNames(const char *prefix)
82 MakeName(fullPathName,prefix,"");
83 MakeName(fullPowerUpName,prefix,"powerUps");
84 MakeName(fullStartName,prefix,"starts");
85 MakeName(fullEndName,prefix,"ends");
86 MakeName(fullMainName,prefix,"main");
87 MakeName(fullTempCounterName,prefix,"tmp-counter");
88 MakeName(fullTempMainName,prefix,"tmp-main");
91 static void FatalError(int line_no)
93 printf("Integrity error %d\n",line_no);
105 void print_stat(const char *str, struct yaffs_stat *st)
107 printf("%s inode %d\n",str,st->st_ino);
110 static void UpdateCounter(const char *name, unsigned *val, int initialise)
124 inh = yaffs_open(name,O_RDONLY, S_IREAD | S_IWRITE);
126 nread = yaffs_read(inh,x,sizeof(x));
130 if(!no_verification &&
131 (nread != sizeof(x) ||
133 printf("Error reading counter %s handle %d, x[0] %u x[1] %u last error %d\n",
134 name, inh, x[0], x[1],yaffsfs_GetLastError());
135 FatalError(__LINE__);
143 outh = yaffs_open(fullTempCounterName, O_RDWR | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
146 struct yaffs_stat tmpstat, oldstat, tmpfstat;
148 yaffs_fstat(outh,&tmpfstat);
149 printf("\n\n\n*** Writing file %s inode %d\n",fullTempCounterName,tmpfstat.st_ino);
150 nwritten = yaffs_write(outh,x,sizeof(x));
155 printf("About to rename %s to %s\n",fullTempCounterName,name);
156 yaffs_stat(fullTempCounterName,&tmpstat);
157 yaffs_stat(name,&oldstat);
158 print_stat("old stat",&oldstat);
159 print_stat("new stat",&tmpstat);
160 print_stat("new fstat",&tmpfstat);
161 yaffs_rename(fullTempCounterName,name);
165 if(nwritten != sizeof(x)){
166 printf("Error writing counter %s handle %d, x[0] %u x[1] %u\n",
167 name, inh, x[0], x[1]);
168 FatalError(__LINE__);
174 "## Set counter %s to %u\n"
179 static void dump_directory_tree_worker(const char *dname,int recursive)
182 struct yaffs_dirent *de;
188 d = yaffs_opendir(dname);
192 printf("opendir failed\n");
197 while((de = yaffs_readdir(d)) != NULL)
201 strcat(str,de->d_name);
206 printf("%s inode %ld obj %d %p length %d mode %X ",
207 str, de->d_ino, s.st_ino,
208 de->d_dont_use, (int)s.st_size, s.st_mode);
210 if(de->d_ino != s.st_ino){
211 printf(" \n\n!!!! HEY inode mismatch\n\n");
212 error_line = __LINE__;
215 switch(s.st_mode & S_IFMT)
217 case S_IFREG: printf("data file"); break;
218 case S_IFDIR: printf("directory"); break;
219 case S_IFLNK: printf("symlink -->");
220 if(yaffs_readlink(str,str,100) < 0)
223 printf("\"%s\"",str);
225 default: printf("unknown"); break;
230 if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
231 dump_directory_tree_worker(str,1);
234 error_line = __LINE__;
238 if(strstr(dname,"lost+found") && nentries >0){
239 printf("\n\n!!! HEY lost+found not empty, had %d entries\n\n\n",nentries);
240 error_line = __LINE__;
243 if(error_line && !no_verification)
244 FatalError(error_line);
251 static void dump_directory_tree(const char *dname)
253 dump_directory_tree_worker(dname,1);
255 printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
263 static unsigned xx[XX_SIZE];
265 static int y_wr_file(const char *fname, unsigned sz32)
270 struct yaffs_stat st;
271 unsigned checksum = 0;
275 h = yaffs_open(fname,O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
277 printf("\n\n\n**** Open writing file %s inode %d\n",fname, st.st_ino);
282 printf("could not open file %s\n",fname);
289 if((r = yaffs_write(h,xx,sizeof(unsigned))) != sizeof(unsigned)){
294 for(i = 0; i < XX_SIZE; i++){
300 if((r = yaffs_write(h,xx,sizeof(xx))) != sizeof(xx)){
308 if((r = yaffs_write(h,xx,sizeof(unsigned))) != sizeof(unsigned)){
314 printf("File closed\n");
318 printf("ywrite error at position %d\n",(int)yaffs_lseek(h,0,SEEK_END));
324 static int y_verify_file(const char *fName)
326 unsigned checksum = 0;
329 unsigned recordedSize = 0;
338 printf("Verifying file %s\n",fName);
340 h = yaffs_open(fName, O_RDONLY,S_IREAD | S_IWRITE);
343 printf("could not open file %s\n",fName);
347 totalSize = yaffs_lseek(h,0,SEEK_END);
348 yaffs_lseek(h,0,SEEK_SET);
350 r = yaffs_read(h,&sz32,sizeof(sz32));
352 if(r != sizeof(sz32)){
353 printf("reading size failed ... returned %d\n",r);
358 recordedSize = sz32 * sizeof(xx) + 8;
360 printf("verify %s: file size is %d, recorded size is %d\n", fName, totalSize, recordedSize);
361 if(totalSize != recordedSize){
362 printf("!!!!!!!!!!!!!!!!!!!!!!!!file size is wrong, should be %d, is %d\n", recordedSize,totalSize);
371 r = yaffs_read(h,xx,sizeof(xx));
373 printf("!!!!!!!!!!!!!!!!!!!!!!!!!!reading data failed ... returned %d\n",r);
377 for(i = 0; i < XX_SIZE; i++)
381 r = yaffs_read(h,xx,sizeof(xx[0]));
382 if(r != sizeof(xx[0])){
383 printf("!!!!!!!!!!!!!!!!!!!!!!!!!!reading data failed ... returned %d\n",r);
391 printf("!!!!!!!!!!!!!!!!!!!!! checksum failed\n");
394 printf("verified ok\n");
401 static void DoUpdateMainFile(void)
405 sz32 = (myrand() % 1000) + 20;
407 result = y_wr_file(fullTempMainName,sz32);
409 if(!no_verification && result)
410 FatalError(__LINE__);
411 printf("Rename file %s to %s\n",fullTempMainName,fullMainName);
412 yaffs_rename(fullTempMainName,fullMainName);
416 static void DoVerifyMainFile(void)
421 result = y_verify_file(fullMainName);
423 FatalError(__LINE__);
428 void NorStressTestInitialise(const char *prefix)
430 MakeFullNames(prefix);
432 UpdateCounter(fullPowerUpName,&powerUps,1);
433 UpdateCounter(fullStartName,&cycleStarts,1);
434 UpdateCounter(fullEndName,&cycleEnds,1);
435 UpdateCounter(fullPowerUpName,&powerUps,1);
441 void NorStressTestRun(const char *prefix, int n_cycles, int do_fsx, int skip_verification)
444 interleave_fsx = do_fsx;
445 no_verification = skip_verification;
447 MakeFullNames(prefix);
448 dump_directory_tree(fullPathName);
451 dump_directory_tree(fullPathName);
453 UpdateCounter(fullPowerUpName,&powerUps,0);
454 dump_directory_tree(fullPathName);
456 while(n_cycles < 0 || n_cycles > 0){
459 UpdateCounter(fullStartName, &cycleStarts,0);
460 dump_directory_tree(fullPathName);
463 dump_directory_tree(fullPathName);
465 UpdateCounter(fullEndName,&cycleEnds,0);
466 dump_directory_tree(fullPathName);