Check in inband tags, some extra yaffs direct functions and some other changes
authorcharles <charles>
Mon, 5 May 2008 07:58:58 +0000 (07:58 +0000)
committercharles <charles>
Mon, 5 May 2008 07:58:58 +0000 (07:58 +0000)
26 files changed:
devextras.h
direct/Makefile
direct/dtest.c
direct/fsx_test/Makefile
direct/fsx_test/yaffs_fsx.c
direct/yaffs_fileem2k.c
direct/yaffs_flashif.h
direct/yaffs_ramdisk.c
direct/yaffs_ramdisk.h
direct/yaffs_ramem2k.c
direct/yaffscfg2k.c
direct/yaffsfs.c
direct/yaffsfs.h
direct/ydirectenv.h
yaffs_checkptrw.c
yaffs_fs.c
yaffs_guts.c
yaffs_guts.h
yaffs_mtdif2.c
yaffs_nand.c
yaffs_nandemul2k.h
yaffs_packedtags2.c
yaffs_packedtags2.h
yaffs_tagscompat.c
yaffs_tagscompat.h
yportenv.h

index 2ba88a2..55c3121 100644 (file)
 #ifndef __EXTRAS_H__
 #define __EXTRAS_H__
 
-#if defined WIN32
-#define __inline__ __inline
-#define new newHack
-#endif
 
-#if !(defined __KERNEL__) || (defined WIN32)
+#if !(defined __KERNEL__)
 
 /* Definition of types */
 typedef unsigned char __u8;
 typedef unsigned short __u16;
 typedef unsigned __u32;
 
+#endif
+
 /*
  * This is a simple doubly linked list implementation that matches the 
  * way the Linux kernel doubly linked list implementation works.
  */
 
-struct list_head {
-       struct list_head *next; /* next in chain */
-       struct list_head *prev; /* previous in chain */
+struct ylist_head {
+       struct ylist_head *next; /* next in chain */
+       struct ylist_head *prev; /* previous in chain */
 };
 
 
 /* Initialise a list head to an empty list */
-#define INIT_LIST_HEAD(p) \
+#define YINIT_LIST_HEAD(p) \
 do { \
  (p)->next = (p);\
  (p)->prev = (p); \
@@ -55,10 +53,10 @@ do { \
 
 
 /* Add an element to a list */
-static __inline__ void list_add(struct list_head *newEntry, 
-                               struct list_head *list)
+static __inline__ void ylist_add(struct ylist_head *newEntry, 
+                                struct ylist_head *list)
 {
-       struct list_head *listNext = list->next;
+       struct ylist_head *listNext = list->next;
        
        list->next = newEntry;
        newEntry->prev = list;
@@ -70,52 +68,63 @@ static __inline__ void list_add(struct list_head *newEntry,
 
 /* Take an element out of its current list, with or without
  * reinitialising the links.of the entry*/
-static __inline__ void list_del(struct list_head *entry)
+static __inline__ void ylist_del(struct ylist_head *entry)
 {
-       struct list_head *listNext = entry->next;
-       struct list_head *listPrev = entry->prev;
+       struct ylist_head *listNext = entry->next;
+       struct ylist_head *listPrev = entry->prev;
        
        listNext->prev = listPrev;
        listPrev->next = listNext;
        
 }
 
-static __inline__ void list_del_init(struct list_head *entry)
+static __inline__ void ylist_del_init(struct ylist_head *entry)
 {
-       list_del(entry);
+       ylist_del(entry);
        entry->next = entry->prev = entry;
 }
 
 
 /* Test if the list is empty */
-static __inline__ int list_empty(struct list_head *entry)
+static __inline__ int ylist_empty(struct ylist_head *entry)
 {
        return (entry->next == entry);
 }
 
 
-/* list_entry takes a pointer to a list entry and offsets it to that
+/* ylist_entry takes a pointer to a list entry and offsets it to that
  * we can find a pointer to the object it is embedded in.
  */
  
  
-#define list_entry(entry, type, member) \
+#define ylist_entry(entry, type, member) \
        ((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member)))
 
 
-/* list_for_each and list_for_each_safe  iterate over lists.
- * list_for_each_safe uses temporary storage to make the list delete safe
+/* ylist_for_each and list_for_each_safe  iterate over lists.
+ * ylist_for_each_safe uses temporary storage to make the list delete safe
  */
 
-#define list_for_each(itervar, list) \
+#define ylist_for_each(itervar, list) \
        for (itervar = (list)->next; itervar != (list); itervar = itervar->next )
 
-#define list_for_each_safe(itervar,saveVar, list) \
+#define ylist_for_each_safe(itervar,saveVar, list) \
        for (itervar = (list)->next, saveVar = (list)->next->next; itervar != (list); \
         itervar = saveVar, saveVar = saveVar->next)
 
+
+#if !(defined __KERNEL__)
+
+
+#ifndef WIN32
+#include <sys/stat.h>
+#endif
+
+
+#ifdef CONFIG_YAFFS_PROVIDE_DEFS
 /* File types */
 
+
 #define DT_UNKNOWN     0
 #define DT_FIFO                1
 #define DT_CHR         2
@@ -124,7 +133,7 @@ static __inline__ int list_empty(struct list_head *entry)
 #define DT_REG         8
 #define DT_LNK         10
 #define DT_SOCK                12
-#define DR_WHT         14
+#define DT_WHT         14
 
 
 #ifndef WIN32
@@ -155,21 +164,18 @@ struct iattr {
        unsigned int ia_attr_flags;
 };
 
+#endif
+
+
 #define KERN_DEBUG
 
 #else
 
-#ifndef WIN32
 #include <linux/types.h>
-#include <linux/list.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
-#endif
 
 #endif
 
-#if defined WIN32
-#undef new
-#endif
 
 #endif
index dd6b61d..a65c0e6 100644 (file)
 #
 # NB Warning this Makefile does not include header dependencies.
 #
-# $Id: Makefile,v 1.15 2007-07-18 19:40:38 charles Exp $
+# $Id: Makefile,v 1.16 2008-05-05 07:58:58 charles Exp $
 
 #EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC
 
-CFLAGS =    -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2 -g $(EXTRA_COMPILE_FLAGS) -DNO_Y_INLINE
-CFLAGS+=    -fstack-check -O0
+CFLAGS =      -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2  
+CFLAGS +=     -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES -DNO_Y_INLINE
+CFLAGS +=    -Wall -g $(EXTRA_COMPILE_FLAGS)
+#CFLAGS+=    -fstack-check -O0
 
 #CFLAGS+=   -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations
 #CFLAGS+=   -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline
@@ -40,7 +42,7 @@ ALLOBJS = $(DIRECTTESTOBJS) $(BOOTTESTOBJS)
 
 SYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffsinterface.h yportenv.h yaffs_tagscompat.c yaffs_tagscompat.h \
           yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h  yaffs_nandemul2k.h \
-          yaffs_nand.c yaffs_nand.h \
+          yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h \
           yaffs_tagsvalidity.c yaffs_tagsvalidity.h yaffs_checkptrw.h yaffs_checkptrw.c \
           yaffs_qsort.c yaffs_qsort.h
 
@@ -49,7 +51,7 @@ SYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffsin
 all: directtest2k
 
 $(ALLOBJS): %.o: %.c
-       gcc -c $(CFLAGS) $< -o $@
+       gcc -c $(CFLAGS) -o $@ $<
 
 $(SYMLINKS):
        ln -s ../$@ $@
index be492b4..6f6da74 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+ * YAFFS: Yet another FFS. A NAND-flash specific file system. 
  *
- * Copyright (C) 2002-2007 Aleph One Ltd.
+ * Copyright (C) 2002 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -9,11 +9,10 @@
  * 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.
+ *
  */
 
-/*
-* Test code for the "direct" interface. 
-*/
+
 
 
 #include <stdio.h>
@@ -125,9 +124,7 @@ int check_pattern_file(char *fn)
 int dump_file_data(char *fn)
 {
        int h;
-       int marker;
        int i = 0;
-       int size;
        int ok = 1;
        unsigned char b;
        
@@ -178,6 +175,7 @@ void create_file_of_size(const char *fn,int syze)
 {
        int h;
        int n;
+       int result;
        
        char xx[200];
        
@@ -188,7 +186,10 @@ void create_file_of_size(const char *fn,int syze)
        while (iterations > 0)
        {
                sprintf(xx,"%s %8d",fn,iterations);
-               yaffs_write(h,xx,strlen(xx));
+               n = strlen(xx);
+               result = yaffs_write(h,xx,n);
+               if(result != n)
+                       printf("Wrote %d, should have been %d\n",result,n);
                iterations--;
        }
        yaffs_close (h);
@@ -197,7 +198,7 @@ void create_file_of_size(const char *fn,int syze)
 void verify_file_of_size(const char *fn,int syze)
 {
        int h;
-       int n;
+       int result;
        
        char xx[200];
        char yy[200];
@@ -212,11 +213,11 @@ void verify_file_of_size(const char *fn,int syze)
                sprintf(xx,"%s %8d",fn,iterations);
                l = strlen(xx);
                
-               yaffs_read(h,yy,l);
+               result = yaffs_read(h,yy,l);
                yy[l] = 0;
                
                if(strcmp(xx,yy)){
-                       printf("=====>>>>> verification of file %s failed near position %d\n",fn,yaffs_lseek(h,0,SEEK_CUR));
+                       printf("=====>>>>> verification of file %s failed near position %lld\n",fn,(long long)yaffs_lseek(h,0,SEEK_CUR));
                }
                iterations--;
        }
@@ -226,8 +227,6 @@ void verify_file_of_size(const char *fn,int syze)
 void create_resized_file_of_size(const char *fn,int syze1,int reSyze, int syze2)
 {
        int h;
-       int n;
-       
        
        int iterations;
        
@@ -240,7 +239,7 @@ void create_resized_file_of_size(const char *fn,int syze1,int reSyze, int syze2)
                iterations--;
        }
        
-       yaffs_truncate(h,reSyze);
+       yaffs_ftruncate(h,reSyze);
        
        yaffs_lseek(h,0,SEEK_SET);
        iterations = (syze2 + strlen(fn) -1)/ strlen(fn);
@@ -375,7 +374,7 @@ void scan_pattern_test(const char *path, int fsize, int niterations)
        }
 }
 
-void fill_disk(char *path,int nfiles)
+void fill_disk(const char *path,int nfiles)
 {
        int h;
        int n;
@@ -401,7 +400,7 @@ void fill_disk(char *path,int nfiles)
        }
 }
 
-void fill_disk_and_delete(char *path, int nfiles, int ncycles)
+void fill_disk_and_delete(const char *path, int nfiles, int ncycles)
 {
        int i,j;
        char str[50];
@@ -883,18 +882,12 @@ int huge_directory_test_on_path(char *path)
 
        int f;
        int i;
-       int r;
+
        int total = 0;
        int lastTotal = 0;
-       char buffer[20];
        
        char str[100];
-       char name[100];
-       char name2[100];
-       
-       int h;
-       mode_t temp_mode;
-       struct yaffs_stat ystat;
+
        
        yaffs_StartUp();
        
@@ -939,6 +932,7 @@ int huge_directory_test_on_path(char *path)
 
 int yaffs_scan_test(const char *path)
 {
+       return 0;
 }
 
 
@@ -1012,7 +1006,7 @@ int resize_stress_test(const char *path)
                                
                                syz -= 500;
                                if(syz < 0) syz = 0;
-                               yaffs_truncate(a,syz);
+                               yaffs_ftruncate(a,syz);
                                
                        }
                        else
@@ -1041,6 +1035,7 @@ int resize_stress_test_no_grow_complex(const char *path,int iters)
    
    char abuffer[1000];
    char bbuffer[1000];
+
    
    yaffs_StartUp();
    
@@ -1079,7 +1074,7 @@ int resize_stress_test_no_grow_complex(const char *path,int iters)
                                
                                        syz -= 2050;
                                        if(syz < 0) syz = 0;
-                                       yaffs_truncate(a,syz);
+                                       yaffs_ftruncate(a,syz);
                                        syz = yaffs_lseek(a,0,SEEK_END);
                                        printf("shrink to %d\n",syz);
                                }
@@ -1096,7 +1091,8 @@ int resize_stress_test_no_grow_complex(const char *path,int iters)
                        
                                        
                }
-               printf("file size is %d\n",yaffs_lseek(a,0,SEEK_END));
+               
+               printf("file size is %lld\n",(long long)yaffs_lseek(a,0,SEEK_END));
 
    }
    
@@ -1152,7 +1148,7 @@ int resize_stress_test_no_grow(const char *path,int iters)
                                
                                        syz -= 2050;
                                        if(syz < 0) syz = 0;
-                                       yaffs_truncate(a,syz);
+                                       yaffs_ftruncate(a,syz);
                                        syz = yaffs_lseek(a,0,SEEK_END);
                                        printf("shrink to %d\n",syz);
                                }
@@ -1169,7 +1165,7 @@ int resize_stress_test_no_grow(const char *path,int iters)
                        
                                        
                }
-               printf("file size is %d\n",yaffs_lseek(a,0,SEEK_END));
+               printf("file size is %lld\n",(long long)yaffs_lseek(a,0,SEEK_END));
 
    }
    
@@ -1253,7 +1249,6 @@ int cache_bypass_bug_test(void)
        // This bug has been fixed.
        
        int a;
-       int i;
        char buffer1[1000];
        char buffer2[1000];
        
@@ -1327,7 +1322,7 @@ int truncate_test(void)
        
        yaffs_write(a,"abcdefghijklmnopqrstuvwzyz",26);
        
-       yaffs_truncate(a,3);
+       yaffs_ftruncate(a,3);
        l= yaffs_lseek(a,0,SEEK_END);
        
        printf("truncated length is %d\n",l);
@@ -1374,13 +1369,10 @@ void lookup_test(const char *mountpt)
        int i;
        int h;
        char a[100];
-       char b[100];
        
 
        yaffs_DIR *d;
        yaffs_dirent *de;
-       struct yaffs_stat s;
-       char str[100];
 
        yaffs_StartUp();
        
@@ -1441,11 +1433,7 @@ void link_test(const char *mountpt)
        char a[100];
        char b[100];
        char c[100];
-       
-       int  f0;
-       int f1;
-       int f2;
-       int f3;
+
        sprintf(a,"%s/aaa",mountpt);
        sprintf(b,"%s/bbb",mountpt);
        sprintf(c,"%s/ccc",mountpt);
@@ -1482,7 +1470,6 @@ void freespace_test(const char *mountpt)
        int i;
        int h;
        char a[100];
-       char b[100];
        
        int  f0;
        int f1;
@@ -1741,8 +1728,6 @@ void multi_mount_test(const char *mountpt,int nmounts)
 {
 
        char a[30];
-       char b[30];
-       char c[30];
        
        int i;
        int j;
@@ -1773,12 +1758,18 @@ void multi_mount_test(const char *mountpt,int nmounts)
                
                sprintf(xx,"%s/1",a);
                h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
-               
+
+#if 0          
                for(j = 0; j < 200; j++){
                   yaffs_write(h0,xx,1000);
                   yaffs_write(h1,xx,1000);
                }
-               
+#else
+               while(yaffs_write(h0,xx,1000) > 0){
+                  
+                  yaffs_write(h1,xx,1000);
+               }
+#endif
                len0 = yaffs_lseek(h0,0,SEEK_END);
                len1 = yaffs_lseek(h1,0,SEEK_END);
                
@@ -1791,7 +1782,7 @@ void multi_mount_test(const char *mountpt,int nmounts)
                }
                
                
-               yaffs_truncate(h0,0);
+       //      yaffs_truncate(h0,0);
                yaffs_close(h0);
                yaffs_close(h1);
                
@@ -1808,8 +1799,6 @@ void small_mount_test(const char *mountpt,int nmounts)
 {
 
        char a[30];
-       char b[30];
-       char c[30];
        
        int i;
        int j;
@@ -1885,17 +1874,12 @@ void small_overwrite_test(const char *mountpt,int nmounts)
 {
 
        char a[30];
-       char b[30];
-       char c[30];
-       
        int i;
        int j;
 
        int h0;
        int h1;
-       int len0;
-       int len1;
-       int nread;
+
        
        sprintf(a,"%s/a",mountpt);
 
@@ -1921,7 +1905,7 @@ void small_overwrite_test(const char *mountpt,int nmounts)
                h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
                
                for(j = 0; j < 1000000; j+=1000){
-                       yaffs_truncate(h0,j);
+                       yaffs_ftruncate(h0,j);
                        yaffs_lseek(h0,j,SEEK_SET);
                        yaffs_write(h0,xx,7000);
                        yaffs_write(h1,xx,7000);
@@ -1941,6 +1925,44 @@ void small_overwrite_test(const char *mountpt,int nmounts)
 }
 
 
+void seek_overwrite_test(const char *mountpt,int nmounts)
+{
+
+       char a[30];
+       
+       int i;
+       int j;
+
+       int h0;
+
+       
+       sprintf(a,"%s/f",mountpt);
+
+       yaffs_StartUp();
+       
+       yaffs_mount(mountpt);
+       
+       
+       for(i = 0; i < nmounts; i++){
+               
+               h0 = yaffs_open(a, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
+                       
+               for(j = 0; j < 100000; j++){
+                       yaffs_lseek(h0,0,SEEK_SET);
+                       yaffs_write(h0,xx,5000);
+                       yaffs_lseek(h0,0x100000,SEEK_SET);
+                       yaffs_write(h0,xx,5000);
+                       
+                       if(early_exit)
+                               exit(0);
+               }
+               
+               yaffs_close(h0);
+               
+       }
+}
+
+
 void yaffs_touch(const char *fn)
 {
        yaffs_chmod(fn, S_IREAD | S_IWRITE);
@@ -2014,7 +2036,7 @@ int make_file2(const char *name1, const char *name2,int syz)
        }
        yaffs_close(h1);
        yaffs_close(h2);
-       
+       return 0;
 }
 
 
@@ -2027,10 +2049,8 @@ void checkpoint_upgrade_test(const char *mountpt,int nmounts)
        char b[50];
        char c[50];
        char d[50];
-       
-       int i;
+
        int j;
-       int h;
        
        sprintf(a,"%s/a",mountpt);
        
@@ -2087,8 +2107,7 @@ void huge_array_test(const char *mountpt,int n)
 
        
        int i;
-       int j;
-       int h;
+       int space;
        
        int fnum;
        
@@ -2104,10 +2123,10 @@ void huge_array_test(const char *mountpt,int n)
                n--;
                fnum = 0;
                printf("\n\n START run\n\n");
-               while(yaffs_freespace(mountpt) > 25000000){
+               while((space = yaffs_freespace(mountpt)) > 25000000){
                        sprintf(a,"%s/file%d",mountpt,fnum);
                        fnum++;
-                       printf("create file %s\n",a);
+                       printf("create file %s, free space %d\n",a,space);
                        create_file_of_size(a,10000000);
                        printf("verifying file %s\n",a);
                        verify_file_of_size(a,10000000);
@@ -2153,7 +2172,7 @@ void random_truncate(int h, char * name)
        flen = yaffs_lseek(h,0,SEEK_END);
        if(n > flen)
                n = flen / 2;
-       yaffs_truncate(name,n);
+       yaffs_ftruncate(h,n);
        yaffs_lseek(h,n,SEEK_SET);
 }
 
@@ -2167,10 +2186,8 @@ void random_small_file_test(const char *mountpt,int iterations)
        
        int i;
        int n;
-       int j;
        int h[NSMALLFILES];
        int r;
-       int fnum;
        
        
        yaffs_StartUp();
@@ -2189,7 +2206,7 @@ void random_small_file_test(const char *mountpt,int iterations)
                        
                        if(strlen(a[i]) == 0){
                                sprintf(a[i],"%s/%dx%d",mountpt,n,i);
-                               h[i] = yaffs_open(a,O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
+                               h[i] = yaffs_open(a[i],O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
                        }
                        
                        if(h[i] < -1)
@@ -2249,6 +2266,10 @@ int main(int argc, char *argv[])
        //short_scan_test("/flash/flash",40000,200);
          //small_mount_test("/flash/flash",1000);
          //small_overwrite_test("/flash/flash",1000);
+         //seek_overwrite_test("/flash/flash",1000);
+        //checkpoint_fill_test("/flash/flash",20);
+        //checkpoint_upgrade_test("/flash/flash",20);
+         //small_overwrite_test("/flash/flash",1000);
          //checkpoint_fill_test("/flash/flash",20);
        // random_small_file_test("/flash/flash",10000);
         // huge_array_test("/flash/flash",10);
index 30323ad..359a523 100644 (file)
 #
 # NB Warning this Makefile does not include header dependencies.
 #
-# $Id: Makefile,v 1.1 2007-10-16 00:46:33 charles Exp $
+# $Id: Makefile,v 1.2 2008-05-05 07:58:58 charles Exp $
 
 #EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC
 
-CFLAGS =    -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2 -g $(EXTRA_COMPILE_FLAGS) -DNO_Y_INLINE
+CFLAGS =    -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2 -DNO_Y_INLINE
+CFLAGS+=    -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES
+CFLAGS+=    -Wall -g $(EXTRA_COMPILE_FLAGS)
 CFLAGS+=    -fstack-check -O0
 
 #CFLAGS+=   -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations
@@ -42,7 +44,7 @@ YAFFSSYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h ya
           yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h  yaffs_nandemul2k.h \
           yaffs_nand.c yaffs_nand.h \
           yaffs_tagsvalidity.c yaffs_tagsvalidity.h yaffs_checkptrw.h yaffs_checkptrw.c \
-          yaffs_qsort.c yaffs_qsort.h
+          yaffs_qsort.c yaffs_qsort.h yaffs_getblockinfo.h
 
 YAFFSDIRECTSYMLINKS =  yaffscfg2k.c yaffs_fileem2k.c yaffsfs.c yaffs_flashif.h \
                       yaffs_fileem2k.h yaffsfs.h yaffs_malloc.h yaffs_ramdisk.h ydirectenv.h \
index 1e110b9..26a8536 100644 (file)
@@ -67,6 +67,7 @@
 #include <unistd.h>
 #include <stdarg.h>
 #include <errno.h>
+#include <time.h>
 
 #include "yaffsfs.h"
 
@@ -421,14 +422,14 @@ check_trunc_hack(void)
 {
        struct yaffs_stat statbuf;
 
-       yaffs_truncate(fd, (off_t)0);
-       yaffs_truncate(fd, (off_t)100000);
+       yaffs_ftruncate(fd, (off_t)0);
+       yaffs_ftruncate(fd, (off_t)100000);
        yaffs_fstat(fd, &statbuf);
        if (statbuf.st_size != (off_t)100000) {
                prt("no extend on truncate! not posix!\n");
                exit(130);
        }
-       yaffs_truncate(fd, (off_t)0);
+       yaffs_ftruncate(fd, (off_t)0);
 }
 
 
@@ -579,7 +580,7 @@ dotruncate(unsigned size)
            (debug && (monitorstart == -1 || monitorend == -1 ||
                       size <= monitorend)))
                prt("%lu trunc\tfrom 0x%x to 0x%x\n", testcalls, oldsize, size);
-       if (yaffs_truncate(fd, (off_t)size) == -1) {
+       if (yaffs_ftruncate(fd, (off_t)size) == -1) {
                prt("ftruncate1: %x\n", size);
                prterr("dotruncate: ftruncate");
                report_failure(160);
@@ -605,7 +606,7 @@ writefileimage()
                            iret, (unsigned long long)file_size);
                report_failure(172);
        }
-       if (lite ? 0 : yaffs_truncate(fd, file_size) == -1) {
+       if (lite ? 0 : yaffs_ftruncate(fd, file_size) == -1) {
                prt("ftruncate2: %llx\n", (unsigned long long)file_size);
                prterr("writefileimage: ftruncate");
                report_failure(173);
index 1e2cd6b..cb94486 100644 (file)
@@ -16,7 +16,7 @@
  * This is only intended as test code to test persistence etc.
  */
 
-const char *yaffs_flashif_c_version = "$Id: yaffs_fileem2k.c,v 1.12 2007-02-14 01:09:06 wookey Exp $";
+const char *yaffs_flashif_c_version = "$Id: yaffs_fileem2k.c,v 1.13 2008-05-05 07:58:58 charles Exp $";
 
 
 #include "yportenv.h"
@@ -103,16 +103,10 @@ static int GetBlockFileHandle(int n)
 static int  CheckInit(void)
 {
        static int initialised = 0;
-       int h;
        int i;
 
-       
-       off_t fSize;
-       off_t requiredSize;
-       int written;
        int blk;
-       
-       yflash_Page p;
+
        
        if(initialised) 
        {
@@ -144,7 +138,7 @@ int yflash_GetNumberOfBlocks(void)
        return filedisk.nBlocks;
 }
 
-int yflash_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags)
+int yflash_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_ExtendedTags *tags)
 {
        int written;
        int pos;
@@ -158,90 +152,114 @@ int yflash_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8
        CheckInit();
        
        
-       
-       if(data)
-       {
-               pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
-               h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
+       if(dev->inbandTags){
                
-               lseek(h,pos,SEEK_SET);
-               nRead =  read(h, localBuffer,dev->nDataBytesPerChunk);
-               for(i = error = 0; i < dev->nDataBytesPerChunk && !error; i++){
-                       if(localBuffer[i] != 0xFF){
-                               printf("nand simulation: chunk %d data byte %d was %0x2\n",
-                                       chunkInNAND,i,localBuffer[i]);
-                               error = 1;
-                       }
-               }
+               yaffs_PackedTags2TagsPart * pt2tp;
+               pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
+               yaffs_PackTags2TagsPart(pt2tp,tags);
                
-               for(i = 0; i < dev->nDataBytesPerChunk; i++)
-                 localBuffer[i] &= data[i];
-                 
-               if(memcmp(localBuffer,data,dev->nDataBytesPerChunk))
-                       printf("nand simulator: data does not match\n");
-                       
+               pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
+               h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
+                                                       
                lseek(h,pos,SEEK_SET);
-               written = write(h,localBuffer,dev->nDataBytesPerChunk);
+               written = write(h,data,dev->totalBytesPerChunk);
+
                
                if(yaffs_testPartialWrite){
                        close(h);
                        exit(1);
                }
                
-#ifdef SIMULATE_FAILURES
-                       if((chunkInNAND >> 6) == 100) 
-                         written = 0;
-
-                       if((chunkInNAND >> 6) == 110) 
-                         written = 0;
-#endif
+               if(written != dev->totalBytesPerChunk) return YAFFS_FAIL;
 
 
-               if(written != dev->nDataBytesPerChunk) return YAFFS_FAIL;
        }
        
-       if(tags)
-       {
-               pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE ;
-               h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
-               
-               lseek(h,pos,SEEK_SET);
-
-               if( 0 && dev->isYaffs2)
+       else {
+       
+               if(data)
                {
+                       pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
+                       h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
+               
+                       lseek(h,pos,SEEK_SET);
+                       nRead =  read(h, localBuffer,dev->nDataBytesPerChunk);
+                       for(i = error = 0; i < dev->nDataBytesPerChunk && !error; i++){
+                               if(localBuffer[i] != 0xFF){
+                                       printf("nand simulation: chunk %d data byte %d was %0x2\n",
+                                               chunkInNAND,i,localBuffer[i]);
+                                       error = 1;
+                               }
+                       }
+               
+                       for(i = 0; i < dev->nDataBytesPerChunk; i++)
+                       localBuffer[i] &= data[i];
+                 
+                       if(memcmp(localBuffer,data,dev->nDataBytesPerChunk))
+                               printf("nand simulator: data does not match\n");
                        
-                       written = write(h,tags,sizeof(yaffs_ExtendedTags));
-                       if(written != sizeof(yaffs_ExtendedTags)) return YAFFS_FAIL;
+                       lseek(h,pos,SEEK_SET);
+                       written = write(h,localBuffer,dev->nDataBytesPerChunk);
+               
+                       if(yaffs_testPartialWrite){
+                               close(h);
+                               exit(1);
+                       }
+               
+#ifdef SIMULATE_FAILURES
+                               if((chunkInNAND >> 6) == 100) 
+                               written = 0;
+
+                               if((chunkInNAND >> 6) == 110) 
+                               written = 0;
+#endif
+
+
+                       if(written != dev->nDataBytesPerChunk) return YAFFS_FAIL;
                }
-               else
+       
+               if(tags)
                {
-                       yaffs_PackedTags2 pt;
-                       yaffs_PackTags2(&pt,tags);
-                       __u8 * ptab = (__u8 *)&pt;
+                       pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE ;
+                       h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
+               
+                       lseek(h,pos,SEEK_SET);
 
-                       nRead = read(h,localBuffer,sizeof(pt));
-                       for(i = error = 0; i < sizeof(pt) && !error; i++){
-                               if(localBuffer[i] != 0xFF){
-                                       printf("nand simulation: chunk %d oob byte %d was %0x2\n",
-                                               chunkInNAND,i,localBuffer[i]);
-                                               error = 1;
-                               }
+                       if( 0 && dev->isYaffs2)
+                       {
+                       
+                               written = write(h,tags,sizeof(yaffs_ExtendedTags));
+                               if(written != sizeof(yaffs_ExtendedTags)) return YAFFS_FAIL;
                        }
+                       else
+                       {
+                               yaffs_PackedTags2 pt;
+                               yaffs_PackTags2(&pt,tags);
+                               __u8 * ptab = (__u8 *)&pt;
+
+                               nRead = read(h,localBuffer,sizeof(pt));
+                               for(i = error = 0; i < sizeof(pt) && !error; i++){
+                                       if(localBuffer[i] != 0xFF){
+                                               printf("nand simulation: chunk %d oob byte %d was %0x2\n",
+                                                       chunkInNAND,i,localBuffer[i]);
+                                                       error = 1;
+                                       }
+                               }
                
-                       for(i = 0; i < sizeof(pt); i++)
-                         localBuffer[i] &= ptab[i];
+                               for(i = 0; i < sizeof(pt); i++)
+                               localBuffer[i] &= ptab[i];
                         
-                       if(memcmp(localBuffer,&pt,sizeof(pt)))
-                               printf("nand sim: tags corruption\n");
+                               if(memcmp(localBuffer,&pt,sizeof(pt)))
+                                       printf("nand sim: tags corruption\n");
                                
-                       lseek(h,pos,SEEK_SET);
+                               lseek(h,pos,SEEK_SET);
                        
-                       written = write(h,localBuffer,sizeof(pt));
-                       if(written != sizeof(pt)) return YAFFS_FAIL;
+                               written = write(h,localBuffer,sizeof(pt));
+                               if(written != sizeof(pt)) return YAFFS_FAIL;
+                       }
                }
-       }
        
-
+       }
        return YAFFS_OK;        
 
 }
@@ -268,6 +286,9 @@ int yflash_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *da
        int nread;
        int pos;
        int h;
+       int localData = 0;
+       int retval = YAFFS_OK;
+       int nRead;
        
        T(YAFFS_TRACE_MTD,(TSTR("read chunk %d data %x tags %x" TENDSTR),chunkInNAND,(unsigned)data, (unsigned)tags));
        
@@ -275,68 +296,107 @@ int yflash_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *da
        
        
        
-       if(data)
-       {
+       
+       if(dev->inbandTags){
+               /* Got to suck the tags out of the data area */
+               if(!data) {
+                       localData=1;
+                       data = yaffs_GetTempBuffer(dev,__LINE__);
+               }
 
+               
+               yaffs_PackedTags2TagsPart * pt2tp;
+               pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
+
+               
                pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
-               h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];             
-               lseek(h,pos,SEEK_SET);
-               nread = read(h,data,dev->nDataBytesPerChunk);
+               h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
                
+               lseek(h,pos,SEEK_SET);
+
+               nRead = read(h, data,dev->totalBytesPerChunk);
+
+               yaffs_UnpackTags2TagsPart(tags,pt2tp);
                
-               if(nread != dev->nDataBytesPerChunk) return YAFFS_FAIL;
+               if(nread != dev->totalBytesPerChunk)
+                       retval = YAFFS_FAIL;
+                       
+               if(localData)
+                       yaffs_ReleaseTempBuffer(dev,data,__LINE__);
+
+
+
        }
        
-       if(tags)
-       {
-               pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE;
-               h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];             
-               lseek(h,pos,SEEK_SET);
+       else {
+       
+               if(data)
+               {
 
-               if(0 && dev->isYaffs2)
+                       pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
+                       h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];             
+                       lseek(h,pos,SEEK_SET);
+                       nread = read(h,data,dev->nDataBytesPerChunk);
+               
+               
+                       if(nread != dev->nDataBytesPerChunk) 
+                               retval = YAFFS_FAIL;
+               }
+       
+               if(tags)
                {
-                       nread= read(h,tags,sizeof(yaffs_ExtendedTags));
-                       if(nread != sizeof(yaffs_ExtendedTags)) return YAFFS_FAIL;
-                       if(yaffs_CheckAllFF((__u8 *)tags,sizeof(yaffs_ExtendedTags)))
+                       pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE;
+                       h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];             
+                       lseek(h,pos,SEEK_SET);
+
+                       if(0 && dev->isYaffs2)
                        {
-                               yaffs_InitialiseTags(tags);
+                               nread= read(h,tags,sizeof(yaffs_ExtendedTags));
+                               if(nread != sizeof(yaffs_ExtendedTags))
+                                        retval =  YAFFS_FAIL;
+                               if(yaffs_CheckAllFF((__u8 *)tags,sizeof(yaffs_ExtendedTags)))
+                               {
+                                       yaffs_InitialiseTags(tags);
+                               }
+                               else
+                               {
+                                       tags->chunkUsed = 1;
+                               }
                        }
                        else
                        {
-                               tags->chunkUsed = 1;
-                       }
-               }
-               else
-               {
-                       yaffs_PackedTags2 pt;
-                       nread= read(h,&pt,sizeof(pt));
-                       yaffs_UnpackTags2(tags,&pt);
+                               yaffs_PackedTags2 pt;
+                               nread= read(h,&pt,sizeof(pt));
+                               yaffs_UnpackTags2(tags,&pt);
 #ifdef SIMULATE_FAILURES
-                       if((chunkInNAND >> 6) == 100) {
-                           if(fail300 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){
-                              tags->eccResult = YAFFS_ECC_RESULT_FIXED;
-                              fail300 = 0;
-                           }
-                           
-                       }
-                       if((chunkInNAND >> 6) == 110) {
-                           if(fail320 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){
-                              tags->eccResult = YAFFS_ECC_RESULT_FIXED;
-                              fail320 = 0;
-                           }
-                       }
+                               if((chunkInNAND >> 6) == 100) {
+                                       if(fail300 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){
+                                               tags->eccResult = YAFFS_ECC_RESULT_FIXED;
+                                               fail300 = 0;
+                                       }
+                               }
+                               
+                               if((chunkInNAND >> 6) == 110) {
+                                       if(fail320 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){
+                                               tags->eccResult = YAFFS_ECC_RESULT_FIXED;
+                                               fail320 = 0;
+                                       }
+                               }
 #endif
-                       if(failRead10>0 && chunkInNAND == 10){
-                               failRead10--;
-                               nread = 0;
-                       }
+                               if(failRead10>0 && chunkInNAND == 10){
+                                       failRead10--;
+                                       nread = 0;
+                               }
                        
-                       if(nread != sizeof(pt)) return YAFFS_FAIL;
+                               if(nread != sizeof(pt))
+                                       retval = YAFFS_FAIL;
+                       }
                }
        }
        
 
-       return YAFFS_OK;        
+
+       return retval;  
 
 }
 
@@ -413,7 +473,7 @@ int yflash_InitialiseNAND(yaffs_Device *dev)
 
 
 
-int yflash_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber)
+int yflash_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, __u32 *sequenceNumber)
 {
        yaffs_ExtendedTags tags;
        int chunkNo;
index f7f4e42..a6bc65d 100644 (file)
 #include "yaffs_guts.h"
 int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
 int yflash_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare);
-int yflash_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags);
+int yflash_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_ExtendedTags *tags);
 int yflash_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare);
 int yflash_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags);
 int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
 int yflash_InitialiseNAND(yaffs_Device *dev);
 int yflash_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
-int yflash_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber);
+int yflash_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, __u32 *sequenceNumber);
 
 #endif
index 3cf054a..fa76b6c 100644 (file)
@@ -18,7 +18,7 @@
  * Use this with dev->useNANDECC enabled, then ECC overheads are not required.
  */
 
-const char *yaffs_ramdisk_c_version = "$Id: yaffs_ramdisk.c,v 1.4 2007-02-14 01:09:06 wookey Exp $";
+const char *yaffs_ramdisk_c_version = "$Id: yaffs_ramdisk.c,v 1.5 2008-05-05 07:58:58 charles Exp $";
 
 
 #include "yportenv.h"
@@ -118,7 +118,7 @@ static int  CheckInit(yaffs_Device *dev)
        return 1;
 }
 
-int yramdisk_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags)
+int yramdisk_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_ExtendedTags *tags)
 {
        int blk;
        int pg;
index 045ab42..4565998 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "yaffs_guts.h"
 int yramdisk_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
-int yramdisk_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags);
+int yramdisk_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_ExtendedTags *tags);
 int yramdisk_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags);
 int yramdisk_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
 int yramdisk_InitialiseNAND(yaffs_Device *dev);
index c01bc97..b496cc6 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 
-const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.3 2007-02-14 01:09:06 wookey Exp $";
+const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.4 2008-05-05 07:58:58 charles Exp $";
 
 #ifndef __KERNEL__
 #define CONFIG_YAFFS_RAM_ENABLED
@@ -190,7 +190,7 @@ static int  CheckInit(void)
        return 1;
 }
 
-int nandemul2k_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags)
+int nandemul2k_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_ExtendedTags *tags)
 {
        int blk;
        int pg;
@@ -327,7 +327,7 @@ int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
        
 }
 
-int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber)
+int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, __u32  *sequenceNumber)
 {
        yaffs_ExtendedTags tags;
        int chunkNo;
index 2c95409..2f7442e 100644 (file)
@@ -34,19 +34,22 @@ unsigned yaffs_traceMask =
        YAFFS_TRACE_ALLOCATE | 
        YAFFS_TRACE_CHECKPOINT |
        YAFFS_TRACE_BAD_BLOCKS |
-       YAFFS_TRACE_VERIFY |
-       YAFFS_TRACE_VERIFY_NAND |
-       YAFFS_TRACE_VERIFY_FULL |
-//     (~0) |
        
        0;
         
 
+static int yaffsfs_lastError;
 
 void yaffsfs_SetError(int err)
 {
        //Do whatever to set error
-       errno = err;
+       yaffsfs_lastError = err;
+}
+
+
+int yaffsfs_GetLastError(void)
+{
+       return yaffsfs_lastError;
 }
 
 void yaffsfs_Lock(void)
@@ -69,7 +72,7 @@ static size_t malloc_limit = 0 & 6000000;
 
 void *yaffs_malloc(size_t size)
 {
-       size_t this;
+       void * this;
        if(yaffs_kill_alloc)
                return NULL;
        if(malloc_limit && malloc_limit <(total_malloced + size) )
@@ -121,6 +124,7 @@ static yaffsfs_DeviceConfiguration yaffsfs_config[] = {
        { "/flash/boot", &bootDev},
        { "/flash/flash", &flashDev},
        { "/ram2k", &ram2kDev},
+       { "/flash/bigblock", &flashDev},
        {(void *)0,(void *)0} /* Null entry to terminate list */
 #endif
 };
@@ -135,7 +139,7 @@ int yaffs_StartUp(void)
        // Set up devices
        // /ram
        memset(&ramDev,0,sizeof(ramDev));
-       ramDev.nDataBytesPerChunk = 512;
+       ramDev.totalBytesPerChunk = 512;
        ramDev.nChunksPerBlock = 32;
        ramDev.nReservedBlocks = 2; // Set this smaller for RAM
        ramDev.startBlock = 0; // Can use block 0
@@ -150,7 +154,7 @@ int yaffs_StartUp(void)
 
        // /boot
        memset(&bootDev,0,sizeof(bootDev));
-       bootDev.nDataBytesPerChunk = 512;
+       bootDev.totalBytesPerChunk = 512;
        bootDev.nChunksPerBlock = 32;
        bootDev.nReservedBlocks = 5;
        bootDev.startBlock = 0; // Can use block 0
@@ -173,9 +177,10 @@ int yaffs_StartUp(void)
        // 2kpage/64chunk per block/128MB device
        memset(&flashDev,0,sizeof(flashDev));
 
-       flashDev.nDataBytesPerChunk = 2048;
+       flashDev.totalBytesPerChunk = 512;
        flashDev.nChunksPerBlock = 64;
        flashDev.nReservedBlocks = 5;
+       flashDev.inbandTags = 1;
        //flashDev.checkpointStartBlock = 1;
        //flashDev.checkpointEndBlock = 20;
        flashDev.startBlock = 0;
@@ -198,7 +203,7 @@ int yaffs_StartUp(void)
        // 2kpage/64chunk per block/128MB device
        memset(&ram2kDev,0,sizeof(ram2kDev));
 
-       ram2kDev.nDataBytesPerChunk = nandemul2k_GetBytesPerChunk();
+       ram2kDev.totalBytesPerChunk = nandemul2k_GetBytesPerChunk();
        ram2kDev.nChunksPerBlock = nandemul2k_GetChunksPerBlock();
        ram2kDev.nReservedBlocks = 5;
        ram2kDev.startBlock = 0; // First block after /boot
index dc6dab9..2b9d0bc 100644 (file)
 #endif
 
 
-const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.18 2007-07-18 19:40:38 charles Exp $";
+const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.19 2008-05-05 07:58:58 charles Exp $";
 
 // configurationList is the list of devices that are supported
 static yaffsfs_DeviceConfiguration *yaffsfs_configurationList;
 
 
 /* Some forward references */
-static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const char *path, int symDepth);
+static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const YCHAR *path, int symDepth);
 static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj);
 
 
@@ -137,22 +137,95 @@ static int yaffsfs_PutHandle(int handle)
 // Stuff to search for a directory from a path
 
 
-int yaffsfs_Match(char a, char b)
+int yaffsfs_Match(YCHAR a, YCHAR b)
 {
        // case sensitive
        return (a == b);
 }
 
+int yaffsfs_IsPathDivider(YCHAR ch)
+{
+       YCHAR *str = YAFFS_PATH_DIVIDERS;
+       
+       while(*str){
+               if(*str == ch)
+                       return 1;
+               str++;
+       }
+       
+       return 0;
+}
+
 // yaffsfs_FindDevice
 // yaffsfs_FindRoot
 // Scan the configuration list to find the root.
 // Curveballs: Should match paths that end in '/' too
 // Curveball2 Might have "/x/ and "/x/y". Need to return the longest match
-static yaffs_Device *yaffsfs_FindDevice(const char *path, char **restOfPath)
+static yaffs_Device *yaffsfs_FindDevice(const YCHAR *path, YCHAR **restOfPath)
+{
+       yaffsfs_DeviceConfiguration *cfg = yaffsfs_configurationList;
+       const YCHAR *leftOver;
+       const YCHAR *p;
+       yaffs_Device *retval = NULL;
+       int thisMatchLength;
+       int longestMatch = -1;
+       
+       // Check all configs, choose the one that:
+       // 1) Actually matches a prefix (ie /a amd /abc will not match
+       // 2) Matches the longest.
+       while(cfg && cfg->prefix && cfg->dev)
+       {
+               leftOver = path;
+               p = cfg->prefix;
+               thisMatchLength = 0;
+               
+               
+               // Strip off any leading /'s
+               
+               while(yaffsfs_IsPathDivider(*p))
+                       p++;
+
+               while(yaffsfs_IsPathDivider(*leftOver))
+                       leftOver++;
+                       
+               while(*p && *leftOver && 
+                     yaffsfs_Match(*p,*leftOver))
+               {
+                       p++;
+                       leftOver++;
+                       thisMatchLength++;
+                       
+                       // Skip over any multiple /'s to treat them as one or
+                       // skip over a trailling / in the prefix, but not the matching string
+                       while(yaffsfs_IsPathDivider(*p) &&
+                             (yaffsfs_IsPathDivider(*(p+1)) || !(*(p+1))))
+                             p++;                      
+
+                       // Only skip over multiple /'s
+                       while(yaffsfs_IsPathDivider(*leftOver) &&
+                             yaffsfs_IsPathDivider(*(leftOver+1)))
+                             leftOver++;                       
+               }
+               
+               if((!*p ) &&
+                  (!*leftOver || yaffsfs_IsPathDivider(*leftOver)) && // no more in this path name part
+                  (thisMatchLength > longestMatch))
+               {
+                       // Matched prefix
+                       *restOfPath = (YCHAR *)leftOver;
+                       retval = cfg->dev;
+                       longestMatch = thisMatchLength;
+               }
+               cfg++;
+       }
+       return retval;
+}
+#if 0
+static yaffs_Device *yaffsfs_FindDevice(const YCHAR *path, YCHAR **restOfPath)
 {
        yaffsfs_DeviceConfiguration *cfg = yaffsfs_configurationList;
-       const char *leftOver;
-       const char *p;
+       const YCHAR *leftOver;
+       const YCHAR *p;
        yaffs_Device *retval = NULL;
        int thisMatchLength;
        int longestMatch = -1;
@@ -167,7 +240,7 @@ static yaffs_Device *yaffsfs_FindDevice(const char *path, char **restOfPath)
                thisMatchLength = 0;
                
                while(*p &&  //unmatched part of prefix 
-                     strcmp(p,"/") && // the rest of the prefix is not / (to catch / at end)
+                     !(yaffsfs_IsPathDivider(*p) && (p[1] == 0)) && // the rest of the prefix is not / (to catch / at end)
                      *leftOver && 
                      yaffsfs_Match(*p,*leftOver))
                {
@@ -175,12 +248,14 @@ static yaffs_Device *yaffsfs_FindDevice(const char *path, char **restOfPath)
                        leftOver++;
                        thisMatchLength++;
                }
-               if((!*p || strcmp(p,"/") == 0) &&      // end of prefix
-                  (!*leftOver || *leftOver == '/') && // no more in this path name part
+               
+
+               if((!*p || (yaffsfs_IsPathDivider(*p) && (p[1] == 0))) &&      // end of prefix
+                  (!*leftOver || yaffsfs_IsPathDivider(*leftOver)) && // no more in this path name part
                   (thisMatchLength > longestMatch))
                {
                        // Matched prefix
-                       *restOfPath = (char *)leftOver;
+                       *restOfPath = (YCHAR *)leftOver;
                        retval = cfg->dev;
                        longestMatch = thisMatchLength;
                }
@@ -188,8 +263,9 @@ static yaffs_Device *yaffsfs_FindDevice(const char *path, char **restOfPath)
        }
        return retval;
 }
+#endif
 
-static yaffs_Object *yaffsfs_FindRoot(const char *path, char **restOfPath)
+static yaffs_Object *yaffsfs_FindRoot(const YCHAR *path, YCHAR **restOfPath)
 {
 
        yaffs_Device *dev;
@@ -207,9 +283,9 @@ static yaffs_Object *yaffsfs_FollowLink(yaffs_Object *obj,int symDepth)
 
        while(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
        {
-               char *alias = obj->variant.symLinkVariant.alias;
+               YCHAR *alias = obj->variant.symLinkVariant.alias;
                                                
-               if(*alias == '/')
+               if(yaffsfs_IsPathDivider(*alias))
                {
                        // Starts with a /, need to scan from root up
                        obj = yaffsfs_FindObject(NULL,alias,symDepth++);
@@ -228,11 +304,11 @@ static yaffs_Object *yaffsfs_FollowLink(yaffs_Object *obj,int symDepth)
 // Parse a path to determine the directory and the name within the directory.
 //
 // eg. "/data/xx/ff" --> puts name="ff" and returns the directory "/data/xx"
-static yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const char *path,char **name,int symDepth)
+static yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const YCHAR *path,YCHAR **name,int symDepth)
 {
        yaffs_Object *dir;
-       char *restOfPath;
-       char str[YAFFS_MAX_NAME_LENGTH+1];
+       YCHAR *restOfPath;
+       YCHAR str[YAFFS_MAX_NAME_LENGTH+1];
        int i;
        
        if(symDepth > YAFFSFS_MAX_SYMLINK_DEREFERENCES)
@@ -243,7 +319,7 @@ static yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const char *
        if(startDir)
        {
                dir = startDir;
-               restOfPath = (char *)path;
+               restOfPath = (YCHAR *)path;
        }
        else
        {
@@ -255,7 +331,7 @@ static yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const char *
                // parse off /.
                // curve ball: also throw away surplus '/' 
                // eg. "/ram/x////ff" gets treated the same as "/ram/x/ff"
-               while(*restOfPath == '/')
+               while(yaffsfs_IsPathDivider(*restOfPath))
                {
                        restOfPath++; // get rid of '/'
                }
@@ -263,7 +339,7 @@ static yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const char *
                *name = restOfPath;
                i = 0;
                
-               while(*restOfPath && *restOfPath != '/')
+               while(*restOfPath && !yaffsfs_IsPathDivider(*restOfPath))
                {
                        if (i < YAFFS_MAX_NAME_LENGTH)
                        {
@@ -281,11 +357,11 @@ static yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const char *
                }
                else
                {
-                       if(strcmp(str,".") == 0)
+                       if(yaffs_strcmp(str,_Y(".")) == 0)
                        {
                                // Do nothing
                        }
-                       else if(strcmp(str,"..") == 0)
+                       else if(yaffs_strcmp(str,_Y("..")) == 0)
                        {
                                dir = dir->parent;
                        }
@@ -311,17 +387,17 @@ static yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const char *
        return NULL;
 }
 
-static yaffs_Object *yaffsfs_FindDirectory(yaffs_Object *relativeDirectory,const char *path,char **name,int symDepth)
+static yaffs_Object *yaffsfs_FindDirectory(yaffs_Object *relativeDirectory,const YCHAR *path,YCHAR **name,int symDepth)
 {
        return yaffsfs_DoFindDirectory(relativeDirectory,path,name,symDepth);
 }
 
 // yaffsfs_FindObject turns a path for an existing object into the object
 // 
-static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const char *path,int symDepth)
+static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const YCHAR *path,int symDepth)
 {
        yaffs_Object *dir;
-       char *name;
+       YCHAR *name;
        
        dir = yaffsfs_FindDirectory(relativeDirectory,path,&name,symDepth);
        
@@ -334,12 +410,39 @@ static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const c
 }
 
 
+int yaffs_dup(int fd)
+{
+       int newHandle = -1;
+       yaffsfs_Handle *oldPtr = NULL;
+       yaffsfs_Handle *newPtr = NULL;
+       
+       yaffsfs_Lock();
+       
+       oldPtr = yaffsfs_GetHandlePointer(fd);
+       if(oldPtr && oldPtr->inUse)
+               newHandle = yaffsfs_GetHandle();
+       if(newHandle >= 0)
+               newPtr = yaffsfs_GetHandlePointer(newHandle);
+               
+       if(newPtr){
+               *newPtr = *oldPtr;
+               return newHandle;
+       }
+       
+       if(!oldPtr)
+               yaffsfs_SetError(-EBADF);
+       else
+               yaffsfs_SetError(-ENOMEM);
+       
+       return -1;
+               
+}
 
-int yaffs_open(const char *path, int oflag, int mode)
+int yaffs_open(const YCHAR *path, int oflag, int mode)
 {
        yaffs_Object *obj = NULL;
        yaffs_Object *dir = NULL;
-       char *name;
+       YCHAR *name;
        int handle = -1;
        yaffsfs_Handle *h = NULL;
        int alreadyOpen = 0;
@@ -373,6 +476,11 @@ int yaffs_open(const char *path, int oflag, int mode)
                        obj = yaffsfs_FollowLink(obj,symDepth++);
                }
 
+               if(obj && obj->variantType != YAFFS_OBJECT_TYPE_FILE)
+               {
+                       obj = NULL;
+               }
+
                if(obj)
                {
                        // Check if the object is already in use
@@ -438,6 +546,7 @@ int yaffs_open(const char *path, int oflag, int mode)
                        else
                        {
                                yaffsfs_SetError(-ENOTDIR);
+                               errorReported = 1;
                        }
                }
                
@@ -463,17 +572,43 @@ int yaffs_open(const char *path, int oflag, int mode)
                        yaffsfs_PutHandle(handle);
                        if(!errorReported)
                        {
-                               yaffsfs_SetError(-EACCESS);
+                               yaffsfs_SetError(-EACCES);
                                errorReported = 1;
                        }
                        handle = -1;
                }
-               
+
        }
-       
+
        yaffsfs_Unlock();
+
+       return handle;
+}
+
+int yaffs_flush(int fd)
+{
+       yaffsfs_Handle *h = NULL;
+       int retVal = 0;
+
+       yaffsfs_Lock();
+
+       h = yaffsfs_GetHandlePointer(fd);
+
+       if(h && h->inUse)
+       {
+               // flush the file
+               yaffs_FlushFile(h->obj,1);
+       }
+       else
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);
+               retVal = -1;
+       }
        
-       return handle;          
+       yaffsfs_Unlock();
+
+       return retVal;
 }
 
 int yaffs_close(int fd)
@@ -515,7 +650,7 @@ int yaffs_read(int fd, void *buf, unsigned int nbyte)
        yaffs_Object *obj = NULL;
        int pos = 0;
        int nRead = -1;
-       int maxRead;
+       unsigned int maxRead;
        
        yaffsfs_Lock();
        h = yaffsfs_GetHandlePointer(fd);
@@ -570,6 +705,59 @@ int yaffs_read(int fd, void *buf, unsigned int nbyte)
                
 }
 
+int yaffs_pread(int fd, void *buf, unsigned int nbyte, unsigned int offset)
+{
+       yaffsfs_Handle *h = NULL;
+       yaffs_Object *obj = NULL;
+       int pos = 0;
+       int nRead = -1;
+       unsigned int maxRead;
+       
+       yaffsfs_Lock();
+       h = yaffsfs_GetHandlePointer(fd);
+       obj = yaffsfs_GetHandleObject(fd);
+       
+       if(!h || !obj)
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);               
+       }
+       else if( h && obj)
+       {
+               pos= offset;
+               if(yaffs_GetObjectFileLength(obj) > pos)
+               {
+                       maxRead = yaffs_GetObjectFileLength(obj) - pos;
+               }
+               else
+               {
+                       maxRead = 0;
+               }
+
+               if(nbyte > maxRead)
+               {
+                       nbyte = maxRead;
+               }
+
+               
+               if(nbyte > 0)
+               {
+                       nRead = yaffs_ReadDataFromFile(obj,buf,pos,nbyte);
+               }
+               else
+               {
+                       nRead = 0;
+               }
+               
+       }
+       
+       yaffsfs_Unlock();
+       
+       
+       return (nRead >= 0) ? nRead : -1;
+               
+}
+
 int yaffs_write(int fd, const void *buf, unsigned int nbyte)
 {
        yaffsfs_Handle *h = NULL;
@@ -622,7 +810,77 @@ int yaffs_write(int fd, const void *buf, unsigned int nbyte)
 
 }
 
-int yaffs_truncate(int fd, off_t newSize)
+int yaffs_pwrite(int fd, const void *buf, unsigned int nbyte, unsigned int offset)
+{
+       yaffsfs_Handle *h = NULL;
+       yaffs_Object *obj = NULL;
+       int pos = 0;
+       int nWritten = -1;
+       int writeThrough = 0;
+       
+       yaffsfs_Lock();
+       h = yaffsfs_GetHandlePointer(fd);
+       obj = yaffsfs_GetHandleObject(fd);
+       
+       if(!h || !obj)
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);               
+       }
+       else if( h && obj && h->readOnly)
+       {
+               // todo error
+       }
+       else if( h && obj)
+       {
+               pos = offset;
+                               
+               nWritten = yaffs_WriteDataToFile(obj,buf,pos,nbyte,writeThrough);
+               
+               if(nWritten < nbyte)
+                       yaffsfs_SetError(-ENOSPC);
+               
+       }
+       
+       yaffsfs_Unlock();
+       
+       
+       return (nWritten >= 0) ? nWritten : -1;
+
+}
+
+
+int yaffs_truncate(const YCHAR *path,off_t newSize) 
+{
+       yaffs_Object *obj = NULL;
+       int result = YAFFS_FAIL;
+       
+       yaffsfs_Lock();
+
+       obj = yaffsfs_FindObject(NULL,path,0);
+       if(obj)
+               obj = yaffs_GetEquivalentObject(obj);
+
+       if(!obj)
+       {
+               yaffsfs_SetError(-ENOENT);
+       }
+       else if(obj->variantType != YAFFS_OBJECT_TYPE_FILE)
+       {
+               yaffsfs_SetError(-EISDIR);
+       }
+       else
+       {
+               result = yaffs_ResizeFile(obj,newSize);
+       }
+       
+       yaffsfs_Unlock();
+       
+       
+       return (result) ? 0 : -1;
+}
+
+int yaffs_ftruncate(int fd, off_t newSize)
 {
        yaffsfs_Handle *h = NULL;
        yaffs_Object *obj = NULL;
@@ -704,11 +962,11 @@ off_t yaffs_lseek(int fd, off_t offset, int whence)
 }
 
 
-int yaffsfs_DoUnlink(const char *path,int isDirectory) 
+int yaffsfs_DoUnlink(const YCHAR *path,int isDirectory) 
 {
        yaffs_Object *dir = NULL;
        yaffs_Object *obj = NULL;
-       char *name;
+       YCHAR *name;
        int result = YAFFS_FAIL;
        
        yaffsfs_Lock();
@@ -747,23 +1005,25 @@ int yaffsfs_DoUnlink(const char *path,int isDirectory)
        
        return (result == YAFFS_FAIL) ? -1 : 0;
 }
-int yaffs_rmdir(const char *path) 
+
+
+int yaffs_rmdir(const YCHAR *path) 
 {
        return yaffsfs_DoUnlink(path,1);
 }
 
-int yaffs_unlink(const char *path) 
+int yaffs_unlink(const YCHAR *path) 
 {
        return yaffsfs_DoUnlink(path,0);
 }
 
-int yaffs_rename(const char *oldPath, const char *newPath)
+int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath)
 {
        yaffs_Object *olddir = NULL;
        yaffs_Object *newdir = NULL;
        yaffs_Object *obj = NULL;
-       char *oldname;
-       char *newname;
+       YCHAR *oldname;
+       YCHAR *newname;
        int result= YAFFS_FAIL;
        int renameAllowed = 1;
        
@@ -802,7 +1062,7 @@ int yaffs_rename(const char *oldPath, const char *newPath)
                        }
                        xx = xx->parent;
                }
-               if(!renameAllowed) yaffsfs_SetError(-EACCESS);
+               if(!renameAllowed) yaffsfs_SetError(-EACCES);
        }
        
        if(renameAllowed)
@@ -851,15 +1111,24 @@ static int yaffsfs_DoStat(yaffs_Object *obj,struct yaffs_stat *buf)
        buf->st_size = yaffs_GetObjectFileLength(obj);
                buf->st_blksize = obj->myDev->nDataBytesPerChunk;
        buf->st_blocks = (buf->st_size + buf->st_blksize -1)/buf->st_blksize;
-       buf->yst_atime = obj->yst_atime; 
-       buf->yst_ctime = obj->yst_ctime; 
-       buf->yst_mtime = obj->yst_mtime; 
+#if CONFIG_YAFFS_WINCE
+               buf->yst_wince_atime[0] = obj->win_atime[0];
+               buf->yst_wince_atime[1] = obj->win_atime[1];
+               buf->yst_wince_ctime[0] = obj->win_ctime[0];
+               buf->yst_wince_ctime[1] = obj->win_ctime[1];
+               buf->yst_wince_mtime[0] = obj->win_mtime[0];
+               buf->yst_wince_mtime[1] = obj->win_mtime[1];
+#else
+       buf->yst_atime = obj->yst_atime;
+       buf->yst_ctime = obj->yst_ctime;
+       buf->yst_mtime = obj->yst_mtime;
+#endif
                retVal = 0;
        }
        return retVal;
 }
 
-static int yaffsfs_DoStatOrLStat(const char *path, struct yaffs_stat *buf,int doLStat)
+static int yaffsfs_DoStatOrLStat(const YCHAR *path, struct yaffs_stat *buf,int doLStat)
 {
        yaffs_Object *obj;
        
@@ -889,12 +1158,12 @@ static int yaffsfs_DoStatOrLStat(const char *path, struct yaffs_stat *buf,int do
        
 }
 
-int yaffs_stat(const char *path, struct yaffs_stat *buf)
+int yaffs_stat(const YCHAR *path, struct yaffs_stat *buf)
 {
        return yaffsfs_DoStatOrLStat(path,buf,0);
 }
 
-int yaffs_lstat(const char *path, struct yaffs_stat *buf)
+int yaffs_lstat(const YCHAR *path, struct yaffs_stat *buf)
 {
        return yaffsfs_DoStatOrLStat(path,buf,1);
 }
@@ -915,6 +1184,46 @@ int yaffs_fstat(int fd, struct yaffs_stat *buf)
        else
        {
                // bad handle
+               yaffsfs_SetError(-EBADF);
+       }
+
+       yaffsfs_Unlock();
+
+       return retVal;
+}
+
+#ifdef CONFIG_YAFFS_WINCE
+int yaffs_get_wince_times(int fd, unsigned *wctime, unsigned *watime, unsigned *wmtime)
+{
+       yaffs_Object *obj;
+
+       int retVal = -1;
+
+       yaffsfs_Lock();
+       obj = yaffsfs_GetHandleObject(fd);
+
+       if(obj)
+       {
+
+               if(wctime){
+                       wctime[0] = obj->win_ctime[0];
+                       wctime[1] = obj->win_ctime[1];
+               }
+               if(watime){
+                       watime[0] = obj->win_atime[0];
+                       watime[1] = obj->win_atime[1];
+               }
+               if(wmtime){
+                       wmtime[0] = obj->win_mtime[0];
+                       wmtime[1] = obj->win_mtime[1];
+               }
+
+
+               retVal = 0;
+       }
+       else
+       {
+               // bad handle
                yaffsfs_SetError(-EBADF);               
        }
        
@@ -923,6 +1232,51 @@ int yaffs_fstat(int fd, struct yaffs_stat *buf)
        return retVal;
 }
 
+
+int yaffs_set_wince_times(int fd, 
+                                                 const unsigned *wctime, 
+                                                 const unsigned *watime, 
+                                                 const unsigned *wmtime)
+{
+       yaffs_Object *obj;
+       
+       int retVal = -1;
+
+       yaffsfs_Lock();
+       obj = yaffsfs_GetHandleObject(fd);
+
+       if(obj)
+       {
+
+               if(wctime){
+                       obj->win_ctime[0] = wctime[0];
+                       obj->win_ctime[1] = wctime[1];
+               }
+               if(watime){
+                       obj->win_atime[0] = watime[0];
+                       obj->win_atime[1] = watime[1];
+               }
+               if(wctime){
+                       obj->win_mtime[0] = wmtime[0];
+                       obj->win_mtime[1] = wmtime[1];
+               }
+
+               retVal = 0;
+       }
+       else
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);
+       }
+
+       yaffsfs_Unlock();
+
+       return retVal;
+}
+
+#endif
+
+
 static int yaffsfs_DoChMod(yaffs_Object *obj,mode_t mode)
 {
        int result;
@@ -943,7 +1297,46 @@ static int yaffsfs_DoChMod(yaffs_Object *obj,mode_t mode)
 }
 
 
-int yaffs_chmod(const char *path, mode_t mode)
+int yaffs_access(const YCHAR *path, int amode)
+{
+       yaffs_Object *obj;
+       
+       int retval = 0;
+       
+       yaffsfs_Lock();
+       obj = yaffsfs_FindObject(NULL,path,0);
+       
+       if(obj)
+       {
+               int access_ok = 1;
+               
+               if((amode & R_OK) && !(obj->yst_mode & S_IREAD))
+                       access_ok = 0;
+               if((amode & W_OK) && !(obj->yst_mode & S_IWRITE))
+                       access_ok = 0;
+               if((amode & X_OK) && !(obj->yst_mode & S_IEXEC))
+                       access_ok = 0;
+
+               if(!access_ok) {
+                       yaffsfs_SetError(-EACCES);
+                       retval = -1;
+               }
+       }
+       else
+       {
+               // todo error not found
+               yaffsfs_SetError(-ENOENT);
+               retval = -1;
+       }
+       
+       yaffsfs_Unlock();
+       
+       return retval;
+       
+}
+
+
+int yaffs_chmod(const YCHAR *path, mode_t mode)
 {
        yaffs_Object *obj;
        
@@ -994,11 +1387,11 @@ int yaffs_fchmod(int fd, mode_t mode)
 }
 
 
-int yaffs_mkdir(const char *path, mode_t mode)
+int yaffs_mkdir(const YCHAR *path, mode_t mode)
 {
        yaffs_Object *parent = NULL;
        yaffs_Object *dir = NULL;
-       char *name;
+       YCHAR *name;
        int retVal= -1;
        
        yaffsfs_Lock();
@@ -1011,7 +1404,14 @@ int yaffs_mkdir(const char *path, mode_t mode)
        }
        else
        {
-               yaffsfs_SetError(-ENOSPC); // just assume no space for now
+               if(!parent){
+                       yaffsfs_SetError(-ENOENT); // missing path
+               }
+               else if (yaffs_FindObjectByName(parent,name)){
+                       yaffsfs_SetError(-EEXIST); // the name already exists
+               }
+               else
+                       yaffsfs_SetError(-ENOSPC); // just assume no space 
                retVal = -1;
        }
        
@@ -1020,14 +1420,14 @@ int yaffs_mkdir(const char *path, mode_t mode)
        return retVal;
 }
 
-int yaffs_mount(const char *path)
+int yaffs_mount(const YCHAR *path)
 {
        int retVal=-1;
        int result=YAFFS_FAIL;
        yaffs_Device *dev=NULL;
-       char *dummy;
+       YCHAR *dummy;
        
-       T(YAFFS_TRACE_ALWAYS,("yaffs: Mounting %s\n",path));
+       T(YAFFS_TRACE_ALWAYS,(TSTR("yaffs: Mounting %s" TENDSTR),path));
        
        yaffsfs_Lock();
        dev = yaffsfs_FindDevice(path,&dummy);
@@ -1060,11 +1460,46 @@ int yaffs_mount(const char *path)
        
 }
 
-int yaffs_unmount(const char *path)
+int yaffs_sync(const YCHAR *path)
 {
        int retVal=-1;
        yaffs_Device *dev=NULL;
-       char *dummy;
+       YCHAR *dummy;
+       
+       yaffsfs_Lock();
+       dev = yaffsfs_FindDevice(path,&dummy);
+       if(dev)
+       {
+               if(dev->isMounted)
+               {
+                       
+                       yaffs_FlushEntireDeviceCache(dev);
+                       yaffs_CheckpointSave(dev);
+                       
+                       
+               }
+               else
+               {
+                       //todo error - not mounted.
+                       yaffsfs_SetError(-EINVAL);
+                       
+               }
+       }
+       else
+       {
+               // todo error - no device
+               yaffsfs_SetError(-ENODEV);
+       }       
+       yaffsfs_Unlock();
+       return retVal;  
+}
+
+
+int yaffs_unmount(const YCHAR *path)
+{
+       int retVal=-1;
+       yaffs_Device *dev=NULL;
+       YCHAR *dummy;
        
        yaffsfs_Lock();
        dev = yaffsfs_FindDevice(path,&dummy);
@@ -1116,11 +1551,11 @@ int yaffs_unmount(const char *path)
        
 }
 
-loff_t yaffs_freespace(const char *path)
+loff_t yaffs_freespace(const YCHAR *path)
 {
        loff_t retVal=-1;
        yaffs_Device *dev=NULL;
-       char *dummy;
+       YCHAR *dummy;
        
        yaffsfs_Lock();
        dev = yaffsfs_FindDevice(path,&dummy);
@@ -1128,7 +1563,31 @@ loff_t yaffs_freespace(const char *path)
        {
                retVal = yaffs_GetNumberOfFreeChunks(dev);
                retVal *= dev->nDataBytesPerChunk;
-               
+
+       }
+       else
+       {
+               yaffsfs_SetError(-EINVAL);
+       }
+
+       yaffsfs_Unlock();
+       return retVal;
+}
+
+loff_t yaffs_totalspace(const YCHAR *path)
+{
+       loff_t retVal=-1;
+       yaffs_Device *dev=NULL;
+       YCHAR *dummy;
+
+       yaffsfs_Lock();
+       dev = yaffsfs_FindDevice(path,&dummy);
+       if(dev  && dev->isMounted)
+       {
+               retVal = (dev->endBlock - dev->startBlock + 1) - dev->nReservedBlocks;
+               retVal *= dev->nChunksPerBlock;
+               retVal *= dev->nDataBytesPerChunk;
+
        }
        else
        {
@@ -1176,16 +1635,16 @@ typedef struct
 {
        __u32 magic;
        yaffs_dirent de;                /* directory entry being used by this dsc */
-       char name[NAME_MAX+1];          /* name of directory being searched */
+       YCHAR name[NAME_MAX+1];         /* name of directory being searched */
        yaffs_Object *dirObj;           /* ptr to directory being searched */
        yaffs_Object *nextReturn;       /* obj to be returned by next readddir */
        int offset;
-       struct list_head others;        
+       struct ylist_head others;       
 } yaffsfs_DirectorySearchContext;
 
 
 
-static struct list_head search_contexts;
+static struct ylist_head search_contexts;
 
 
 static void yaffsfs_SetDirRewound(yaffsfs_DirectorySearchContext *dsc)
@@ -1196,10 +1655,10 @@ static void yaffsfs_SetDirRewound(yaffsfs_DirectorySearchContext *dsc)
           
           dsc->offset = 0;
           
-          if( list_empty(&dsc->dirObj->variant.directoryVariant.children)){
+          if( ylist_empty(&dsc->dirObj->variant.directoryVariant.children)){
                dsc->nextReturn = NULL;
           } else {
-               dsc->nextReturn = list_entry(dsc->dirObj->variant.directoryVariant.children.next,
+               dsc->nextReturn = ylist_entry(dsc->dirObj->variant.directoryVariant.children.next,
                                                yaffs_Object,siblings);
           }
        } else {
@@ -1214,15 +1673,15 @@ static void yaffsfs_DirAdvance(yaffsfs_DirectorySearchContext *dsc)
           dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
           
           if( dsc->nextReturn == NULL ||
-              list_empty(&dsc->dirObj->variant.directoryVariant.children)){
+              ylist_empty(&dsc->dirObj->variant.directoryVariant.children)){
                dsc->nextReturn = NULL;
           } else {
-                  struct list_head *next = dsc->nextReturn->siblings.next;
+                  struct ylist_head *next = dsc->nextReturn->siblings.next;
    
                   if( next == &dsc->dirObj->variant.directoryVariant.children)
                        dsc->nextReturn = NULL; /* end of list */
                   else 
-                       dsc->nextReturn = list_entry(next,yaffs_Object,siblings);
+                       dsc->nextReturn = ylist_entry(next,yaffs_Object,siblings);
           }
        } else {
                /* Hey someone isn't playing nice! */
@@ -1232,20 +1691,20 @@ static void yaffsfs_DirAdvance(yaffsfs_DirectorySearchContext *dsc)
 static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj)
 {
 
-       struct list_head *i;
+       struct ylist_head *i;
        yaffsfs_DirectorySearchContext *dsc;
        
        /* if search contexts not initilised then skip */
        if(!search_contexts.next)
                return;
                
-       /* Iteratethrough the directory search contexts.
+       /* Iterate through the directory search contexts.
         * If any are the one being removed, then advance the dsc to
         * the next one to prevent a hanging ptr.
         */
-        list_for_each(i, &search_contexts) {
+        ylist_for_each(i, &search_contexts) {
                if (i) {
-                       dsc = list_entry(i, yaffsfs_DirectorySearchContext,others);
+                       dsc = ylist_entry(i, yaffsfs_DirectorySearchContext,others);
                        if(dsc->nextReturn == obj)
                                yaffsfs_DirAdvance(dsc);
                }
@@ -1253,7 +1712,7 @@ static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj)
                                
 }
 
-yaffs_DIR *yaffs_opendir(const char *dirname)
+yaffs_DIR *yaffs_opendir(const YCHAR *dirname)
 {
        yaffs_DIR *dir = NULL;
        yaffs_Object *obj = NULL;
@@ -1273,13 +1732,13 @@ yaffs_DIR *yaffs_opendir(const char *dirname)
                        memset(dsc,0,sizeof(yaffsfs_DirectorySearchContext));
                        dsc->magic = YAFFS_MAGIC;
                        dsc->dirObj = obj;
-                       strncpy(dsc->name,dirname,NAME_MAX);
-                       INIT_LIST_HEAD(&dsc->others);
+                       yaffs_strncpy(dsc->name,dirname,NAME_MAX);
+                       YINIT_LIST_HEAD(&dsc->others);
                        
                        if(!search_contexts.next)
-                               INIT_LIST_HEAD(&search_contexts);
+                               YINIT_LIST_HEAD(&search_contexts);
                                
-                       list_add(&dsc->others,&search_contexts);        
+                       ylist_add(&dsc->others,&search_contexts);       
                        yaffsfs_SetDirRewound(dsc);             }
        
        }
@@ -1303,10 +1762,10 @@ struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp)
                        dsc->de.d_dont_use = (unsigned)dsc->nextReturn;
                        dsc->de.d_off = dsc->offset++;
                        yaffs_GetObjectName(dsc->nextReturn,dsc->de.d_name,NAME_MAX);
-                       if(strlen(dsc->de.d_name) == 0)
+                       if(yaffs_strlen(dsc->de.d_name) == 0)
                        {
                                // this should not happen!
-                               strcpy(dsc->de.d_name,"zz");
+                               yaffs_strcpy(dsc->de.d_name,_Y("zz"));
                        }
                        dsc->de.d_reclen = sizeof(struct yaffs_dirent);
                        retVal = &dsc->de;
@@ -1344,7 +1803,7 @@ int yaffs_closedir(yaffs_DIR *dirp)
                
        yaffsfs_Lock();
        dsc->magic = 0;
-       list_del(&dsc->others); /* unhook from list */
+       ylist_del(&dsc->others); /* unhook from list */
        YFREE(dsc);
        yaffsfs_Unlock();
        return 0;
@@ -1353,11 +1812,11 @@ int yaffs_closedir(yaffs_DIR *dirp)
 // end of directory stuff
 
 
-int yaffs_symlink(const char *oldpath, const char *newpath)
+int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath)
 {
        yaffs_Object *parent = NULL;
        yaffs_Object *obj;
-       char *name;
+       YCHAR *name;
        int retVal= -1;
        int mode = 0; // ignore for now
        
@@ -1380,7 +1839,7 @@ int yaffs_symlink(const char *oldpath, const char *newpath)
        
 }
 
-int yaffs_readlink(const char *path, char *buf, int bufsiz)
+int yaffs_readlink(const YCHAR *path, YCHAR *buf, int bufsiz)
 {
        yaffs_Object *obj = NULL;
        int retVal;
@@ -1402,16 +1861,16 @@ int yaffs_readlink(const char *path, char *buf, int bufsiz)
        }
        else
        {
-               char *alias = obj->variant.symLinkVariant.alias;
+               YCHAR *alias = obj->variant.symLinkVariant.alias;
                memset(buf,0,bufsiz);
-               strncpy(buf,alias,bufsiz - 1);
+               yaffs_strncpy(buf,alias,bufsiz - 1);
                retVal = 0;
        }
        yaffsfs_Unlock();
        return retVal;
 }
 
-int yaffs_link(const char *oldpath, const char *newpath)
+int yaffs_link(const YCHAR *oldpath, const YCHAR *newpath)
 {
        // Creates a link called newpath to existing oldpath
        yaffs_Object *obj = NULL;
@@ -1439,7 +1898,7 @@ int yaffs_link(const char *oldpath, const char *newpath)
                yaffs_Object *newdir = NULL;
                yaffs_Object *link = NULL;
                
-               char *newname;
+               YCHAR *newname;
                
                newdir = yaffsfs_FindDirectory(NULL,newpath,&newname,0);
                
@@ -1453,7 +1912,7 @@ int yaffs_link(const char *oldpath, const char *newpath)
                        yaffsfs_SetError(-EXDEV);
                        retVal = -1;
                }
-               if(newdir && strlen(newname) > 0)
+               if(newdir && yaffs_strlen(newname) > 0)
                {
                        link = yaffs_Link(newdir,newname,obj);
                        if(link)
@@ -1471,11 +1930,12 @@ int yaffs_link(const char *oldpath, const char *newpath)
        return retVal;
 }
 
-int yaffs_mknod(const char *pathname, mode_t mode, dev_t dev);
+int yaffs_mknod(const YCHAR *pathname, mode_t mode, dev_t dev);
 
-int yaffs_DumpDevStruct(const char *path)
+int yaffs_DumpDevStruct(const YCHAR *path)
 {
-       char *rest;
+#if 0
+       YCHAR *rest;
        
        yaffs_Object *obj = yaffsfs_FindRoot(path,&rest);
        
@@ -1500,6 +1960,8 @@ int yaffs_DumpDevStruct(const char *path)
                );
                
        }
+
+#endif
        return 0;
 }
 
index 9afe60a..fe4eff5 100644 (file)
@@ -35,6 +35,9 @@
 #define NAME_MAX       256
 #endif
 
+
+#ifdef CONFIG_YAFFSFS_PROVIDE_VALUES
+
 #ifndef O_RDONLY
 #define O_RDONLY       00
 #endif
@@ -91,8 +94,8 @@
 #define EBADF  9
 #endif
 
-#ifndef EACCESS
-#define EACCESS        13
+#ifndef EACCES
+#define EACCES 13
 #endif
 
 #ifndef EXDEV  
 #define        S_IWRITE        0000200
 #endif
 
+#ifndef S_IEXEC
+#define        S_IEXEC 0000100
+#endif
+
+#ifndef R_OK
+#define R_OK   4
+#define W_OK   2
+#define X_OK   1
+#define F_OK   0
+#endif
 
+#else
+#include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
 
 
 struct yaffs_dirent{
     long d_ino;                 /* inode number */
     off_t d_off;                /* offset to this dirent */
     unsigned short d_reclen;    /* length of this d_name */
-    char d_name [NAME_MAX+1];   /* file name (null-terminated) */
+    YUCHAR  d_type;    /* type of this record */
+    YCHAR d_name [NAME_MAX+1];   /* file name (null-terminated) */
     unsigned d_dont_use;       /* debug pointer, not for public consumption */
 };
 
@@ -175,7 +194,7 @@ typedef struct __opaque yaffs_DIR;
 struct yaffs_stat{
     int                      st_dev;      /* device */
     int           st_ino;      /* inode */
-    mode_t        st_mode;     /* protection */
+    unsigned      st_mode;     /* protection */
     int           st_nlink;    /* number of hard links */
     int           st_uid;      /* user ID of owner */
     int           st_gid;      /* group ID of owner */
@@ -183,46 +202,68 @@ struct yaffs_stat{
     off_t         st_size;     /* total size, in bytes */
     unsigned long st_blksize;  /* blocksize for filesystem I/O */
     unsigned long st_blocks;   /* number of blocks allocated */
-    unsigned long yst_atime;    /* time of last access */
+#ifdef CONFIG_YAFFS_WINCE
+       /* Special 64-bit times for WinCE */
+       unsigned long yst_wince_atime[2];
+       unsigned long yst_wince_mtime[2];
+       unsigned long yst_wince_ctime[2];
+#else
+       unsigned long yst_atime;    /* time of last access */
     unsigned long yst_mtime;    /* time of last modification */
     unsigned long yst_ctime;    /* time of last change */
+#endif
 };
 
-int yaffs_open(const char *path, int oflag, int mode) ;
+int yaffs_open(const YCHAR *path, int oflag, int mode) ;
+int yaffs_close(int fd) ;
+int yaffs_flush(int fd) ;
+
+int yaffs_access(const YCHAR *path, int amode);
+
+int yaffs_dup(int fd);
+
 int yaffs_read(int fd, void *buf, unsigned int nbyte) ;
 int yaffs_write(int fd, const void *buf, unsigned int nbyte) ;
-int yaffs_close(int fd) ;
+
+int yaffs_pread(int fd, void *buf, unsigned int nbyte, unsigned int offset);
+int yaffs_pwrite(int fd, const void *buf, unsigned int nbyte, unsigned int offset);
+
 off_t yaffs_lseek(int fd, off_t offset, int whence) ;
-int yaffs_truncate(int fd, off_t newSize);
 
-int yaffs_unlink(const char *path) ;
-int yaffs_rename(const char *oldPath, const char *newPath) ;
+int yaffs_truncate(const YCHAR *path, off_t newSize);
+int yaffs_ftruncate(int fd, off_t newSize);
 
-int yaffs_stat(const char *path, struct yaffs_stat *buf) ;
-int yaffs_lstat(const char *path, struct yaffs_stat *buf) ;
+int yaffs_unlink(const YCHAR *path) ;
+int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath) ;
+
+int yaffs_stat(const YCHAR *path, struct yaffs_stat *buf) ;
+int yaffs_lstat(const YCHAR *path, struct yaffs_stat *buf) ;
 int yaffs_fstat(int fd, struct yaffs_stat *buf) ;
 
-int yaffs_chmod(const char *path, mode_t mode); 
+int yaffs_chmod(const YCHAR *path, mode_t mode); 
 int yaffs_fchmod(int fd, mode_t mode); 
 
-int yaffs_mkdir(const char *path, mode_t mode) ;
-int yaffs_rmdir(const char *path) ;
+int yaffs_mkdir(const YCHAR *path, mode_t mode) ;
+int yaffs_rmdir(const YCHAR *path) ;
 
-yaffs_DIR *yaffs_opendir(const char *dirname) ;
+yaffs_DIR *yaffs_opendir(const YCHAR *dirname) ;
 struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) ;
 void yaffs_rewinddir(yaffs_DIR *dirp) ;
 int yaffs_closedir(yaffs_DIR *dirp) ;
 
-int yaffs_mount(const char *path) ;
-int yaffs_unmount(const char *path) ;
+int yaffs_mount(const YCHAR *path) ;
+int yaffs_unmount(const YCHAR *path) ;
+
+int yaffs_sync(const YCHAR *path) ;
 
-int yaffs_symlink(const char *oldpath, const char *newpath); 
-int yaffs_readlink(const char *path, char *buf, int bufsiz); 
+int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath); 
+int yaffs_readlink(const YCHAR *path, YCHAR *buf, int bufsiz); 
 
-int yaffs_link(const char *oldpath, const char *newpath); 
-int yaffs_mknod(const char *pathname, mode_t mode, dev_t dev);
+int yaffs_link(const YCHAR *oldpath, const YCHAR *newpath); 
+int yaffs_mknod(const YCHAR *pathname, mode_t mode, dev_t dev);
 
-loff_t yaffs_freespace(const char *path);
+loff_t yaffs_freespace(const YCHAR *path);
+loff_t yaffs_totalspace(const YCHAR *path);
 
 void yaffs_initialise(yaffsfs_DeviceConfiguration *configList);
 
index 0c28205..6a2bb18 100644 (file)
@@ -30,7 +30,8 @@
 #include "yaffs_malloc.h"
 
 #include "assert.h"
-#define YBUG() assert(1)
+#define YBUG() assert(0)
+
 
 #define YCHAR char
 #define YUCHAR unsigned char
@@ -42,6 +43,8 @@
 #define yaffs_sprintf       sprintf
 #define yaffs_toupper(a)     toupper(a)
 
+#define YAFFS_PATH_DIVIDERS  "/"
+
 #ifdef NO_Y_INLINE
 #define Y_INLINE
 #else
index d1ecdf5..68e6d0c 100644 (file)
  */
 
 const char *yaffs_checkptrw_c_version =
-    "$Id: yaffs_checkptrw.c,v 1.15 2007-12-13 15:35:17 wookey Exp $";
+    "$Id: yaffs_checkptrw.c,v 1.16 2008-05-05 07:58:58 charles Exp $";
 
 
 #include "yaffs_checkptrw.h"
-
+#include "yaffs_getblockinfo.h"
 
 static int yaffs_CheckpointSpaceOk(yaffs_Device *dev)
 {
@@ -142,7 +142,7 @@ int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
                return 0;
 
        if(!dev->checkpointBuffer)
-               dev->checkpointBuffer = YMALLOC_DMA(dev->nDataBytesPerChunk);
+               dev->checkpointBuffer = YMALLOC_DMA(dev->totalBytesPerChunk);
        if(!dev->checkpointBuffer)
                return 0;
 
index eceb34f..ab6a3a7 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 const char *yaffs_fs_c_version =
-    "$Id: yaffs_fs.c,v 1.65 2007-12-13 15:35:17 wookey Exp $";
+    "$Id: yaffs_fs.c,v 1.66 2008-05-05 07:58:58 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 #include <linux/version.h>
@@ -53,6 +53,8 @@ extern const char *yaffs_guts_c_version;
 #include <linux/string.h>
 #include <linux/ctype.h>
 
+#include "asm/div64.h"
+
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 
 #include <linux/statfs.h>      /* Added NCB 15-8-2003 */
@@ -753,6 +755,8 @@ static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object * obj)
                        break;
                }
 
+               inode->i_flags |= S_NOATIME;
+               
                inode->i_ino = obj->objectId;
                inode->i_mode = obj->yst_mode;
                inode->i_uid = obj->yst_uid;
@@ -1350,25 +1354,47 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
        buf->f_type = YAFFS_MAGIC;
        buf->f_bsize = sb->s_blocksize;
        buf->f_namelen = 255;
-       if (sb->s_blocksize > dev->nDataBytesPerChunk) {
-
+       
+       if(dev->nDataBytesPerChunk & (dev->nDataBytesPerChunk - 1)){
+               /* Do this if chunk size is not a power of 2 */
+               
+               uint64_t bytesInDev;
+               uint64_t bytesFree;
+
+               bytesInDev = ((uint64_t)((dev->endBlock - dev->startBlock +1))) *
+                            ((uint64_t)(dev->nChunksPerBlock * dev->nDataBytesPerChunk));
+       
+               do_div(bytesInDev,sb->s_blocksize); /* bytesInDev becomes the number of blocks */
+               buf->f_blocks = bytesInDev;
+
+               bytesFree  = ((uint64_t)(yaffs_GetNumberOfFreeChunks(dev))) *
+                            ((uint64_t)(dev->nDataBytesPerChunk));
+       
+               do_div(bytesFree,sb->s_blocksize);
+       
+               buf->f_bfree = bytesFree;
+       
+       } else if (sb->s_blocksize > dev->nDataBytesPerChunk) {
+       
                buf->f_blocks =
-                   (dev->endBlock - dev->startBlock +
-                    1) * dev->nChunksPerBlock / (sb->s_blocksize /
-                                                 dev->nDataBytesPerChunk);
-               buf->f_bfree =
-                   yaffs_GetNumberOfFreeChunks(dev) / (sb->s_blocksize /
-                                                       dev->nDataBytesPerChunk);
+                          (dev->endBlock - dev->startBlock + 1) * 
+                           dev->nChunksPerBlock / 
+                           (sb->s_blocksize / dev->nDataBytesPerChunk);
+               buf->f_bfree =
+                          yaffs_GetNumberOfFreeChunks(dev) / 
+                          (sb->s_blocksize / dev->nDataBytesPerChunk);
        } else {
-
-               buf->f_blocks =
-                   (dev->endBlock - dev->startBlock +
-                    1) * dev->nChunksPerBlock * (dev->nDataBytesPerChunk /
-                                                 sb->s_blocksize);
-               buf->f_bfree =
-                   yaffs_GetNumberOfFreeChunks(dev) * (dev->nDataBytesPerChunk /
-                                                       sb->s_blocksize);
+              buf->f_blocks =
+                          (dev->endBlock - dev->startBlock + 1) * 
+                          dev->nChunksPerBlock * 
+                          (dev->nDataBytesPerChunk / sb->s_blocksize);
+                          
+                      buf->f_bfree =
+                          yaffs_GetNumberOfFreeChunks(dev) * 
+                          (dev->nDataBytesPerChunk / sb->s_blocksize);
        }
+       
+       
        buf->f_files = 0;
        buf->f_ffree = 0;
        buf->f_bavail = buf->f_bfree;
@@ -1602,6 +1628,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
 
        sb->s_magic = YAFFS_MAGIC;
        sb->s_op = &yaffs_super_ops;
+       sb->s_flags |= MS_NOATIME;
 
        if (!sb)
                printk(KERN_INFO "yaffs: sb is NULL\n");
@@ -1678,22 +1705,15 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
 #ifdef CONFIG_YAFFS_AUTO_YAFFS2
 
        if (yaffsVersion == 1 &&
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-           mtd->writesize >= 2048) {
-#else
-           mtd->oobblock >= 2048) {
-#endif
+           WRITE_SIZE(mtd) >= 2048) {
            T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs2\n"));
            yaffsVersion = 2;
        }
 
        /* Added NCB 26/5/2006 for completeness */
-       if (yaffsVersion == 2 &&
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-           mtd->writesize == 512) {
-#else
-           mtd->oobblock == 512) {
-#endif
+       if (yaffsVersion == 2 && 
+           !options.inband_tags &&
+           WRITE_SIZE(mtd) == 512){
            T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs1\n"));
            yaffsVersion = 1;
        }
@@ -1719,12 +1739,9 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
                        return NULL;
                }
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-               if (mtd->writesize < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
-#else
-               if (mtd->oobblock < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
-#endif
-                   mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) {
+               if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
+                   mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) &&
+                   !options.inband_tags) {
                        T(YAFFS_TRACE_ALWAYS,
                          ("yaffs: MTD device does not have the "
                           "right page sizes\n"));
@@ -1784,9 +1801,10 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        dev->startBlock = 0;
        dev->endBlock = nBlocks - 1;
        dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
-       dev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
+       dev->totalBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
        dev->nReservedBlocks = 5;
        dev->nShortOpCaches = (options.no_cache) ? 0 : 10;
+       dev->inbandTags = options.inband_tags;
 
        /* ... and the functions. */
        if (yaffsVersion == 2) {
@@ -1799,10 +1817,10 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
                dev->spareBuffer = YMALLOC(mtd->oobsize);
                dev->isYaffs2 = 1;
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-               dev->nDataBytesPerChunk = mtd->writesize;
+               dev->totalBytesPerChunk = mtd->writesize;
                dev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
 #else
-               dev->nDataBytesPerChunk = mtd->oobblock;
+               dev->totalBytesPerChunk = mtd->oobblock;
                dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
 #endif
                nBlocks = mtd->size / mtd->erasesize;
@@ -1989,6 +2007,7 @@ static char *yaffs_dump_dev(char *buf, yaffs_Device * dev)
 {
        buf += sprintf(buf, "startBlock......... %d\n", dev->startBlock);
        buf += sprintf(buf, "endBlock........... %d\n", dev->endBlock);
+       buf += sprintf(buf, "totalBytesPerChunk. %d\n", dev->totalBytesPerChunk);
        buf += sprintf(buf, "nDataBytesPerChunk. %d\n", dev->nDataBytesPerChunk);
        buf += sprintf(buf, "chunkGroupBits..... %d\n", dev->chunkGroupBits);
        buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize);
@@ -2004,10 +2023,8 @@ static char *yaffs_dump_dev(char *buf, yaffs_Device * dev)
        buf += sprintf(buf, "nPageReads......... %d\n", dev->nPageReads);
        buf += sprintf(buf, "nBlockErasures..... %d\n", dev->nBlockErasures);
        buf += sprintf(buf, "nGCCopies.......... %d\n", dev->nGCCopies);
-       buf +=
-           sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections);
-       buf +=
-           sprintf(buf, "passiveGCs......... %d\n",
+       buf += sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections);
+       buf += sprintf(buf, "passiveGCs......... %d\n",
                    dev->passiveGarbageCollections);
        buf += sprintf(buf, "nRetriedWrites..... %d\n", dev->nRetriedWrites);
        buf += sprintf(buf, "nShortOpCaches..... %d\n", dev->nShortOpCaches);
@@ -2023,6 +2040,7 @@ static char *yaffs_dump_dev(char *buf, yaffs_Device * dev)
            sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions);
        buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC);
        buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2);
+       buf += sprintf(buf, "inbandTags......... %d\n", dev->inbandTags);
 
        return buf;
 }
index 097b525..c1a5b0c 100644 (file)
  */
 
 const char *yaffs_guts_c_version =
-    "$Id: yaffs_guts.c,v 1.54 2007-12-13 15:35:17 wookey Exp $";
+    "$Id: yaffs_guts.c,v 1.55 2008-05-05 07:58:58 charles Exp $";
 
 #include "yportenv.h"
 
 #include "yaffsinterface.h"
 #include "yaffs_guts.h"
 #include "yaffs_tagsvalidity.h"
+#include "yaffs_getblockinfo.h"
 
 #include "yaffs_tagscompat.h"
 #ifndef  CONFIG_YAFFS_USE_OWN_SORT
@@ -78,9 +79,6 @@ static int yaffs_DoGenericObjectDeletion(yaffs_Object * in);
 
 static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blockNo);
 
-static __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo);
-static void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer,
-                                   int lineNo);
 
 static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
                                  int chunkInNAND);
@@ -121,23 +119,32 @@ static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device * dev,
 
 /* Function to calculate chunk and offset */
 
-static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, __u32 *chunk, __u32 *offset)
+static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, int *chunkOut, __u32 *offsetOut)
 {
-       if(dev->chunkShift){
-               /* Easy-peasy power of 2 case */
-               *chunk  = (__u32)(addr >> dev->chunkShift);
-               *offset = (__u32)(addr & dev->chunkMask);
-       }
-       else if(dev->crumbsPerChunk)
+       int chunk;
+       __u32 offset;
+       
+       chunk  = (__u32)(addr >> dev->chunkShift);
+               
+       if(dev->chunkDiv == 1)
        {
-               /* Case where we're using "crumbs" */
-               *offset = (__u32)(addr & dev->crumbMask);
-               addr >>= dev->crumbShift;
-               *chunk = ((__u32)addr)/dev->crumbsPerChunk;
-               *offset += ((addr - (*chunk * dev->crumbsPerChunk)) << dev->crumbShift);
+               /* easy power of 2 case */
+               offset = (__u32)(addr & dev->chunkMask);
        }
        else
-               YBUG();
+       {
+               /* Non power-of-2 case */
+               
+               loff_t chunkBase;
+               
+               chunk /= dev->chunkDiv;
+               
+               chunkBase = ((loff_t)chunk) * dev->nDataBytesPerChunk;
+               offset = (__u32)(addr - chunkBase);
+       }
+
+       *chunkOut = chunk;
+       *offsetOut = offset;
 }
 
 /* Function to return the number of shifts for a power of 2 greater than or equal
@@ -168,7 +175,7 @@ static __u32 ShiftsGE(__u32 x)
 /* Function to return the number of shifts to get a 1 in bit 0
  */
 
-static __u32 ShiftDiv(__u32 x)
+static __u32 Shifts(__u32 x)
 {
        int nShifts;
 
@@ -200,16 +207,21 @@ static int yaffs_InitialiseTempBuffers(yaffs_Device *dev)
        for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) {
                dev->tempBuffer[i].line = 0;    /* not in use */
                dev->tempBuffer[i].buffer = buf =
-                   YMALLOC_DMA(dev->nDataBytesPerChunk);
+                   YMALLOC_DMA(dev->totalBytesPerChunk);
        }
 
        return buf ? YAFFS_OK : YAFFS_FAIL;
 
 }
 
-static __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo)
+__u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo)
 {
        int i, j;
+
+       dev->tempInUse++;
+       if(dev->tempInUse > dev->maxTemp)
+               dev->maxTemp = dev->tempInUse;
+
        for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
                if (dev->tempBuffer[i].line == 0) {
                        dev->tempBuffer[i].line = lineNo;
@@ -242,10 +254,13 @@ static __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo)
 
 }
 
-static void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer,
+void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer,
                                    int lineNo)
 {
        int i;
+       
+       dev->tempInUse--;
+       
        for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
                if (dev->tempBuffer[i].buffer == buffer) {
                        dev->tempBuffer[i].line = 0;
@@ -390,11 +405,14 @@ static int yaffs_SkipVerification(yaffs_Device *dev)
        return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY | YAFFS_TRACE_VERIFY_FULL));
 }
 
+#if 0
 static int yaffs_SkipFullVerification(yaffs_Device *dev)
 {
        return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY_FULL));
 }
 
+#endif
+
 static int yaffs_SkipNANDVerification(yaffs_Device *dev)
 {
        return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY_NAND));
@@ -597,7 +615,6 @@ static int yaffs_VerifyTnodeWorker(yaffs_Object * obj, yaffs_Tnode * tn,
        int i;
        yaffs_Device *dev = obj->myDev;
        int ok = 1;
-       int nTnodeBytes = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
 
        if (tn) {
                if (level > 0) {
@@ -646,7 +663,6 @@ static void yaffs_VerifyFile(yaffs_Object *obj)
        __u32 lastChunk;
        __u32 x;
        __u32 i;
-       int ok;
        yaffs_Device *dev;
        yaffs_ExtendedTags tags;
        yaffs_Tnode *tn;
@@ -829,7 +845,7 @@ static void yaffs_VerifyObjects(yaffs_Device *dev)
 {
        yaffs_Object *obj;
        int i;
-       struct list_head *lh;
+       struct ylist_head *lh;
 
        if(yaffs_SkipVerification(dev))
                return;
@@ -837,9 +853,9 @@ static void yaffs_VerifyObjects(yaffs_Device *dev)
        /* Iterate through the objects in each hash entry */
 
         for(i = 0; i <  YAFFS_NOBJECT_BUCKETS; i++){
-               list_for_each(lh, &dev->objectBucket[i].list) {
+               ylist_for_each(lh, &dev->objectBucket[i].list) {
                        if (lh) {
-                               obj = list_entry(lh, yaffs_Object, hashLink);
+                               obj = ylist_entry(lh, yaffs_Object, hashLink);
                                yaffs_VerifyObject(obj);
                        }
                }
@@ -1869,7 +1885,7 @@ static int yaffs_CreateFreeObjects(yaffs_Device * dev, int nObjects)
        /* Hook them into the free list */
        for (i = 0; i < nObjects - 1; i++) {
                newObjects[i].siblings.next =
-                   (struct list_head *)(&newObjects[i + 1]);
+                   (struct ylist_head *)(&newObjects[i + 1]);
        }
 
        newObjects[nObjects - 1].siblings.next = (void *)dev->freeObjects;
@@ -1909,9 +1925,9 @@ static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device * dev)
                tn->myDev = dev;
                tn->chunkId = -1;
                tn->variantType = YAFFS_OBJECT_TYPE_UNKNOWN;
-               INIT_LIST_HEAD(&(tn->hardLinks));
-               INIT_LIST_HEAD(&(tn->hashLink));
-               INIT_LIST_HEAD(&tn->siblings);
+               YINIT_LIST_HEAD(&(tn->hardLinks));
+               YINIT_LIST_HEAD(&(tn->hashLink));
+               YINIT_LIST_HEAD(&tn->siblings);
 
                /* Add it to the lost and found directory.
                 * NB Can't put root or lostNFound in lostNFound so
@@ -1954,8 +1970,8 @@ static void yaffs_UnhashObject(yaffs_Object * tn)
        yaffs_Device *dev = tn->myDev;
 
        /* If it is still linked into the bucket list, free from the list */
-       if (!list_empty(&tn->hashLink)) {
-               list_del_init(&tn->hashLink);
+       if (!ylist_empty(&tn->hashLink)) {
+               ylist_del_init(&tn->hashLink);
                bucket = yaffs_HashFunction(tn->objectId);
                dev->objectBucket[bucket].count--;
        }
@@ -1981,7 +1997,7 @@ static void yaffs_FreeObject(yaffs_Object * tn)
        yaffs_UnhashObject(tn);
 
        /* Link into the free list. */
-       tn->siblings.next = (struct list_head *)(dev->freeObjects);
+       tn->siblings.next = (struct ylist_head *)(dev->freeObjects);
        dev->freeObjects = tn;
        dev->nFreeObjects++;
 
@@ -2027,7 +2043,7 @@ static void yaffs_InitialiseObjects(yaffs_Device * dev)
        dev->nFreeObjects = 0;
 
        for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
-               INIT_LIST_HEAD(&dev->objectBucket[i].list);
+               YINIT_LIST_HEAD(&dev->objectBucket[i].list);
                dev->objectBucket[i].count = 0;
        }
 
@@ -2078,7 +2094,7 @@ static int yaffs_CreateNewObjectNumber(yaffs_Device * dev)
         */
 
        int found = 0;
-       struct list_head *i;
+       struct ylist_head *i;
 
        __u32 n = (__u32) bucket;
 
@@ -2088,10 +2104,10 @@ static int yaffs_CreateNewObjectNumber(yaffs_Device * dev)
                found = 1;
                n += YAFFS_NOBJECT_BUCKETS;
                if (1 || dev->objectBucket[bucket].count > 0) {
-                       list_for_each(i, &dev->objectBucket[bucket].list) {
+                       ylist_for_each(i, &dev->objectBucket[bucket].list) {
                                /* If there is already one in the list */
                                if (i
-                                   && list_entry(i, yaffs_Object,
+                                   && ylist_entry(i, yaffs_Object,
                                                  hashLink)->objectId == n) {
                                        found = 0;
                                }
@@ -2108,7 +2124,7 @@ static void yaffs_HashObject(yaffs_Object * in)
        int bucket = yaffs_HashFunction(in->objectId);
        yaffs_Device *dev = in->myDev;
 
-       list_add(&in->hashLink, &dev->objectBucket[bucket].list);
+       ylist_add(&in->hashLink, &dev->objectBucket[bucket].list);
        dev->objectBucket[bucket].count++;
 
 }
@@ -2116,13 +2132,13 @@ static void yaffs_HashObject(yaffs_Object * in)
 yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number)
 {
        int bucket = yaffs_HashFunction(number);
-       struct list_head *i;
+       struct ylist_head *i;
        yaffs_Object *in;
 
-       list_for_each(i, &dev->objectBucket[bucket].list) {
+       ylist_for_each(i, &dev->objectBucket[bucket].list) {
                /* Look if it is in the list */
                if (i) {
-                       in = list_entry(i, yaffs_Object, hashLink);
+                       in = ylist_entry(i, yaffs_Object, hashLink);
                        if (in->objectId == number) {
 #ifdef __KERNEL__
                                /* Don't tell the VFS about this one if it is defered free */
@@ -2143,7 +2159,7 @@ yaffs_Object *yaffs_CreateNewObject(yaffs_Device * dev, int number,
 {
 
        yaffs_Object *theObject;
-       yaffs_Tnode *tn;
+       yaffs_Tnode *tn = NULL;
 
        if (number < 0) {
                number = yaffs_CreateNewObjectNumber(dev);
@@ -2191,7 +2207,7 @@ yaffs_Object *yaffs_CreateNewObject(yaffs_Device * dev, int number,
                        theObject->variant.fileVariant.top = tn;
                        break;
                case YAFFS_OBJECT_TYPE_DIRECTORY:
-                       INIT_LIST_HEAD(&theObject->variant.directoryVariant.
+                       YINIT_LIST_HEAD(&theObject->variant.directoryVariant.
                                       children);
                        break;
                case YAFFS_OBJECT_TYPE_SYMLINK:
@@ -2258,7 +2274,7 @@ static yaffs_Object *yaffs_MknodObject(yaffs_ObjectType type,
                                       const YCHAR * aliasString, __u32 rdev)
 {
        yaffs_Object *in;
-       YCHAR *str;
+       YCHAR *str = NULL;
 
        yaffs_Device *dev = parent->myDev;
 
@@ -2316,7 +2332,7 @@ static yaffs_Object *yaffs_MknodObject(yaffs_ObjectType type,
                            equivalentObject;
                        in->variant.hardLinkVariant.equivalentObjectId =
                            equivalentObject->objectId;
-                       list_add(&in->hardLinks, &equivalentObject->hardLinks);
+                       ylist_add(&in->hardLinks, &equivalentObject->hardLinks);
                        break;
                case YAFFS_OBJECT_TYPE_FILE:
                case YAFFS_OBJECT_TYPE_DIRECTORY:
@@ -2477,7 +2493,7 @@ int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName,
                existingTarget = yaffs_FindObjectByName(newDir, newName);
                if (existingTarget &&
                    existingTarget->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
-                   !list_empty(&existingTarget->variant.directoryVariant.children)) {
+                   !ylist_empty(&existingTarget->variant.directoryVariant.children)) {
                        /* There is a target that is a non-empty directory, so we fail */
                        return YAFFS_FAIL;      /* EEXIST or ENOTEMPTY */
                } else if (existingTarget && existingTarget != obj) {
@@ -3091,7 +3107,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block)
                                                yaffs_ObjectHeader *oh;
                                                oh = (yaffs_ObjectHeader *)buffer;
                                                oh->isShrink = 0;
-                                               oh->shadowsObject = -1;
+                                               oh->shadowsObject = oh->inbandShadowsObject = -1;
                                                tags.extraShadows = 0;
                                                tags.extraIsShrinkHeader = 0;
 
@@ -3682,7 +3698,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object * in, const YCHAR * name, int force,
 
                oh->type = in->variantType;
                oh->yst_mode = in->yst_mode;
-               oh->shadowsObject = shadows;
+               oh->shadowsObject = oh->inbandShadowsObject = shadows;
 
 #ifdef CONFIG_YAFFS_WINCE
                oh->win_atime[0] = in->win_atime[0];
@@ -4376,7 +4392,7 @@ static int yaffs_WriteCheckpointObjects(yaffs_Device *dev)
        yaffs_CheckpointObject cp;
        int i;
        int ok = 1;
-       struct list_head *lh;
+       struct ylist_head *lh;
 
 
        /* Iterate through the objects in each hash entry,
@@ -4384,9 +4400,9 @@ static int yaffs_WriteCheckpointObjects(yaffs_Device *dev)
         */
 
         for(i = 0; ok &&  i <  YAFFS_NOBJECT_BUCKETS; i++){
-               list_for_each(lh, &dev->objectBucket[i].list) {
+               ylist_for_each(lh, &dev->objectBucket[i].list) {
                        if (lh) {
-                               obj = list_entry(lh, yaffs_Object, hashLink);
+                               obj = ylist_entry(lh, yaffs_Object, hashLink);
                                if (!obj->deferedFree) {
                                        yaffs_ObjectToCheckpointObject(&cp,obj);
                                        cp.structType = sizeof(cp);
@@ -4444,7 +4460,7 @@ static int yaffs_ReadCheckpointObjects(yaffs_Device *dev)
                                        ok = yaffs_ReadCheckpointTnodes(obj);
                                } else if(obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
                                        obj->hardLinks.next =
-                                                   (struct list_head *)
+                                                   (struct ylist_head *)
                                                    hardList;
                                        hardList = obj;
                                }
@@ -4650,7 +4666,7 @@ int yaffs_ReadDataFromFile(yaffs_Object * in, __u8 * buffer, loff_t offset,
 {
 
        int chunk;
-       int start;
+       __u32 start;
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
@@ -4678,10 +4694,10 @@ int yaffs_ReadDataFromFile(yaffs_Object * in, __u8 * buffer, loff_t offset,
                cache = yaffs_FindChunkCache(in, chunk);
 
                /* If the chunk is already in the cache or it is less than a whole chunk
-                * then use the cache (if there is caching)
+                * or we're using inband tags then use the cache (if there is caching)
                 * else bypass the cache.
                 */
-               if (cache || nToCopy != dev->nDataBytesPerChunk) {
+               if (cache || nToCopy != dev->nDataBytesPerChunk || dev->inbandTags) {
                        if (dev->nShortOpCaches > 0) {
 
                                /* If we can't find the data in the cache, then load it up. */
@@ -4770,7 +4786,7 @@ int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset,
 {
 
        int chunk;
-       int start;
+       __u32 start;
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
@@ -4818,8 +4834,10 @@ int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset,
                        nToWriteBack = dev->nDataBytesPerChunk;
                }
 
-               if (nToCopy != dev->nDataBytesPerChunk) {
-                       /* An incomplete start or end chunk (or maybe both start and end chunk) */
+               if (nToCopy != dev->nDataBytesPerChunk || dev->inbandTags) {
+                       /* An incomplete start or end chunk (or maybe both start and end chunk), 
+                        * or we're using inband tags, so we want to use the cache buffers.
+                        */
                        if (dev->nShortOpCaches > 0) {
                                yaffs_ChunkCache *cache;
                                /* If we can't find the data in the cache, then load the cache */
@@ -4907,7 +4925,8 @@ int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset,
                        }
 
                } else {
-
+                       /* A full chunk. Write directly from the supplied buffer. */
+                       
 #ifdef CONFIG_YAFFS_WINCE
                        /* Under WinCE can't do direct transfer. Need to use a local buffer.
                         * This is because we otherwise screw up WinCE's memory mapper
@@ -4926,7 +4945,7 @@ int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset,
                                                         0);
                        yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__);
 #else
-                       /* A full chunk. Write directly from the supplied buffer. */
+
                        chunkWritten =
                            yaffs_WriteChunkDataToObject(in, chunk, buffer,
                                                         dev->nDataBytesPerChunk,
@@ -5004,7 +5023,7 @@ int yaffs_ResizeFile(yaffs_Object * in, loff_t newSize)
 {
 
        int oldFileSize = in->variant.fileVariant.fileSize;
-       int newSizeOfPartialChunk;
+       __u32 newSizeOfPartialChunk;
        int newFullChunks;
 
        yaffs_Device *dev = in->myDev;
@@ -5017,11 +5036,11 @@ int yaffs_ResizeFile(yaffs_Object * in, loff_t newSize)
        yaffs_CheckGarbageCollection(dev);
 
        if (in->variantType != YAFFS_OBJECT_TYPE_FILE) {
-               return yaffs_GetFileSize(in);
+               return YAFFS_FAIL;
        }
 
        if (newSize == oldFileSize) {
-               return oldFileSize;
+               return YAFFS_OK;
        }
 
        if (newSize < oldFileSize) {
@@ -5119,7 +5138,7 @@ static int yaffs_DoGenericObjectDeletion(yaffs_Object * in)
 
        if (in->myDev->isYaffs2 && (in->parent != in->myDev->deletedDir)) {
                /* Move to the unlinked directory so we have a record that it was deleted. */
-               yaffs_ChangeObjectName(in, in->myDev->deletedDir,"deleted", 0, 0);
+               yaffs_ChangeObjectName(in, in->myDev->deletedDir,_Y("deleted"), 0, 0);
 
        }
 
@@ -5157,7 +5176,7 @@ static int yaffs_UnlinkFile(yaffs_Object * in)
                if (immediateDeletion) {
                        retVal =
                            yaffs_ChangeObjectName(in, in->myDev->deletedDir,
-                                                  "deleted", 0, 0);
+                                                  _Y("deleted"), 0, 0);
                        T(YAFFS_TRACE_TRACING,
                          (TSTR("yaffs: immediate deletion of file %d" TENDSTR),
                           in->objectId));
@@ -5170,7 +5189,7 @@ static int yaffs_UnlinkFile(yaffs_Object * in)
                } else {
                        retVal =
                            yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,
-                                                  "unlinked", 0, 0);
+                                                  _Y("unlinked"), 0, 0);
                }
 
        }
@@ -5205,7 +5224,7 @@ int yaffs_DeleteFile(yaffs_Object * in)
 static int yaffs_DeleteDirectory(yaffs_Object * in)
 {
        /* First check that the directory is empty. */
-       if (list_empty(&in->variant.directoryVariant.children)) {
+       if (ylist_empty(&in->variant.directoryVariant.children)) {
                return yaffs_DoGenericObjectDeletion(in);
        }
 
@@ -5225,7 +5244,7 @@ static int yaffs_DeleteHardLink(yaffs_Object * in)
        /* remove this hardlink from the list assocaited with the equivalent
         * object
         */
-       list_del(&in->hardLinks);
+       ylist_del(&in->hardLinks);
        return yaffs_DoGenericObjectDeletion(in);
 }
 
@@ -5257,7 +5276,7 @@ static int yaffs_UnlinkWorker(yaffs_Object * obj)
 
        if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
                return yaffs_DeleteHardLink(obj);
-       } else if (!list_empty(&obj->hardLinks)) {
+       } else if (!ylist_empty(&obj->hardLinks)) {
                /* Curve ball: We're unlinking an object that has a hardlink.
                 *
                 * This problem arises because we are not strictly following
@@ -5276,10 +5295,10 @@ static int yaffs_UnlinkWorker(yaffs_Object * obj)
                int retVal;
                YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
 
-               hl = list_entry(obj->hardLinks.next, yaffs_Object, hardLinks);
+               hl = ylist_entry(obj->hardLinks.next, yaffs_Object, hardLinks);
 
-               list_del_init(&hl->hardLinks);
-               list_del_init(&hl->siblings);
+               ylist_del_init(&hl->hardLinks);
+               ylist_del_init(&hl->siblings);
 
                yaffs_GetObjectName(hl, name, YAFFS_MAX_NAME_LENGTH + 1);
 
@@ -5386,13 +5405,13 @@ static void yaffs_HardlinkFixup(yaffs_Device *dev, yaffs_Object *hardList)
                if (in) {
                        /* Add the hardlink pointers */
                        hl->variant.hardLinkVariant.equivalentObject = in;
-                       list_add(&hl->hardLinks, &in->hardLinks);
+                       ylist_add(&hl->hardLinks, &in->hardLinks);
                } else {
                        /* Todo Need to report/handle this better.
                         * Got a problem... hardlink to a non-existant object
                         */
                        hl->variant.hardLinkVariant.equivalentObject = NULL;
-                       INIT_LIST_HEAD(&hl->hardLinks);
+                       YINIT_LIST_HEAD(&hl->hardLinks);
 
                }
 
@@ -5432,7 +5451,7 @@ static int yaffs_Scan(yaffs_Device * dev)
        yaffs_BlockState state;
        yaffs_Object *hardList = NULL;
        yaffs_BlockInfo *bi;
-       int sequenceNumber;
+       __u32 sequenceNumber;
        yaffs_ObjectHeader *oh;
        yaffs_Object *in;
        yaffs_Object *parent;
@@ -5609,8 +5628,7 @@ static int yaffs_Scan(yaffs_Device * dev)
                                                bi->sequenceNumber)) {
                                                T(YAFFS_TRACE_ALWAYS,
                                                  (TSTR
-                                                  ("yaffs: Allocation block %d was not highest sequence id:"
-                                                   " block seq = %d, dev seq = %d"
+                                                  ("yaffs: Allocation block %d was not highest sequence id: block seq = %d, dev seq = %d"
                                                    TENDSTR), blk,bi->sequenceNumber,dev->sequenceNumber));
                                        }
                                }
@@ -5784,7 +5802,7 @@ static int yaffs_Scan(yaffs_Device * dev)
                                                /* Set up as a directory */
                                                parent->variantType =
                                                    YAFFS_OBJECT_TYPE_DIRECTORY;
-                                               INIT_LIST_HEAD(&parent->variant.
+                                               YINIT_LIST_HEAD(&parent->variant.
                                                               directoryVariant.
                                                               children);
                                        } else if (parent->variantType !=
@@ -5796,8 +5814,7 @@ static int yaffs_Scan(yaffs_Device * dev)
 
                                                T(YAFFS_TRACE_ERROR,
                                                  (TSTR
-                                                  ("yaffs tragedy: attempting to use non-directory as"
-                                                   " a directory in scan. Put in lost+found."
+                                                  ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
                                                    TENDSTR)));
                                                parent = dev->lostNFoundDir;
                                        }
@@ -5842,7 +5859,7 @@ static int yaffs_Scan(yaffs_Device * dev)
                                                    equivalentObjectId =
                                                    oh->equivalentObjectId;
                                                in->hardLinks.next =
-                                                   (struct list_head *)
+                                                   (struct ylist_head *)
                                                    hardList;
                                                hardList = in;
                                                break;
@@ -5901,16 +5918,16 @@ static int yaffs_Scan(yaffs_Device * dev)
         * just delete them.
         */
        {
-               struct list_head *i;
-               struct list_head *n;
+               struct ylist_head *i;
+               struct ylist_head *n;
 
                yaffs_Object *l;
                /* Soft delete all the unlinked files */
-               list_for_each_safe(i, n,
+               ylist_for_each_safe(i, n,
                                   &dev->unlinkedDir->variant.directoryVariant.
                                   children) {
                        if (i) {
-                               l = list_entry(i, yaffs_Object, siblings);
+                               l = ylist_entry(i, yaffs_Object, siblings);
                                yaffs_DestroyObject(l);
                        }
                }
@@ -5999,7 +6016,7 @@ static int yaffs_ScanBackwards(yaffs_Device * dev)
        yaffs_BlockState state;
        yaffs_Object *hardList = NULL;
        yaffs_BlockInfo *bi;
-       int sequenceNumber;
+       __u32 sequenceNumber;
        yaffs_ObjectHeader *oh;
        yaffs_Object *in;
        yaffs_Object *parent;
@@ -6328,6 +6345,12 @@ static int yaffs_ScanBackwards(yaffs_Device * dev)
                                                                        NULL);
 
                                        oh = (yaffs_ObjectHeader *) chunkData;
+                                       
+                                       if(dev->inbandTags){
+                                               /* Fix up the header if they got corrupted by inband tags */
+                                               oh->shadowsObject = oh->inbandShadowsObject;
+                                               oh->isShrink = oh->inbandIsShrink;
+                                       }
 
                                        if (!in)
                                                in = yaffs_FindOrCreateObjectByNumber(dev, tags.objectId, oh->type);
@@ -6338,8 +6361,7 @@ static int yaffs_ScanBackwards(yaffs_Device * dev)
                                        /* TODO Hoosterman we have a problem! */
                                        T(YAFFS_TRACE_ERROR,
                                          (TSTR
-                                          ("yaffs tragedy: Could not make object for object  %d  "
-                                           "at chunk %d during scan"
+                                          ("yaffs tragedy: Could not make object for object  %d at chunk %d during scan"
                                            TENDSTR), tags.objectId, chunk));
 
                                }
@@ -6497,7 +6519,7 @@ static int yaffs_ScanBackwards(yaffs_Device * dev)
                                                /* Set up as a directory */
                                                parent->variantType =
                                                    YAFFS_OBJECT_TYPE_DIRECTORY;
-                                               INIT_LIST_HEAD(&parent->variant.
+                                               YINIT_LIST_HEAD(&parent->variant.
                                                               directoryVariant.
                                                               children);
                                        } else if (parent->variantType !=
@@ -6509,8 +6531,7 @@ static int yaffs_ScanBackwards(yaffs_Device * dev)
 
                                                T(YAFFS_TRACE_ERROR,
                                                  (TSTR
-                                                  ("yaffs tragedy: attempting to use non-directory as"
-                                                   " a directory in scan. Put in lost+found."
+                                                  ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
                                                    TENDSTR)));
                                                parent = dev->lostNFoundDir;
                                        }
@@ -6561,7 +6582,7 @@ static int yaffs_ScanBackwards(yaffs_Device * dev)
                                                  in->variant.hardLinkVariant.equivalentObjectId =
                                                    equivalentObjectId;
                                                  in->hardLinks.next =
-                                                   (struct list_head *) hardList;
+                                                   (struct ylist_head *) hardList;
                                                  hardList = in;
                                                }
                                                break;
@@ -6621,27 +6642,27 @@ static int yaffs_ScanBackwards(yaffs_Device * dev)
        *  Sort out state of unlinked and deleted objects.
        */
        {
-               struct list_head *i;
-               struct list_head *n;
+               struct ylist_head *i;
+               struct ylist_head *n;
 
                yaffs_Object *l;
 
                /* Soft delete all the unlinked files */
-               list_for_each_safe(i, n,
+               ylist_for_each_safe(i, n,
                                   &dev->unlinkedDir->variant.directoryVariant.
                                   children) {
                        if (i) {
-                               l = list_entry(i, yaffs_Object, siblings);
+                               l = ylist_entry(i, yaffs_Object, siblings);
                                yaffs_DestroyObject(l);
                        }
                }
 
                /* Soft delete all the deletedDir files */
-               list_for_each_safe(i, n,
+               ylist_for_each_safe(i, n,
                                   &dev->deletedDir->variant.directoryVariant.
                                   children) {
                        if (i) {
-                               l = list_entry(i, yaffs_Object, siblings);
+                               l = ylist_entry(i, yaffs_Object, siblings);
                                yaffs_DestroyObject(l);
 
                        }
@@ -6668,7 +6689,7 @@ static void yaffs_RemoveObjectFromDirectory(yaffs_Object * obj)
        if(dev && dev->removeObjectCallback)
                dev->removeObjectCallback(obj);
 
-       list_del_init(&obj->siblings);
+       ylist_del_init(&obj->siblings);
        obj->parent = NULL;
 }
 
@@ -6694,14 +6715,14 @@ static void yaffs_AddObjectToDirectory(yaffs_Object * directory,
 
        if (obj->siblings.prev == NULL) {
                /* Not initialised */
-               INIT_LIST_HEAD(&obj->siblings);
+               YINIT_LIST_HEAD(&obj->siblings);
 
-       } else if (!list_empty(&obj->siblings)) {
+       } else if (!ylist_empty(&obj->siblings)) {
                /* If it is holed up somewhere else, un hook it */
                yaffs_RemoveObjectFromDirectory(obj);
        }
        /* Now add it */
-       list_add(&obj->siblings, &directory->variant.directoryVariant.children);
+       ylist_add(&obj->siblings, &directory->variant.directoryVariant.children);
        obj->parent = directory;
 
        if (directory == obj->myDev->unlinkedDir
@@ -6717,7 +6738,7 @@ yaffs_Object *yaffs_FindObjectByName(yaffs_Object * directory,
 {
        int sum;
 
-       struct list_head *i;
+       struct ylist_head *i;
        YCHAR buffer[YAFFS_MAX_NAME_LENGTH + 1];
 
        yaffs_Object *l;
@@ -6742,9 +6763,9 @@ yaffs_Object *yaffs_FindObjectByName(yaffs_Object * directory,
 
        sum = yaffs_CalcNameSum(name);
 
-       list_for_each(i, &directory->variant.directoryVariant.children) {
+       ylist_for_each(i, &directory->variant.directoryVariant.children) {
                if (i) {
-                       l = list_entry(i, yaffs_Object, siblings);
+                       l = ylist_entry(i, yaffs_Object, siblings);
 
                        yaffs_CheckObjectDetailsLoaded(l);
 
@@ -6776,7 +6797,7 @@ yaffs_Object *yaffs_FindObjectByName(yaffs_Object * directory,
 int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir,
                                   int (*fn) (yaffs_Object *))
 {
-       struct list_head *i;
+       struct ylist_head *i;
        yaffs_Object *l;
 
        if (!theDir) {
@@ -6793,9 +6814,9 @@ int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir,
                YBUG();
        }
 
-       list_for_each(i, &theDir->variant.directoryVariant.children) {
+       ylist_for_each(i, &theDir->variant.directoryVariant.children) {
                if (i) {
-                       l = list_entry(i, yaffs_Object, siblings);
+                       l = ylist_entry(i, yaffs_Object, siblings);
                        if (l && !fn(l)) {
                                return YAFFS_FAIL;
                        }
@@ -6884,12 +6905,12 @@ int yaffs_GetObjectFileLength(yaffs_Object * obj)
 int yaffs_GetObjectLinkCount(yaffs_Object * obj)
 {
        int count = 0;
-       struct list_head *i;
+       struct ylist_head *i;
 
        if (!obj->unlinked) {
                count++;        /* the object itself */
        }
-       list_for_each(i, &obj->hardLinks) {
+       ylist_for_each(i, &obj->hardLinks) {
                count++;        /* add the hard links; */
        }
        return count;
@@ -7112,8 +7133,9 @@ int yaffs_GutsInitialise(yaffs_Device * dev)
 
        /* Check geometry parameters. */
 
-       if ((dev->isYaffs2 && dev->nDataBytesPerChunk < 1024) ||
-           (!dev->isYaffs2 && dev->nDataBytesPerChunk != 512) ||
+       if ((!dev->inbandTags && dev->isYaffs2 && dev->totalBytesPerChunk < 1024) ||
+           (!dev->isYaffs2 && dev->totalBytesPerChunk != 512) ||
+           (dev->inbandTags && !dev->isYaffs2 ) ||
             dev->nChunksPerBlock < 2 ||
             dev->nReservedBlocks < 2 ||
             dev->internalStartBlock <= 0 ||
@@ -7122,8 +7144,8 @@ int yaffs_GutsInitialise(yaffs_Device * dev)
            ) {
                T(YAFFS_TRACE_ALWAYS,
                  (TSTR
-                  ("yaffs: NAND geometry problems: chunk size %d, type is yaffs%s "
-                   TENDSTR), dev->nDataBytesPerChunk, dev->isYaffs2 ? "2" : ""));
+                  ("yaffs: NAND geometry problems: chunk size %d, type is yaffs%s, inbandTags %d "
+                   TENDSTR), dev->totalBytesPerChunk, dev->isYaffs2 ? "2" : "", dev->inbandTags));
                return YAFFS_FAIL;
        }
 
@@ -7132,6 +7154,12 @@ int yaffs_GutsInitialise(yaffs_Device * dev)
                  (TSTR("yaffs: InitialiseNAND failed" TENDSTR)));
                return YAFFS_FAIL;
        }
+       
+       /* Sort out space for inband tags, if required */
+       if(dev->inbandTags)
+               dev->nDataBytesPerChunk = dev->totalBytesPerChunk - sizeof(yaffs_PackedTags2TagsPart);
+       else 
+               dev->nDataBytesPerChunk = dev->totalBytesPerChunk;
 
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
@@ -7167,22 +7195,14 @@ int yaffs_GutsInitialise(yaffs_Device * dev)
        /*
         *  Calculate all the chunk size manipulation numbers:
         */
-        /* Start off assuming it is a power of 2 */
-        dev->chunkShift = ShiftDiv(dev->nDataBytesPerChunk);
-        dev->chunkMask = (1<<dev->chunkShift) - 1;
-
-        if(dev->nDataBytesPerChunk == (dev->chunkMask + 1)){
-               /* Yes it is a power of 2, disable crumbs */
-               dev->crumbMask = 0;
-               dev->crumbShift = 0;
-               dev->crumbsPerChunk = 0;
-        } else {
-               /* Not a power of 2, use crumbs instead */
-               dev->crumbShift = ShiftDiv(sizeof(yaffs_PackedTags2TagsPart));
-               dev->crumbMask = (1<<dev->crumbShift)-1;
-               dev->crumbsPerChunk = dev->nDataBytesPerChunk/(1 << dev->crumbShift);
-               dev->chunkShift = 0;
-               dev->chunkMask = 0;
+        {
+               __u32 x = dev->nDataBytesPerChunk;
+                /* We always use dev->chunkShift and dev->chunkDiv */
+                dev->chunkShift = Shifts(x);
+                x >>= dev->chunkShift;
+                dev->chunkDiv = x;
+                /* We only use chunk mask if chunkDiv is 1 */
+                dev->chunkMask = (1<<dev->chunkShift) - 1;
        }
 
 
@@ -7266,7 +7286,7 @@ int yaffs_GutsInitialise(yaffs_Device * dev)
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
-               __u8 *buf;
+               void *buf;
                int srCacheBytes = dev->nShortOpCaches * sizeof(yaffs_ChunkCache);
 
                if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES) {
@@ -7282,7 +7302,7 @@ int yaffs_GutsInitialise(yaffs_Device * dev)
                        dev->srCache[i].object = NULL;
                        dev->srCache[i].lastUse = 0;
                        dev->srCache[i].dirty = 0;
-                       dev->srCache[i].data = buf = YMALLOC_DMA(dev->nDataBytesPerChunk);
+                       dev->srCache[i].data = buf = YMALLOC_DMA(dev->totalBytesPerChunk);
                }
                if(!buf)
                        init_failed = 1;
@@ -7408,6 +7428,7 @@ void yaffs_Deinitialise(yaffs_Device * dev)
                        YFREE(dev->tempBuffer[i].buffer);
                }
 
+
                dev->isMounted = 0;
        }
 
@@ -7511,22 +7532,25 @@ static void yaffs_VerifyFreeChunks(yaffs_Device * dev)
 /*---------------------------------------- YAFFS test code ----------------------*/
 
 #define yaffs_CheckStruct(structure,syze, name) \
+       do { \
            if(sizeof(structure) != syze) \
               { \
                 T(YAFFS_TRACE_ALWAYS,(TSTR("%s should be %d but is %d\n" TENDSTR),\
                 name,syze,sizeof(structure))); \
                 return YAFFS_FAIL; \
-               }
+               } \
+       } while(0)
 
 static int yaffs_CheckStructures(void)
 {
-/*      yaffs_CheckStruct(yaffs_Tags,8,"yaffs_Tags") */
-/*      yaffs_CheckStruct(yaffs_TagsUnion,8,"yaffs_TagsUnion") */
-/*      yaffs_CheckStruct(yaffs_Spare,16,"yaffs_Spare") */
+/*      yaffs_CheckStruct(yaffs_Tags,8,"yaffs_Tags"); */
+/*      yaffs_CheckStruct(yaffs_TagsUnion,8,"yaffs_TagsUnion"); */
+/*      yaffs_CheckStruct(yaffs_Spare,16,"yaffs_Spare"); */
 #ifndef CONFIG_YAFFS_TNODE_LIST_DEBUG
-       yaffs_CheckStruct(yaffs_Tnode, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_Tnode")
+       yaffs_CheckStruct(yaffs_Tnode, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_Tnode");
+#endif
+#ifndef CONFIG_YAFFS_WINCE
+               yaffs_CheckStruct(yaffs_ObjectHeader, 512, "yaffs_ObjectHeader");
 #endif
-           yaffs_CheckStruct(yaffs_ObjectHeader, 512, "yaffs_ObjectHeader")
-
            return YAFFS_OK;
 }
index cf89ef5..b9b2ea1 100644 (file)
@@ -90,7 +90,7 @@
 
 #define YAFFS_MAX_SHORT_OP_CACHES      20
 
-#define YAFFS_N_TEMP_BUFFERS           4
+#define YAFFS_N_TEMP_BUFFERS           6
 
 /* We limit the number attempts at sucessfully saving a chunk of data.
  * Small-page devices have 32 pages per block; large-page devices have 64.
@@ -331,11 +331,14 @@ typedef struct {
        __u32 win_ctime[2];
        __u32 win_atime[2];
        __u32 win_mtime[2];
-       __u32 roomToGrow[4];
 #else
-       __u32 roomToGrow[10];
+       __u32 roomToGrow[6];
+
 #endif
+       __u32 inbandShadowsObject;
+       __u32 inbandIsShrink;
 
+       __u32 reservedSpace[2];
        int shadowsObject;      /* This object header shadows the specified object if > 0 */
 
        /* isShrink applies to object headers written when we shrink the file (ie resize) */
@@ -381,7 +384,7 @@ typedef struct {
 } yaffs_FileStructure;
 
 typedef struct {
-       struct list_head children;      /* list of child links */
+       struct ylist_head children;     /* list of child links */
 } yaffs_DirectoryStructure;
 
 typedef struct {
@@ -424,14 +427,14 @@ struct yaffs_ObjectStruct {
 
        struct yaffs_DeviceStruct *myDev;       /* The device I'm on */
 
-       struct list_head hashLink;      /* list of objects in this hash bucket */
+       struct ylist_head hashLink;     /* list of objects in this hash bucket */
 
-       struct list_head hardLinks;     /* all the equivalent hard linked objects */
+       struct ylist_head hardLinks;    /* all the equivalent hard linked objects */
 
        /* directory structure stuff */
        /* also used for linking up the free list */
        struct yaffs_ObjectStruct *parent;
-       struct list_head siblings;
+       struct ylist_head siblings;
 
        /* Where's my object header in NAND? */
        int chunkId;
@@ -485,7 +488,7 @@ struct yaffs_ObjectList_struct {
 typedef struct yaffs_ObjectList_struct yaffs_ObjectList;
 
 typedef struct {
-       struct list_head list;
+       struct ylist_head list;
        int count;
 } yaffs_ObjectBucket;
 
@@ -528,7 +531,7 @@ typedef struct {
 /*----------------- Device ---------------------------------*/
 
 struct yaffs_DeviceStruct {
-       struct list_head devList;
+       struct ylist_head devList;
        const char *name;
 
        /* Entry parameters set up way early. Yaffs sets up the rest.*/
@@ -583,7 +586,7 @@ struct yaffs_DeviceStruct {
                                          yaffs_ExtendedTags * tags);
        int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo);
        int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo,
-                              yaffs_BlockState * state, int *sequenceNumber);
+                              yaffs_BlockState * state, __u32 *sequenceNumber);
 #endif
 
        int isYaffs2;
@@ -598,7 +601,8 @@ struct yaffs_DeviceStruct {
        void (*markSuperBlockDirty)(void * superblock);
 
        int wideTnodesDisabled; /* Set to disable wide tnodes */
-
+       
+       YCHAR *pathDividers;    /* String of legal path dividers */
 
        /* End of stuff that must be set before initialisation. */
 
@@ -615,16 +619,14 @@ struct yaffs_DeviceStruct {
        __u32 tnodeWidth;
        __u32 tnodeMask;
 
-       /* Stuff to support various file offses to chunk/offset translations */
-       /* "Crumbs" for nDataBytesPerChunk not being a power of 2 */
-       __u32 crumbMask;
-       __u32 crumbShift;
-       __u32 crumbsPerChunk;
-
-       /* Straight shifting for nDataBytesPerChunk being a power of 2 */
-       __u32 chunkShift;
-       __u32 chunkMask;
+       /* Stuff for figuring out file offset to chunk conversions */
+       __u32 chunkShift; /* Shift value */
+       __u32 chunkDiv;   /* Divisor after shifting: 1 for power-of-2 sizes */
+       __u32 chunkMask;  /* Mask to use for power-of-2 case */
 
+       /* Stuff to handle inband tags */
+       int inbandTags;
+       __u32 totalBytesPerChunk;
 
 #ifdef __KERNEL__
 
@@ -746,9 +748,11 @@ struct yaffs_DeviceStruct {
        int nUnlinkedFiles;             /* Count of unlinked files. */
        int nBackgroundDeletions;       /* Count of background deletions. */
 
-
+       
+       /* Temporary buffer management */
        yaffs_TempBuffer tempBuffer[YAFFS_N_TEMP_BUFFERS];
        int maxTemp;
+       int tempInUse;
        int unmanagedTempAllocations;
        int unmanagedTempDeallocations;
 
@@ -799,18 +803,6 @@ typedef struct {
     __u32 head;
 } yaffs_CheckpointValidity;
 
-/* Function to manipulate block info */
-static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk)
-{
-       if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
-               T(YAFFS_TRACE_ERROR,
-                 (TSTR
-                  ("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),
-                  blk));
-               YBUG();
-       }
-       return &dev->blockInfo[blk - dev->internalStartBlock];
-}
 
 /*----------------------- YAFFS Functions -----------------------*/
 
@@ -901,4 +893,7 @@ void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn);
 int yaffs_CheckFF(__u8 * buffer, int nBytes);
 void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
 
+__u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo);
+void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer, int lineNo);
+
 #endif
index 125ed40..3768b9b 100644 (file)
@@ -14,7 +14,7 @@
 /* mtd interface for YAFFS2 */
 
 const char *yaffs_mtdif2_c_version =
-    "$Id: yaffs_mtdif2.c,v 1.19 2007-12-13 15:35:18 wookey Exp $";
+    "$Id: yaffs_mtdif2.c,v 1.20 2008-05-05 07:58:58 charles Exp $";
 
 #include "yportenv.h"
 
@@ -27,6 +27,10 @@ const char *yaffs_mtdif2_c_version =
 
 #include "yaffs_packedtags2.h"
 
+/* NB For use with inband tags....
+ * We assume that the data buffer is of size totalBytersPerChunk so that we can also
+ * use it to load the tags.
+ */
 int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
                                      const __u8 * data,
                                      const yaffs_ExtendedTags * tags)
@@ -39,7 +43,7 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
 #endif
        int retval = 0;
 
-       loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
+       loff_t addr;
 
        yaffs_PackedTags2 pt;
 
@@ -47,47 +51,42 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
          (TSTR
           ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
            TENDSTR), chunkInNAND, data, tags));
-
-#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-       if (tags)
-               yaffs_PackTags2(&pt, tags);
+           
+
+       addr  = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
+       
+       /* For yaffs2 writing there must be both data and tags.
+        * If we're using inband tags, then the tags are stuffed into
+        * the end of the data buffer.
+        */
+       if(!data || !tags)
+               BUG();  
+       else if(dev->inbandTags){
+               yaffs_PackedTags2TagsPart *pt2tp;
+               pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk);
+               yaffs_PackTags2TagsPart(pt2tp,tags);
+       }
        else
-               BUG(); /* both tags and data should always be present */
-
-       if (data) {
-               ops.mode = MTD_OOB_AUTO;
-               ops.ooblen = sizeof(pt);
-               ops.len = dev->nDataBytesPerChunk;
-               ops.ooboffs = 0;
-               ops.datbuf = (__u8 *)data;
-               ops.oobbuf = (void *)&pt;
-               retval = mtd->write_oob(mtd, addr, &ops);
-       } else
-               BUG(); /* both tags and data should always be present */
-#else
-       if (tags) {
                yaffs_PackTags2(&pt, tags);
-       }
+       
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+       ops.mode = MTD_OOB_AUTO;
+       ops.ooblen = (dev->inbandTags) ? 0 : sizeof(pt);
+       ops.len = dev->totalBytesPerChunk;
+       ops.ooboffs = 0;
+       ops.datbuf = (__u8 *)data;
+       ops.oobbuf = (dev->inbandTags) ? NULL : (void *)&pt;
+       retval = mtd->write_oob(mtd, addr, &ops);
 
-       if (data && tags) {
-               if (dev->useNANDECC)
-                       retval =
-                           mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
-                                          &dummy, data, (__u8 *) & pt, NULL);
-               else
-                       retval =
-                           mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
-                                          &dummy, data, (__u8 *) & pt, NULL);
+#else
+       if (!dev->inbandTags) {
+               retval =
+                   mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
+                                  &dummy, data, (__u8 *) & pt, NULL);
        } else {
-               if (data)
-                       retval =
-                           mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy,
-                                      data);
-               if (tags)
-                       retval =
-                           mtd->write_oob(mtd, addr, mtd->oobsize, &dummy,
-                                          (__u8 *) & pt);
-
+               retval =
+                   mtd->write(mtd, addr, dev->totalBytesPerChunk, &dummy,
+                              data);
        }
 #endif
 
@@ -106,6 +105,7 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
 #endif
        size_t dummy;
        int retval = 0;
+       int localData = 0;
 
        loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
 
@@ -115,10 +115,21 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
          (TSTR
           ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p"
            TENDSTR), chunkInNAND, data, tags));
+           
+       if(dev->inbandTags){
+               
+               if(!data) {
+                       localData = 1;
+                       data = yaffs_GetTempBuffer(dev,__LINE__);
+               }
+               
 
-#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-       if (data && !tags)
-               retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
+       }
+
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+       if (dev->inbandTags || (data && !tags))
+               retval = mtd->read(mtd, addr, dev->totalBytesPerChunk,
                                &dummy, data);
        else if (tags) {
                ops.mode = MTD_OOB_AUTO;
@@ -130,38 +141,43 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
                retval = mtd->read_oob(mtd, addr, &ops);
        }
 #else
-       if (data && tags) {
-               if (dev->useNANDECC) {
-                       retval =
-                           mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
-                                         &dummy, data, dev->spareBuffer,
-                                         NULL);
-               } else {
-                       retval =
-                           mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
+       if (!dev->inbandTags && data && tags) {
+
+               retval = mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
                                          &dummy, data, dev->spareBuffer,
                                          NULL);
-               }
        } else {
                if (data)
                        retval =
                            mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy,
                                      data);
-               if (tags)
+               if (!dev->inbandTags && tags)
                        retval =
                            mtd->read_oob(mtd, addr, mtd->oobsize, &dummy,
                                          dev->spareBuffer);
        }
 #endif
 
-       memcpy(&pt, dev->spareBuffer, sizeof(pt));
 
-       if (tags)
-               yaffs_UnpackTags2(tags, &pt);
+       if(dev->inbandTags){
+               if(tags){
+                       yaffs_PackedTags2TagsPart * pt2tp;
+                       pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];    
+                       yaffs_UnpackTags2TagsPart(tags,pt2tp);
+               }
+       }
+       else {
+               if (tags){
+                       memcpy(&pt, dev->spareBuffer, sizeof(pt));
+                       yaffs_UnpackTags2(tags, &pt);
+               }
+       }
 
+       if(localData)
+               yaffs_ReleaseTempBuffer(dev,data,__LINE__);
+       
        if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
-               tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
-
+               tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;             
        if (retval == 0)
                return YAFFS_OK;
        else
index 3898985..af42157 100644 (file)
  */
 
 const char *yaffs_nand_c_version =
-    "$Id: yaffs_nand.c,v 1.8 2007-12-13 15:35:18 wookey Exp $";
+    "$Id: yaffs_nand.c,v 1.9 2008-05-05 07:58:58 charles Exp $";
 
 #include "yaffs_nand.h"
 #include "yaffs_tagscompat.h"
 #include "yaffs_tagsvalidity.h"
 
+#include "yaffs_getblockinfo.h"
 
 int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
                                           __u8 * buffer,
@@ -98,7 +99,7 @@ int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo)
 int yaffs_QueryInitialBlockState(yaffs_Device * dev,
                                                 int blockNo,
                                                 yaffs_BlockState * state,
-                                                unsigned *sequenceNumber)
+                                                __u32 *sequenceNumber)
 {
        blockNo -= dev->blockOffset;
 
index cd2e96f..c8576b3 100644 (file)
 
 int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
                                        int chunkInNAND, const __u8 * data,
-                                       yaffs_ExtendedTags * tags);
+                                       const yaffs_ExtendedTags * tags);
 int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_DeviceStruct *dev,
                                         int chunkInNAND, __u8 * data,
                                         yaffs_ExtendedTags * tags);
 int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
 int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
-                             yaffs_BlockState * state, int *sequenceNumber);
+                             yaffs_BlockState * state, __u32 *sequenceNumber);
 int nandemul2k_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
                                int blockInNAND);
 int nandemul2k_InitialiseNAND(struct yaffs_DeviceStruct *dev);
index e420f95..957ed8b 100644 (file)
 #define EXTRA_OBJECT_TYPE_SHIFT (28)
 #define EXTRA_OBJECT_TYPE_MASK  ((0x0F) << EXTRA_OBJECT_TYPE_SHIFT)
 
-static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 * pt)
+
+static void yaffs_DumpPackedTags2TagsPart(const yaffs_PackedTags2TagsPart * ptt)
 {
        T(YAFFS_TRACE_MTD,
          (TSTR("packed tags obj %d chunk %d byte %d seq %d" TENDSTR),
-          pt->t.objectId, pt->t.chunkId, pt->t.byteCount,
-          pt->t.sequenceNumber));
+          ptt->objectId, ptt->chunkId, ptt->byteCount,
+          ptt->sequenceNumber));
+}
+static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 * pt)
+{
+       yaffs_DumpPackedTags2TagsPart(&pt->t);
 }
 
 static void yaffs_DumpTags2(const yaffs_ExtendedTags * t)
 {
        T(YAFFS_TRACE_MTD,
          (TSTR
-          ("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte "
-           "%d del %d ser %d seq %d"
+          ("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte %d del %d ser %d seq %d"
            TENDSTR), t->eccResult, t->blockBad, t->chunkUsed, t->objectId,
           t->chunkId, t->byteCount, t->chunkDeleted, t->serialNumber,
           t->sequenceNumber));
 
 }
 
-void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t)
+void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart * ptt, const yaffs_ExtendedTags * t)
 {
-       pt->t.chunkId = t->chunkId;
-       pt->t.sequenceNumber = t->sequenceNumber;
-       pt->t.byteCount = t->byteCount;
-       pt->t.objectId = t->objectId;
+       ptt->chunkId = t->chunkId;
+       ptt->sequenceNumber = t->sequenceNumber;
+       ptt->byteCount = t->byteCount;
+       ptt->objectId = t->objectId;
 
        if (t->chunkId == 0 && t->extraHeaderInfoAvailable) {
                /* Store the extra header info instead */
                /* We save the parent object in the chunkId */
-               pt->t.chunkId = EXTRA_HEADER_INFO_FLAG
+               ptt->chunkId = EXTRA_HEADER_INFO_FLAG
                        | t->extraParentObjectId;
                if (t->extraIsShrinkHeader) {
-                       pt->t.chunkId |= EXTRA_SHRINK_FLAG;
+                       ptt->chunkId |= EXTRA_SHRINK_FLAG;
                }
                if (t->extraShadows) {
-                       pt->t.chunkId |= EXTRA_SHADOWS_FLAG;
+                       ptt->chunkId |= EXTRA_SHADOWS_FLAG;
                }
 
-               pt->t.objectId &= ~EXTRA_OBJECT_TYPE_MASK;
-               pt->t.objectId |=
+               ptt->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
+               ptt->objectId |=
                    (t->extraObjectType << EXTRA_OBJECT_TYPE_SHIFT);
 
                if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
-                       pt->t.byteCount = t->extraEquivalentObjectId;
+                       ptt->byteCount = t->extraEquivalentObjectId;
                } else if (t->extraObjectType == YAFFS_OBJECT_TYPE_FILE) {
-                       pt->t.byteCount = t->extraFileLength;
+                       ptt->byteCount = t->extraFileLength;
                } else {
-                       pt->t.byteCount = 0;
+                       ptt->byteCount = 0;
                }
        }
 
-       yaffs_DumpPackedTags2(pt);
+       yaffs_DumpPackedTags2TagsPart(ptt);
        yaffs_DumpTags2(t);
+}
+
+
+void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t)
+{
+       yaffs_PackTags2TagsPart(&pt->t,t);
 
 #ifndef YAFFS_IGNORE_TAGS_ECC
        {
@@ -101,13 +111,60 @@ void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t)
 #endif
 }
 
-void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt)
+
+void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags * t, yaffs_PackedTags2TagsPart * ptt)
 {
 
        memset(t, 0, sizeof(yaffs_ExtendedTags));
 
        yaffs_InitialiseTags(t);
 
+       if (ptt->sequenceNumber != 0xFFFFFFFF) {
+               t->blockBad = 0;
+               t->chunkUsed = 1;
+               t->objectId = ptt->objectId;
+               t->chunkId = ptt->chunkId;
+               t->byteCount = ptt->byteCount;
+               t->chunkDeleted = 0;
+               t->serialNumber = 0;
+               t->sequenceNumber = ptt->sequenceNumber;
+
+               /* Do extra header info stuff */
+
+               if (ptt->chunkId & EXTRA_HEADER_INFO_FLAG) {
+                       t->chunkId = 0;
+                       t->byteCount = 0;
+
+                       t->extraHeaderInfoAvailable = 1;
+                       t->extraParentObjectId =
+                           ptt->chunkId & (~(ALL_EXTRA_FLAGS));
+                       t->extraIsShrinkHeader =
+                           (ptt->chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0;
+                       t->extraShadows =
+                           (ptt->chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0;
+                       t->extraObjectType =
+                           ptt->objectId >> EXTRA_OBJECT_TYPE_SHIFT;
+                       t->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
+
+                       if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
+                               t->extraEquivalentObjectId = ptt->byteCount;
+                       } else {
+                               t->extraFileLength = ptt->byteCount;
+                       }
+               }
+       }
+
+       yaffs_DumpPackedTags2TagsPart(ptt);
+       yaffs_DumpTags2(t);
+
+}
+
+
+void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt)
+{
+
+       yaffs_UnpackTags2TagsPart(t,&pt->t);
+
        if (pt->t.sequenceNumber != 0xFFFFFFFF) {
                /* Page is in use */
 #ifdef YAFFS_IGNORE_TAGS_ECC
@@ -142,41 +199,10 @@ void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt)
                        }
                }
 #endif
-               t->blockBad = 0;
-               t->chunkUsed = 1;
-               t->objectId = pt->t.objectId;
-               t->chunkId = pt->t.chunkId;
-               t->byteCount = pt->t.byteCount;
-               t->chunkDeleted = 0;
-               t->serialNumber = 0;
-               t->sequenceNumber = pt->t.sequenceNumber;
-
-               /* Do extra header info stuff */
-
-               if (pt->t.chunkId & EXTRA_HEADER_INFO_FLAG) {
-                       t->chunkId = 0;
-                       t->byteCount = 0;
-
-                       t->extraHeaderInfoAvailable = 1;
-                       t->extraParentObjectId =
-                           pt->t.chunkId & (~(ALL_EXTRA_FLAGS));
-                       t->extraIsShrinkHeader =
-                           (pt->t.chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0;
-                       t->extraShadows =
-                           (pt->t.chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0;
-                       t->extraObjectType =
-                           pt->t.objectId >> EXTRA_OBJECT_TYPE_SHIFT;
-                       t->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
-
-                       if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
-                               t->extraEquivalentObjectId = pt->t.byteCount;
-                       } else {
-                               t->extraFileLength = pt->t.byteCount;
-                       }
-               }
        }
 
        yaffs_DumpPackedTags2(pt);
        yaffs_DumpTags2(t);
 
 }
+
index c2242ff..75761d3 100644 (file)
@@ -33,6 +33,11 @@ typedef struct {
        yaffs_ECCOther ecc;
 } yaffs_PackedTags2;
 
+/* Full packed tags with ECC, used for oob tags */
 void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t);
 void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt);
+
+/* Only the tags part (no ECC for use with inband tags */
+void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart * pt, const yaffs_ExtendedTags * t);
+void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags * t, yaffs_PackedTags2TagsPart * pt);
 #endif
index 7622b1a..ab756d0 100644 (file)
@@ -14,6 +14,7 @@
 #include "yaffs_guts.h"
 #include "yaffs_tagscompat.h"
 #include "yaffs_ecc.h"
+#include "yaffs_getblockinfo.h"
 
 static void yaffs_HandleReadDataError(yaffs_Device * dev, int chunkInNAND);
 #ifdef NOTYET
@@ -438,7 +439,7 @@ int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev,
        yaffs_ECCResult eccResult;
 
        static yaffs_Spare spareFF;
-       static int init;
+       static int init = 0;
 
        if (!init) {
                memset(&spareFF, 0xFF, sizeof(spareFF));
@@ -497,9 +498,9 @@ int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
 }
 
 int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
-                                         int blockNo, yaffs_BlockState *
-                                         state,
-                                         int *sequenceNumber)
+                                         int blockNo,
+                                         yaffs_BlockState *state,
+                                         __u32 *sequenceNumber)
 {
 
        yaffs_Spare spare0, spare1;
index a61e3ba..6549398 100644 (file)
@@ -30,8 +30,9 @@ int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev,
 int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
                                            int blockNo);
 int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
-                                         int blockNo, yaffs_BlockState *
-                                         state, int *sequenceNumber);
+                                         int blockNo, 
+                                         yaffs_BlockState *state,
+                                         __u32 *sequenceNumber);
 
 void yaffs_CalcTagsECC(yaffs_Tags * tags);
 int yaffs_CheckECCOnTags(yaffs_Tags * tags);
index 6cd90da..097b2a6 100644 (file)
@@ -193,8 +193,8 @@ extern unsigned int yaffs_wr_attempts;
 
 #define T(mask,p) do{ if((mask) & (yaffs_traceMask | YAFFS_TRACE_ALWAYS)) TOUT(p);} while(0)
 
-#ifndef CONFIG_YAFFS_WINCE
-#define YBUG() T(YAFFS_TRACE_BUG,(TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR),__LINE__))
+#ifndef YBUG
+#define YBUG() do {T(YAFFS_TRACE_BUG,(TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR),__LINE__));} while(0)
 #endif
 
 #endif