Have updated yaffs direct tests and added README files to the tests.
[yaffs2.git] / direct / tests / nor_stress.c
index 51a6bdd25ee8518388d86a2eb69a538da0302f44..e62095d785e59e71dd1ac07d157a6aa7be13d3a5 100644 (file)
@@ -1,3 +1,17 @@
+/*
+ * YAFFS: Yet another FFS. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Charles Manning <charles@aleph1.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
 #include "nor_stress.h"
 
 
@@ -7,6 +21,7 @@
 #include <stdio.h>
 
 
+extern int fuzz_test;
 
 #if 1
 #define FSX_INIT(mount_pt) do{ if(interleave_fsx) yaffs_fsx_init(mount_pt); } while(0)
@@ -27,12 +42,16 @@ do { \
 #endif
 
 
+void (*ext_fatal)(void) = NULL;
+
 static unsigned powerUps;
 static unsigned cycleStarts;
 static unsigned cycleEnds;
 
 static int interleave_fsx;
 
+static int no_verification;
 char fullPathName[100];
 char fullPowerUpName[100];
 char fullStartName[100];
@@ -68,10 +87,23 @@ void MakeFullNames(const char *prefix)
   MakeName(fullTempMainName,prefix,"tmp-main");
 }
 
-static void FatalError(void)
+static void FatalError(int line_no)
 {
-  printf("Integrity error\n");
-  while(1){}
+  printf("Integrity error %d\n",line_no);
+
+  if(fuzz_test)
+       return;
+
+  if(ext_fatal)
+       ext_fatal();
+       
+  while(1){
+   sleep(1);
+  }
+}
+void print_stat(const char *str, struct yaffs_stat *st)
+{
+       printf("%s inode %d\n",str,st->st_ino);
 }
 
 static void UpdateCounter(const char *name, unsigned *val,  int initialise)
@@ -94,11 +126,12 @@ static void UpdateCounter(const char *name, unsigned *val,  int initialise)
       yaffs_close(inh);
     }
 
-    if(nread != sizeof(x) ||
-       x[0] + 1 != x[1]){
+    if(!no_verification &&
+      (nread != sizeof(x) ||
+       x[0] + 1 != x[1])){
       printf("Error reading counter %s handle %d, x[0] %u x[1] %u last error %d\n",
               name, inh, x[0], x[1],yaffsfs_GetLastError());
-      FatalError();
+      FatalError(__LINE__);
               
     }
     x[0]++;
@@ -107,12 +140,23 @@ static void UpdateCounter(const char *name, unsigned *val,  int initialise)
   
   FSX();
   outh = yaffs_open(fullTempCounterName, O_RDWR | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
+  
   if(outh >= 0){
+   struct yaffs_stat tmpstat, oldstat, tmpfstat;
    FSX(); 
+    yaffs_fstat(outh,&tmpfstat);
+    printf("\n\n\n*** Writing file %s inode %d\n",fullTempCounterName,tmpfstat.st_ino);
     nwritten = yaffs_write(outh,x,sizeof(x));
     FSX();
     yaffs_close(outh);
     FSX();
+
+    printf("About to rename %s to %s\n",fullTempCounterName,name);
+    yaffs_stat(fullTempCounterName,&tmpstat);
+    yaffs_stat(name,&oldstat);
+    print_stat("old stat",&oldstat);
+    print_stat("new stat",&tmpstat);
+    print_stat("new fstat",&tmpfstat);
     yaffs_rename(fullTempCounterName,name);
     FSX();
   }
@@ -120,7 +164,7 @@ static void UpdateCounter(const char *name, unsigned *val,  int initialise)
   if(nwritten != sizeof(x)){
       printf("Error writing counter %s handle %d, x[0] %u x[1] %u\n",
               name, inh, x[0], x[1]);
-      FatalError();
+      FatalError(__LINE__);
   }
   
   *val = x[0];
@@ -137,6 +181,8 @@ static void dump_directory_tree_worker(const char *dname,int recursive)
        yaffs_dirent *de;
        struct yaffs_stat s;
        char str[1000];
+       int error_line = 0;
+       int nentries;
                        
        d = yaffs_opendir(dname);
        
@@ -146,15 +192,22 @@ static void dump_directory_tree_worker(const char *dname,int recursive)
        }
        else
        {
+               nentries = 0;
                while((de = yaffs_readdir(d)) != NULL)
                {
                        strcpy(str,dname);
                        strcat(str,"/");
                        strcat(str,de->d_name);
+                       nentries++;
                        
                        yaffs_lstat(str,&s);
                        
-                       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);
+                       printf("%s inode %ld %d obj %x length %d mode %X ",str, de->d_ino, s.st_ino,de->d_dont_use,(int)s.st_size,s.st_mode);\
+                       if(de->d_ino != s.st_ino){
+                               printf(" \n\n!!!! HEY inode mismatch\n\n");
+                               error_line = __LINE__;
+                       }
+
                        switch(s.st_mode & S_IFMT)
                        {
                                case S_IFREG: printf("data file"); break;
@@ -174,10 +227,18 @@ static void dump_directory_tree_worker(const char *dname,int recursive)
                                dump_directory_tree_worker(str,1);
                                
                         if(s.st_ino > 10000)
-                          FatalError();
+                               error_line = __LINE__;
                                                        
                }
                
+               if(strstr(dname,"lost+found") && nentries >0){
+                       printf("\n\n!!! HEY lost+found not empty, had %d entries\n\n\n",nentries);
+                       error_line = __LINE__;
+               }
+
+               if(error_line && !no_verification)
+                       FatalError(error_line);
+               
                yaffs_closedir(d);
        }
 
@@ -197,17 +258,20 @@ static void dump_directory_tree(const char *dname)
 
 static unsigned xx[XX_SIZE];
 
-static int yWriteFile(const char *fname, unsigned sz32)
+static int y_wr_file(const char *fname, unsigned sz32)
 {
        int h;
        int r;
        int i;
+       struct yaffs_stat st;
        unsigned checksum = 0;
        
-       printf("Writing file %s\n",fname);
 
        FSX();
        h = yaffs_open(fname,O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
+       yaffs_fstat(h,&st);
+       printf("\n\n\n**** Open writing file %s inode %d\n",fname, st.st_ino);
+       
        FSX();
 
        if(h < 0){
@@ -243,6 +307,7 @@ static int yWriteFile(const char *fname, unsigned sz32)
        
        FSX();
        yaffs_close(h);
+       printf("File closed\n");
        return 0;
 
 WRITE_ERROR:
@@ -252,7 +317,7 @@ WRITE_ERROR:
        
 }
 
-static int yVerifyFile(const char *fName)
+static int y_verify_file(const char *fName)
 {
        unsigned checksum = 0;
        unsigned totalSize;
@@ -263,6 +328,8 @@ static int yVerifyFile(const char *fName)
        int i;
        int retval = 0;
 
+       if(no_verification)
+               return 0;
 
         printf("Verifying file %s\n",fName);
                
@@ -333,10 +400,11 @@ static void DoUpdateMainFile(void)
         int sz32;
         sz32 = (myrand() % 1000)   + 20;
         
-       result = yWriteFile(fullTempMainName,sz32);
+       result = y_wr_file(fullTempMainName,sz32);
        FSX();
-       if(result)
-           FatalError();
+       if(!no_verification && result)
+           FatalError(__LINE__);
+       printf("Raname file %s to %s\n",fullTempMainName,fullMainName);
        yaffs_rename(fullTempMainName,fullMainName);
        FSX();
 }
@@ -344,9 +412,11 @@ static void DoUpdateMainFile(void)
 static void DoVerifyMainFile(void)
 {
         int result;
-       result = yVerifyFile(fullMainName);
+       if(no_verification)
+               return;
+       result = y_verify_file(fullMainName);
        if(result)
-           FatalError();
+           FatalError(__LINE__);
 
 }
 
@@ -364,10 +434,14 @@ void NorStressTestInitialise(const char *prefix)
 }
 
 
-void NorStressTestRun(const char *prefix, int n_cycles, int do_fsx)
+void NorStressTestRun(const char *prefix, int n_cycles, int do_fsx, int skip_verification)
 {
+
   interleave_fsx = do_fsx;
+  no_verification = skip_verification;
   MakeFullNames(prefix);
+  dump_directory_tree(fullPathName);
   FSX_INIT(prefix);
     
   dump_directory_tree(fullPathName);