Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
authorcharles <charles>
Thu, 3 Jul 2008 20:06:05 +0000 (20:06 +0000)
committercharles <charles>
Thu, 3 Jul 2008 20:06:05 +0000 (20:06 +0000)
devextras.h
direct/dtest.c
direct/yaffsfs.c
direct/yaffsfs.h
mtdemul/Makefile
mtdemul/nandemul2k.c
yaffs_fs.c
yaffs_guts.c
yaffs_guts.h

index d2abbd5b7a3d9151d16dba2ba0d867b0dea2cb23..a9366fdd2e79b182750938d655036f7928c99ceb 100644 (file)
  * published by the Free Software Foundation.
  *
  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
- */\r
-\r
-/*\r
+ */
+
+/*
  * This file is just holds extra declarations of macros that would normally
  * be providesd in the Linux kernel. These macros have been written from
  * scratch but are functionally equivalent to the Linux ones.
- *\r
- */\r
-\r
-#ifndef __EXTRAS_H__\r
-#define __EXTRAS_H__\r
-\r
-\r
-#if !(defined __KERNEL__) \r
-\r
+ *
+ */
+
+#ifndef __EXTRAS_H__
+#define __EXTRAS_H__
+
+
+#if !(defined __KERNEL__) 
+
 /* Definition of types */
-typedef unsigned char __u8;\r
-typedef unsigned short __u16;\r
-typedef unsigned __u32;\r
-\r
+typedef unsigned char __u8;
+typedef unsigned short __u16;
+typedef unsigned __u32;
+
 #endif
-\r
-/*\r
- * This is a simple doubly linked list implementation that matches the \r
- * way the Linux kernel doubly linked list implementation works.\r
- */\r
-\r
+
+/*
+ * This is a simple doubly linked list implementation that matches the 
+ * way the Linux kernel doubly linked list implementation works.
+ */
+
 struct ylist_head {
-        struct ylist_head *next; /* next in chain */
-        struct ylist_head *prev; /* previous in chain */
-};\r
-\r
-\r
-/* Initialise a list head to an empty list */\r
+       struct ylist_head *next; /* next in chain */
+       struct ylist_head *prev; /* previous in chain */
+};
+
+
+/* Initialise a static list */
+#define YLIST_HEAD(name) \
+struct ylist_head name = { &(name),&(name)}
+
+
+
+/* Initialise a list head to an empty list */
 #define YINIT_LIST_HEAD(p) \
-do { \\r
- (p)->next = (p);\\r
+do { \
+ (p)->next = (p);\
  (p)->prev = (p); \
-} while(0)\r
-\r
-\r
-/* Add an element to a list */\r
+} while(0)
+
+
+/* Add an element to a list */
 static __inline__ void ylist_add(struct ylist_head *newEntry, 
                                  struct ylist_head *list)
-{\r
+{
         struct ylist_head *listNext = list->next;
-        \r
-        list->next = newEntry;\r
-        newEntry->prev = list;\r
+        
+        list->next = newEntry;
+        newEntry->prev = list;
        newEntry->next = listNext;
        listNext->prev = newEntry;
        
 }
 
-\r
-/* Take an element out of its current list, with or without\r
- * reinitialising the links.of the entry*/\r
+static __inline__ void ylist_add_tail(struct ylist_head *newEntry, 
+                                struct ylist_head *list)
+{
+       struct ylist_head *listPrev = list->prev;
+       
+       list->prev = newEntry;
+       newEntry->next = list;
+       newEntry->prev = listPrev;
+       listPrev->next = newEntry;
+       
+}
+
+
+/* Take an element out of its current list, with or without
+ * reinitialising the links.of the entry*/
 static __inline__ void ylist_del(struct ylist_head *entry)
-{\r
+{
         struct ylist_head *listNext = entry->next;
         struct ylist_head *listPrev = entry->prev;
-        \r
-        listNext->prev = listPrev;\r
-        listPrev->next = listNext;\r
-        \r
-}\r
-\r
+        
+        listNext->prev = listPrev;
+        listPrev->next = listNext;
+        
+}
+
 static __inline__ void ylist_del_init(struct ylist_head *entry)
-{\r
+{
         ylist_del(entry);
-        entry->next = entry->prev = entry;\r
-}\r
-\r
-\r
-/* Test if the list is empty */\r
+        entry->next = entry->prev = entry;
+}
+
+
+/* Test if the list is empty */
 static __inline__ int ylist_empty(struct ylist_head *entry)
-{\r
-        return (entry->next == entry);\r
-}\r
-\r
-\r
+{
+        return (entry->next == entry);
+}
+
+
 /* 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.\r
- */\r
\r
\r
+ * we can find a pointer to the object it is embedded in.
+ */
 #define ylist_entry(entry, type, member) \
-        ((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member)))\r
-\r
-\r
+        ((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member)))
+
+
 /* ylist_for_each and list_for_each_safe  iterate over lists.
  * ylist_for_each_safe uses temporary storage to make the list delete safe
- */\r
-\r
+ */
+
 #define ylist_for_each(itervar, list) \
-        for (itervar = (list)->next; itervar != (list); itervar = itervar->next )\r
-\r
+        for (itervar = (list)->next; itervar != (list); itervar = itervar->next )
+
 #define ylist_for_each_safe(itervar,saveVar, list) \
-        for (itervar = (list)->next, saveVar = (list)->next->next; itervar != (list); \\r
-         itervar = saveVar, saveVar = saveVar->next)\r
-\r
+        for (itervar = (list)->next, saveVar = (list)->next->next; itervar != (list); \
+         itervar = saveVar, saveVar = saveVar->next)
+
 
 #if !(defined __KERNEL__)
 
@@ -122,30 +140,30 @@ static __inline__ int ylist_empty(struct ylist_head *entry)
 
 
 #ifdef CONFIG_YAFFS_PROVIDE_DEFS
-/* File types */\r
-\r
+/* File types */
 
-#define DT_UNKNOWN      0\r
-#define DT_FIFO         1\r
-#define DT_CHR          2\r
+
+#define DT_UNKNOWN      0
+#define DT_FIFO         1
+#define DT_CHR          2
 #define DT_DIR         4
 #define DT_BLK         6
-#define DT_REG          8\r
-#define DT_LNK          10\r
-#define DT_SOCK         12\r
+#define DT_REG          8
+#define DT_LNK          10
+#define DT_SOCK         12
 #define DT_WHT          14
-\r
-\r
-#ifndef WIN32\r
-#include <sys/stat.h>\r
-#endif\r
-\r
-/*\r
- * Attribute flags.  These should be or-ed together to figure out what\r
- * has been changed!\r
- */\r
-#define ATTR_MODE       1\r
-#define ATTR_UID        2\r
+
+
+#ifndef WIN32
+#include <sys/stat.h>
+#endif
+
+/*
+ * Attribute flags.  These should be or-ed together to figure out what
+ * has been changed!
+ */
+#define ATTR_MODE       1
+#define ATTR_UID        2
 #define ATTR_GID       4
 #define ATTR_SIZE      8
 #define ATTR_ATIME     16
@@ -161,21 +179,21 @@ struct iattr {
        unsigned ia_atime;
        unsigned ia_mtime;
        unsigned ia_ctime;
-        unsigned int ia_attr_flags;\r
-};\r
-\r
+        unsigned int ia_attr_flags;
+};
+
 #endif
 
 
-#define KERN_DEBUG\r
-\r
-#else\r
-\r
-#include <linux/types.h>\r
-#include <linux/fs.h>\r
-#include <linux/stat.h>\r
-\r
-#endif\r
-\r
-\r
-#endif\r
+#define KERN_DEBUG
+
+#else
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+
+#endif
+
+
+#endif
index 5b038c4b036c10971b8462d4567f890756c03b69..792c67ef35c539d7b5cd5a6021e723d9ba688101 100644 (file)
@@ -966,6 +966,7 @@ void rename_over_test(const char *mountpt)
        
 }
 
+
 int resize_stress_test(const char *path)
 {
    int a,b,i,j;
@@ -1029,6 +1030,28 @@ int resize_stress_test(const char *path)
    
 }
 
+int root_perm_remount(const char *path)
+{
+   struct yaffs_stat s;
+   
+   yaffs_StartUp();
+   
+   yaffs_mount(path);
+   
+   yaffs_stat(path,&s);
+   printf("root perms after mount %x\n",s.st_mode);
+   
+   yaffs_chmod(path, 0777);
+
+   yaffs_stat(path,&s);
+   printf("root perms after setting to 0777 is  %x\n",s.st_mode);
+   
+   yaffs_unmount(path);
+      
+   return 0;
+   
+}
+
 
 int resize_stress_test_no_grow_complex(const char *path,int iters)
 {
@@ -2259,7 +2282,8 @@ int main(int argc, char *argv[])
        
        //return cache_read_test();
        
-       //resize_stress_test_no_grow("/flash/flash",20);
+       // resize_stress_test_no_grow("/flash/flash",20);
+       //root_perm_remount("/flash/flash");
        
        //huge_directory_test_on_path("/ram2k");
        
index 6206ed427bb7dff99a9e176c1d049ed4cc61febc..119751843f0ae9d4b9225b5fa96d265fdf191ef9 100644 (file)
@@ -24,7 +24,7 @@
 #endif
 
 
-const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.20 2008-07-02 20:17:41 charles Exp $";
+const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.21 2008-07-03 20:06:05 charles Exp $";
 
 // configurationList is the list of devices that are supported
 static yaffsfs_DeviceConfiguration *yaffsfs_configurationList;
@@ -1602,6 +1602,28 @@ loff_t yaffs_totalspace(const YCHAR *path)
        return retVal;
 }
 
+int yaffs_inodecount(const YCHAR *path)
+{
+       loff_t retVal= -1;
+       yaffs_Device *dev=NULL;
+       YCHAR *dummy;
+
+       yaffsfs_Lock();
+       dev = yaffsfs_FindDevice(path,&dummy);
+       if(dev  && dev->isMounted) {
+          int nObjects = dev->nObjectsCreated - dev->nFreeObjects;
+          if(nObjects > dev->nHardLinks)
+               retVal = nObjects - dev->nHardLinks;
+       }
+       
+       if(retVal < 0){
+               yaffsfs_SetError(-EINVAL);
+       }
+       
+       yaffsfs_Unlock();
+       return retVal;  
+}
+
 
 
 void yaffs_initialise(yaffsfs_DeviceConfiguration *cfgList)
index 1c0d316a4fafaf598f793a8aba0b55f1b9c3dfd0..c05e02a6c2cf6603a7902c6e0f0e81dcb4d308bb 100644 (file)
@@ -272,6 +272,9 @@ int yaffs_mknod(const YCHAR *pathname, mode_t mode, dev_t dev);
 loff_t yaffs_freespace(const YCHAR *path);
 loff_t yaffs_totalspace(const YCHAR *path);
 
+int yaffs_inodecount(const YCHAR *path);
+
+
 void yaffs_initialise(yaffsfs_DeviceConfiguration *configList);
 
 int yaffs_StartUp(void);
index fe03b478d280da20d043ab8102d0b8f79f398bf7..eeac54e0403d8c11605b0e3121d032c9233a7423 100644 (file)
@@ -15,8 +15,9 @@
 ## Change or override  KERNELDIR to your kernel
 ## comment out USE_xxxx if you don't want these features.
 
-KERNELDIR = /usr/src/kernel-headers-2.4.27
+KERNELDIR = /opt/linux-source-2.6.24
 
+#CFLAGS = -D__KERNEL__ -DMODULE   -I$(KERNELDIR)/include -O2 -Wall -g
 CFLAGS = -D__KERNEL__ -DMODULE   -I$(KERNELDIR)/include -O2 -Wall -g
 
 
index bcbf16ad1c9c6df641ca17beada59f27d3dcccdc..7efa8d45d6e383f0764413d14e7d5f341014a99a 100644 (file)
@@ -15,7 +15,7 @@
  *  This version hacked for emulating 2kpage NAND for YAFFS2 testing.
  */
 
-#include <linux/config.h>
+//#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/version.h>
@@ -280,15 +280,10 @@ static int nandemul2k_ReadStatus(__u8 *status)
  */
 static int nand_read (struct mtd_info *mtd, loff_t from, size_t len,
                        size_t *retlen, u_char *buf);
-static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-                               size_t *retlen, u_char *buf, u_char *oob_buf, struct nand_oobinfo *dummy);
 static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
                                size_t *retlen, u_char *buf);
 static int nand_write (struct mtd_info *mtd, loff_t to, size_t len,
                        size_t *retlen, const u_char *buf);
-static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-                               size_t *retlen, const u_char *buf,
-                               u_char *oob_buf, struct nand_oobinfo *dummy);
 static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
                                size_t *retlen, const u_char *buf);
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7))
@@ -343,17 +338,17 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
 
                /* Get raw starting column */
 
-               start = from & (mtd->oobblock-1);
+               start = from & (PAGE_DATA_SIZE - 1);
 
                // OK now check for the curveball where the start and end are in
                // the same page
-               if((start + n) < mtd->oobblock)
+               if((start + n) < PAGE_DATA_SIZE)
                {
                        nToCopy = n;
                }
                else
                {
-                       nToCopy =  mtd->oobblock - start;
+                       nToCopy =  PAGE_DATA_SIZE - start;
                }
 
                nandemul2k_Read(buf, page, start, nToCopy);
@@ -386,7 +381,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
        page = ((int) from) >> NAND_SHIFT;
 
        /* Mask to get column */
-       col = from & 0x0f;
+       col = from & (PAGE_SPARE_SIZE-1)
 
        /* Initialize return length value */
        *retlen = 0;
@@ -447,17 +442,17 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
 
                /* Get raw starting column */
 
-               start = to & (mtd->oobblock - 1);
+               start = to & (PAGE_DATA_SIZE - 1);
 
                // OK now check for the curveball where the start and end are in
                // the same page
-               if((start + n) < mtd->oobblock)
+               if((start + n) < PAGE_DATA_SIZE)
                {
                        nToCopy = n;
                }
                else
                {
-                       nToCopy =  mtd->oobblock - start;
+                       nToCopy =  PAGE_DATA_SIZE - start;
                }
 
                nandemul2k_Program(buf, page, start, nToCopy);
@@ -492,7 +487,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
        page = ((int) to) >> NAND_SHIFT;
 
        /* Mask to get column */
-       col = to & 0x0f;
+       col = to & PAGE_SPARE_SIZE;
 
        /* Initialize return length value */
        *retlen = 0;
@@ -567,10 +562,9 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
                nandemul2k_DoErase(block);
                block++;
        }
-
-       instr->state = MTD_ERASE_DONE; Â * change state to ERASE_DONE */
-
-       instr->callback(instr); Â * wake up */
+       
+       instr->state = MTD_ERASE_DONE; /* Changed state to done */
+       instr->callback(instr);        /* ... and wake up */
 
        return 0;
 
@@ -603,8 +597,9 @@ static void nand_sync (struct mtd_info *mtd)
  */
 static int nandemul2k_scan (struct mtd_info *mtd,int nchips)
 {
-       mtd->oobblock = PAGE_DATA_SIZE;
-       mtd->oobsize =  PAGE_SPARE_SIZE;
+       mtd->writesize = PAGE_DATA_SIZE;
+       mtd->oobsize   = PAGE_SPARE_SIZE;
+       mtd->oobavail  = PAGE_SPARE_SIZE/2; /* Simulate using up some for other uses */
        mtd->erasesize = PAGE_DATA_SIZE * PAGES_PER_BLOCK;
        mtd->size = sizeInMB * 1024*1024;
 
@@ -614,14 +609,13 @@ static int nandemul2k_scan (struct mtd_info *mtd,int nchips)
        mtd->type = MTD_NANDFLASH;
        mtd->flags = MTD_CAP_NANDFLASH;
        mtd->owner = THIS_MODULE;
-       mtd->ecctype = MTD_ECC_NONE;
        mtd->erase = nand_erase;
        mtd->point = NULL;
        mtd->unpoint = NULL;
        mtd->read = nand_read;
        mtd->write = nand_write;
-       mtd->read_ecc = nand_read_ecc;
-       mtd->write_ecc = nand_write_ecc;
+       mtd->read_oob = nand_read_oob;
+       mtd->write_oob = nand_write_oob;
        mtd->read_oob = nand_read_oob;
        mtd->write_oob = nand_write_oob;
        mtd->block_isbad = nand_block_isbad;
index ab6a3a7e00b19c16a1be25f72db29e74976f7316..b8f2575e7e52a77e702969b986626e58d144ab4f 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 const char *yaffs_fs_c_version =
-    "$Id: yaffs_fs.c,v 1.66 2008-05-05 07:58:58 charles Exp $";
+    "$Id: yaffs_fs.c,v 1.67 2008-07-03 20:06:05 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 #include <linux/version.h>
@@ -43,7 +43,6 @@ extern const char *yaffs_guts_c_version;
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/list.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
@@ -108,6 +107,19 @@ MODULE_PARM(yaffs_traceMask,"i");
 MODULE_PARM(yaffs_wr_attempts,"i");
 #endif
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25))
+/* use iget and read_inode */
+#define Y_IGET(sb,inum) iget((sb),(inum))
+static void yaffs_read_inode(struct inode *inode);
+
+#else
+/* Call local equivalent */
+#define YAFFS_USE_OWN_IGET
+#define Y_IGET(sb,inum) yaffs_iget((sb),(inum))
+
+static struct inode * yaffs_iget(struct super_block *sb, unsigned long ino);
+#endif
+
 /*#define T(x) printk x */
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
@@ -183,7 +195,6 @@ static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf);
 #else
 static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
 #endif
-static void yaffs_read_inode(struct inode *inode);
 
 static void yaffs_put_inode(struct inode *inode);
 static void yaffs_delete_inode(struct inode *);
@@ -286,7 +297,10 @@ static struct file_operations yaffs_dir_operations = {
 
 static struct super_operations yaffs_super_ops = {
        .statfs = yaffs_statfs,
+
+#ifndef YAFFS_USE_OWN_IGET
        .read_inode = yaffs_read_inode,
+#endif
        .put_inode = yaffs_put_inode,
        .put_super = yaffs_put_super,
        .delete_inode = yaffs_delete_inode,
@@ -848,7 +862,9 @@ struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
        T(YAFFS_TRACE_OS,
          (KERN_DEBUG "yaffs_get_inode for object %d\n", obj->objectId));
 
-       inode = iget(sb, obj->objectId);
+       inode = Y_IGET(sb, obj->objectId);
+       if(IS_ERR(inode))
+         return NULL;
 
        /* NB Side effect: iget calls back to yaffs_read_inode(). */
        /* iget also increments the inode's i_count */
@@ -920,7 +936,7 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
        yaffs_Device *dev;
        struct inode *inode = f->f_dentry->d_inode;
        unsigned long offset, curoffs;
-       struct list_head *i;
+       struct ylist_head *i;
        yaffs_Object *l;
 
        char name[YAFFS_MAX_NAME_LENGTH + 1];
@@ -969,10 +985,10 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
                f->f_version = inode->i_version;
        }
 
-       list_for_each(i, &obj->variant.directoryVariant.children) {
+       ylist_for_each(i, &obj->variant.directoryVariant.children) {
                curoffs++;
                if (curoffs >= offset) {
-                       l = list_entry(i, yaffs_Object, siblings);
+                       l = ylist_entry(i, yaffs_Object, siblings);
 
                        yaffs_GetObjectName(l, name,
                                            YAFFS_MAX_NAME_LENGTH + 1);
@@ -1273,7 +1289,7 @@ static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
        if (target &&
            target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
-           !list_empty(&target->variant.directoryVariant.children)) {
+           !ylist_empty(&target->variant.directoryVariant.children)) {
 
                T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n"));
 
@@ -1404,7 +1420,6 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
 }
 
 
-/**
 static int yaffs_do_sync_fs(struct super_block *sb)
 {
 
@@ -1414,8 +1429,10 @@ static int yaffs_do_sync_fs(struct super_block *sb)
        if(sb->s_dirt) {
                yaffs_GrossLock(dev);
 
-               if(dev)
+               if(dev){
+                       yaffs_FlushEntireDeviceCache(dev);
                        yaffs_CheckpointSave(dev);
+               }
 
                yaffs_GrossUnlock(dev);
 
@@ -1423,7 +1440,7 @@ static int yaffs_do_sync_fs(struct super_block *sb)
        }
        return 0;
 }
-**/
+
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
 static void yaffs_write_super(struct super_block *sb)
@@ -1433,8 +1450,9 @@ static int yaffs_write_super(struct super_block *sb)
 {
 
        T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_write_super\n"));
+       yaffs_do_sync_fs(sb);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
-       return 0; /* yaffs_do_sync_fs(sb);*/
+       return 0; 
 #endif
 }
 
@@ -1448,10 +1466,47 @@ static int yaffs_sync_fs(struct super_block *sb)
 
        T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_fs\n"));
 
-       return 0; /* yaffs_do_sync_fs(sb);*/
+       yaffs_do_sync_fs(sb);
+       
+       return 0; 
+
+}
+
+#ifdef YAFFS_USE_OWN_IGET
+
+static struct inode * yaffs_iget(struct super_block *sb, unsigned long ino)
+{
+       struct inode *inode;
+       yaffs_Object *obj;
+       yaffs_Device *dev = yaffs_SuperToDevice(sb);
+
+       T(YAFFS_TRACE_OS,
+         (KERN_DEBUG "yaffs_iget for %lu\n", ino));
+
+       inode = iget_locked(sb, ino);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+       if (!(inode->i_state & I_NEW))
+               return inode;
+
+       /* NB This is called as a side effect of other functions, but
+       * we had to release the lock to prevent deadlocks, so
+       * need to lock again.
+       */
+    
+       yaffs_GrossLock(dev);
+
+       obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
+
+       yaffs_FillInodeFromObject(inode, obj);
 
+       yaffs_GrossUnlock(dev);
+       
+       unlock_new_inode(inode);
+       return inode;
 }
 
+#else
 
 static void yaffs_read_inode(struct inode *inode)
 {
@@ -1475,7 +1530,9 @@ static void yaffs_read_inode(struct inode *inode)
        yaffs_GrossUnlock(dev);
 }
 
-static LIST_HEAD(yaffs_dev_list);
+#endif
+
+static YLIST_HEAD(yaffs_dev_list);
 
 #if 0 // not used
 static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
@@ -1529,7 +1586,7 @@ static void yaffs_put_super(struct super_block *sb)
        yaffs_GrossUnlock(dev);
 
        /* we assume this is protected by lock_kernel() in mount/umount */
-       list_del(&dev->devList);
+       ylist_del(&dev->devList);
 
        if(dev->spareBuffer){
                YFREE(dev->spareBuffer);
@@ -1864,7 +1921,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        dev->skipCheckpointWrite = options.skip_checkpoint_write;
 
        /* we assume this is protected by lock_kernel() in mount/umount */
-       list_add_tail(&dev->devList, &yaffs_dev_list);
+       ylist_add_tail(&dev->devList, &yaffs_dev_list);
 
        init_MUTEX(&dev->grossLock);
 
@@ -2049,7 +2106,7 @@ static int yaffs_proc_read(char *page,
                           char **start,
                           off_t offset, int count, int *eof, void *data)
 {
-       struct list_head *item;
+       struct ylist_head *item;
        char *buf = page;
        int step = offset;
        int n = 0;
@@ -2073,8 +2130,8 @@ static int yaffs_proc_read(char *page,
        lock_kernel();
 
        /* Locate and print the Nth entry.  Order N-squared but N is small. */
-       list_for_each(item, &yaffs_dev_list) {
-               yaffs_Device *dev = list_entry(item, yaffs_Device, devList);
+       ylist_for_each(item, &yaffs_dev_list) {
+               yaffs_Device *dev = ylist_entry(item, yaffs_Device, devList);
                if (n < step) {
                        n++;
                        continue;
index 6e725ace9d64f3f8f491ee711afc975c42c2a4fb..d4ecda3c035e74375bf4db24e147ed495b4fa882 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 const char *yaffs_guts_c_version =
-    "$Id: yaffs_guts.c,v 1.57 2008-07-02 20:17:41 charles Exp $";
+    "$Id: yaffs_guts.c,v 1.58 2008-07-03 20:06:05 charles Exp $";
 
 #include "yportenv.h"
 
@@ -767,20 +767,20 @@ static void yaffs_VerifyObject(yaffs_Object *obj)
                return;
                
        /* Check sane object header chunk */
-       
-        chunkMin = dev->internalStartBlock * dev->nChunksPerBlock;
-        chunkMax = (dev->internalEndBlock+1) * dev->nChunksPerBlock - 1;
-        
-        chunkIdOk = (((unsigned)(obj->chunkId)) >= chunkMin && ((unsigned)(obj->chunkId)) <= chunkMax);
-        chunkIsLive = chunkIdOk && 
-                        yaffs_CheckChunkBit(dev, 
-                                            obj->chunkId / dev->nChunksPerBlock,
-                                           obj->chunkId % dev->nChunksPerBlock);
-       if(!obj->fake && 
+
+       chunkMin = dev->internalStartBlock * dev->nChunksPerBlock;
+       chunkMax = (dev->internalEndBlock+1) * dev->nChunksPerBlock - 1;
+
+       chunkIdOk = (((unsigned)(obj->hdrChunk)) >= chunkMin && ((unsigned)(obj->hdrChunk)) <= chunkMax);
+       chunkIsLive = chunkIdOk &&
+                       yaffs_CheckChunkBit(dev,
+                                           obj->hdrChunk / dev->nChunksPerBlock,
+                                           obj->hdrChunk % dev->nChunksPerBlock);
+       if(!obj->fake &&
            (!chunkIdOk || !chunkIsLive)) {
           T(YAFFS_TRACE_VERIFY,
           (TSTR("Obj %d has chunkId %d %s %s"TENDSTR),
-          obj->objectId,obj->chunkId,
+          obj->objectId,obj->hdrChunk,
           chunkIdOk ? "" : ",out of range",
           chunkIsLive || !chunkIdOk ? "" : ",marked as deleted"));
        }
@@ -791,9 +791,9 @@ static void yaffs_VerifyObject(yaffs_Object *obj)
                __u8 *buffer = yaffs_GetTempBuffer(dev,__LINE__);
                
                oh = (yaffs_ObjectHeader *)buffer;
-               
-               yaffs_ReadChunkWithTagsFromNAND(dev, obj->chunkId,buffer, &tags);
-               
+
+               yaffs_ReadChunkWithTagsFromNAND(dev, obj->hdrChunk,buffer, &tags);
+
                yaffs_VerifyObjectHeader(obj,oh,&tags,1);
                
                yaffs_ReleaseTempBuffer(dev,buffer,__LINE__);
@@ -875,7 +875,8 @@ static Y_INLINE int yaffs_HashFunction(int n)
 }
 
 /*
- * Access functions to useful fake objects
+ * Access functions to useful fake objects.
+ * Note that root might have a presence in NAND if permissions are set.
  */
  
 yaffs_Object *yaffs_Root(yaffs_Device * dev)
@@ -1922,12 +1923,12 @@ static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device * dev)
                /* Now sweeten it up... */
 
                memset(tn, 0, sizeof(yaffs_Object));
-                tn->myDev = dev;
-                tn->chunkId = -1;
-                tn->variantType = YAFFS_OBJECT_TYPE_UNKNOWN;
-                YINIT_LIST_HEAD(&(tn->hardLinks));
-                YINIT_LIST_HEAD(&(tn->hashLink));
-                YINIT_LIST_HEAD(&tn->siblings);
+               tn->myDev = dev;
+               tn->hdrChunk = 0;
+               tn->variantType = YAFFS_OBJECT_TYPE_UNKNOWN;
+               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
@@ -1950,14 +1951,14 @@ static yaffs_Object *yaffs_CreateFakeDirectory(yaffs_Device * dev, int number,
        yaffs_Object *obj =
            yaffs_CreateNewObject(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY);
        if (obj) {
-               obj->fake = 1;          /* it is fake so it has no NAND presence... */
+               obj->fake = 1;          /* it is fake so it might have no NAND presence... */
                obj->renameAllowed = 0; /* ... and we're not allowed to rename it... */
                obj->unlinkAllowed = 0; /* ... or unlink it */
                obj->deleted = 0;
                obj->unlinked = 0;
                obj->yst_mode = mode;
                obj->myDev = dev;
-               obj->chunkId = 0;       /* Not a valid chunk. */
+               obj->hdrChunk = 0;      /* Not a valid chunk. */
        }
 
        return obj;
@@ -2296,7 +2297,7 @@ static yaffs_Object *yaffs_MknodObject(yaffs_ObjectType type,
        
 
        if (in) {
-               in->chunkId = -1;
+               in->hdrChunk = 0;
                in->valid = 1;
                in->variantType = type;
 
@@ -3035,7 +3036,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block)
                                   
                                if(object && !yaffs_SkipVerification(dev)){
                                        if(tags.chunkId == 0)
-                                               matchingChunk = object->chunkId;
+                                               matchingChunk = object->hdrChunk;
                                        else if(object->softDeleted)
                                                matchingChunk = oldChunk; /* Defeat the test */
                                        else
@@ -3079,7 +3080,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block)
                                        /* Deleted object header with no data chunks.
                                         * Can be discarded and the file deleted.
                                         */
-                                       object->chunkId = 0;
+                                       object->hdrChunk = 0;
                                        yaffs_FreeTnode(object->myDev,
                                                        object->variant.
                                                        fileVariant.top);
@@ -3125,7 +3126,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block)
 
                                                if (tags.chunkId == 0) {
                                                        /* It's a header */
-                                                       object->chunkId =  newChunk;
+                                                       object->hdrChunk =  newChunk;
                                                        object->serial =   tags.serialNumber;
                                                } else {
                                                        /* It's a data chunk */
@@ -3444,7 +3445,7 @@ static int yaffs_PutChunkIntoFile(yaffs_Object * in, int chunkInInode,
                 * Update: For backward scanning we don't need to re-read tags so this is quite cheap.
                 */
 
-               if (existingChunk != 0) {
+               if (existingChunk > 0) {
                        /* NB Right now existing chunk will not be real chunkId if the device >= 32MB
                         *    thus we have to do a FindChunkInFile to get the real chunk id.
                         *
@@ -3675,7 +3676,10 @@ int yaffs_UpdateObjectHeader(yaffs_Object * in, const YCHAR * name, int force,
         
         yaffs_strcpy(oldName,_Y("silly old name"));
 
-        if (!in->fake || force) {
+
+       if (!in->fake || 
+           in == dev->rootDir || /* The rootDir should also be saved */
+           force) {
 
                yaffs_CheckGarbageCollection(dev);
                yaffs_CheckObjectDetailsLoaded(in);
@@ -3683,9 +3687,9 @@ int yaffs_UpdateObjectHeader(yaffs_Object * in, const YCHAR * name, int force,
                buffer = yaffs_GetTempBuffer(in->myDev, __LINE__);
                oh = (yaffs_ObjectHeader *) buffer;
 
-               prevChunkId = in->chunkId;
+               prevChunkId = in->hdrChunk;
 
-               if (prevChunkId >= 0) {
+               if (prevChunkId > 0) {
                        result = yaffs_ReadChunkWithTagsFromNAND(dev, prevChunkId,
                                                        buffer, &oldTags);
                        
@@ -3787,7 +3791,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object * in, const YCHAR * name, int force,
 
                if (newChunkId >= 0) {
 
-                       in->chunkId = newChunkId;
+                       in->hdrChunk = newChunkId;
 
                        if (prevChunkId >= 0) {
                                yaffs_DeleteChunk(dev, prevChunkId, 1,
@@ -4227,8 +4231,8 @@ static void yaffs_ObjectToCheckpointObject(yaffs_CheckpointObject *cp,
 
        cp->objectId = obj->objectId;
        cp->parentId = (obj->parent) ? obj->parent->objectId : 0;
-       cp->chunkId = obj->chunkId;
-       cp->variantType = obj->variantType;                     
+       cp->hdrChunk = obj->hdrChunk;
+       cp->variantType = obj->variantType;
        cp->deleted = obj->deleted;
        cp->softDeleted = obj->softDeleted;
        cp->unlinked = obj->unlinked;
@@ -4261,9 +4265,9 @@ static void yaffs_CheckpointObjectToObject( yaffs_Object *obj,yaffs_CheckpointOb
                
        if(parent)
                yaffs_AddObjectToDirectory(parent, obj);
-               
-       obj->chunkId = cp->chunkId;
-       obj->variantType = cp->variantType;                     
+
+       obj->hdrChunk = cp->hdrChunk;
+       obj->variantType = cp->variantType;
        obj->deleted = cp->deleted;
        obj->softDeleted = cp->softDeleted;
        obj->unlinked = cp->unlinked;
@@ -4277,8 +4281,8 @@ static void yaffs_CheckpointObjectToObject( yaffs_Object *obj,yaffs_CheckpointOb
                obj->variant.fileVariant.fileSize = cp->fileSizeOrEquivalentObjectId;
        else if(obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK)
                obj->variant.hardLinkVariant.equivalentObjectId = cp->fileSizeOrEquivalentObjectId;
-               
-       if(obj->objectId >= YAFFS_NOBJECT_BUCKETS)
+
+       if(obj->hdrChunk > 0)
                obj->lazyLoaded = 1;
 }
 
@@ -4409,8 +4413,8 @@ static int yaffs_WriteCheckpointObjects(yaffs_Device *dev)
 
                                        T(YAFFS_TRACE_CHECKPOINT,(
                                                TSTR("Checkpoint write object %d parent %d type %d chunk %d obj addr %x" TENDSTR),
-                                               cp.objectId,cp.parentId,cp.variantType,cp.chunkId,(unsigned) obj));
-                                               
+                                               cp.objectId,cp.parentId,cp.variantType,cp.hdrChunk,(unsigned) obj));
+
                                        ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp));
                                        
                                        if(ok && obj->variantType == YAFFS_OBJECT_TYPE_FILE){
@@ -4448,8 +4452,8 @@ static int yaffs_ReadCheckpointObjects(yaffs_Device *dev)
                }
                        
                T(YAFFS_TRACE_CHECKPOINT,(TSTR("Checkpoint read object %d parent %d type %d chunk %d " TENDSTR),
-                       cp.objectId,cp.parentId,cp.variantType,cp.chunkId));
-                       
+                       cp.objectId,cp.parentId,cp.variantType,cp.hdrChunk));
+
                if(ok && cp.objectId == ~0)
                        done = 1;
                else if(ok){
@@ -5143,8 +5147,8 @@ static int yaffs_DoGenericObjectDeletion(yaffs_Object * in)
        }
 
        yaffs_RemoveObjectFromDirectory(in);
-       yaffs_DeleteChunk(in->myDev, in->chunkId, 1, __LINE__);
-       in->chunkId = -1;
+       yaffs_DeleteChunk(in->myDev, in->hdrChunk, 1, __LINE__);
+       in->hdrChunk = 0;
 
        yaffs_FreeObject(in);
        return YAFFS_OK;
@@ -5678,7 +5682,7 @@ static int yaffs_Scan(yaffs_Device * dev)
                                            newSerial) {
                                                /* Use new one - destroy the exisiting one */
                                                yaffs_DeleteChunk(dev,
-                                                                 in->chunkId,
+                                                                 in->hdrChunk,
                                                                  1, __LINE__);
                                                in->valid = 0;
                                        } else {
@@ -5711,7 +5715,7 @@ static int yaffs_Scan(yaffs_Device * dev)
                                        in->yst_ctime = oh->yst_ctime;
                                        in->yst_rdev = oh->yst_rdev;
 #endif
-                                       in->chunkId = chunk;
+                                       in->hdrChunk = chunk;
 
                                } else if (in && !in->valid) {
                                        /* we need to load this info */
@@ -5735,7 +5739,7 @@ static int yaffs_Scan(yaffs_Device * dev)
                                        in->yst_ctime = oh->yst_ctime;
                                        in->yst_rdev = oh->yst_rdev;
 #endif
-                                       in->chunkId = chunk;
+                                       in->hdrChunk = chunk;
 
                                        yaffs_SetObjectName(in, oh->name);
                                        in->dirty = 0;
@@ -5934,12 +5938,12 @@ static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in)
                in->lazyLoaded ? "not yet" : "already"));
 #endif
 
-       if(in->lazyLoaded){
+       if(in->lazyLoaded && in->hdrChunk > 0){
                in->lazyLoaded = 0;
                chunkData = yaffs_GetTempBuffer(dev, __LINE__);
 
-               result = yaffs_ReadChunkWithTagsFromNAND(dev,in->chunkId,chunkData,&tags);
-               oh = (yaffs_ObjectHeader *) chunkData;          
+               result = yaffs_ReadChunkWithTagsFromNAND(dev,in->hdrChunk,chunkData,&tags);
+               oh = (yaffs_ObjectHeader *) chunkData;
 
                in->yst_mode = oh->yst_mode;
 #ifdef CONFIG_YAFFS_WINCE
@@ -6420,15 +6424,15 @@ static int yaffs_ScanBackwards(yaffs_Device * dev)
                                                in->variantType = tags.extraObjectType;
                                                in->lazyLoaded = 1;
                                        }
-                                               
-                                       in->chunkId = chunk;
+
+                                       in->hdrChunk = chunk;
 
                                } else if (!in->valid) {
                                        /* we need to load this info */
 
                                        in->valid = 1;
-                                       in->chunkId = chunk;
-                                       
+                                       in->hdrChunk = chunk;
+
                                        if(oh) {
                                                in->variantType = oh->type;
 
@@ -6745,9 +6749,8 @@ yaffs_Object *yaffs_FindObjectByName(yaffs_Object * directory,
                                if (yaffs_strcmp(name, YAFFS_LOSTNFOUND_NAME) == 0) {
                                        return l;
                                }
-                       } else if (yaffs_SumCompare(l->sum, sum) || l->chunkId <= 0)    
-                       {
-                               /* LostnFound cunk called Objxxx
+                       } else if (yaffs_SumCompare(l->sum, sum) || l->hdrChunk <= 0){
+                               /* LostnFound chunk called Objxxx
                                 * Do a real check
                                 */
                                yaffs_GetObjectName(l, buffer,
@@ -6822,7 +6825,7 @@ int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize)
 
        if (obj->objectId == YAFFS_OBJECTID_LOSTNFOUND) {
                yaffs_strncpy(name, YAFFS_LOSTNFOUND_NAME, buffSize - 1);
-       } else if (obj->chunkId <= 0) {
+       } else if (obj->hdrChunk <= 0) {
                YCHAR locName[20];
                /* make up a name */
                yaffs_sprintf(locName, _Y("%s%d"), YAFFS_LOSTNFOUND_PREFIX,
@@ -6843,9 +6846,9 @@ int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize)
 
                memset(buffer, 0, obj->myDev->nDataBytesPerChunk);
 
-               if (obj->chunkId >= 0) {
+               if (obj->hdrChunk > 0) {
                        result = yaffs_ReadChunkWithTagsFromNAND(obj->myDev,
-                                                       obj->chunkId, buffer,
+                                                       obj->hdrChunk, buffer,
                                                        NULL);
                }
                yaffs_strncpy(name, oh->name, buffSize - 1);
@@ -7006,7 +7009,7 @@ int yaffs_DumpObject(yaffs_Object * obj)
           ("Object %d, inode %d \"%s\"\n dirty %d valid %d serial %d sum %d"
            " chunk %d type %d size %d\n"
            TENDSTR), obj->objectId, yaffs_GetObjectInode(obj), name,
-          obj->dirty, obj->valid, obj->serial, obj->sum, obj->chunkId,
+          obj->dirty, obj->valid, obj->serial, obj->sum, obj->hdrChunk,
           yaffs_GetObjectType(obj), yaffs_GetObjectFileLength(obj)));
 
        return YAFFS_OK;
@@ -7306,6 +7309,7 @@ int yaffs_GutsInitialise(yaffs_Device * dev)
                /* Now scan the flash. */
                if (dev->isYaffs2) {
                        if(yaffs_CheckpointRestore(dev)) {
+                               yaffs_CheckObjectDetailsLoaded(dev->rootDir);
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
index 450672496f0f326971d785065f17c437a4902539..a19362534c4427b4e8b0c1cbd9aa1ef9c5e9f4ea 100644 (file)
@@ -436,8 +436,8 @@ struct yaffs_ObjectStruct {
         struct yaffs_ObjectStruct *parent; 
         struct ylist_head siblings;
 
-        /* Where's my object header in NAND? */
-        int chunkId;            
+       /* Where's my object header in NAND? */
+       int hdrChunk;
 
        int nDataChunks;        /* Number of data chunks attached to the file. */
 
@@ -501,8 +501,7 @@ typedef struct {
         int structType;
        __u32 objectId;         
        __u32 parentId;
-       int chunkId;
-                       
+       int hdrChunk;
        yaffs_ObjectType variantType:3;
        __u8 deleted:1;         
        __u8 softDeleted:1;     
@@ -693,6 +692,8 @@ struct yaffs_DeviceStruct {
        int nObjectsCreated;
        yaffs_Object *freeObjects;
        int nFreeObjects;
+       
+       int nHardLinks;
 
        yaffs_ObjectList *allocatedObjectList;