*** empty log message ***
[yaffs/.git] / yaffs_fs.c
index da3b7f923daa288db1bca8efa4eaf0d635abb940..ff7221baf2e9147dba00082e56c02abd46441f4c 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 
-const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.20 2002-11-26 01:15:37 charles Exp $";
+const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.25 2003-03-11 05:16:53 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 
@@ -352,7 +352,7 @@ static int yaffs_file_flush(struct file* file)
 
        yaffs_GrossLock(dev);
        
-    yaffs_FlushFile(obj);
+    yaffs_FlushFile(obj,1);
 
        yaffs_GrossUnlock(dev);
 
@@ -853,8 +853,11 @@ static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dent
        dev = obj->myDev;
        
        yaffs_GrossLock(dev);
-       
-       link = yaffs_Link(yaffs_InodeToObject(dir),dentry->d_name.name,obj);
+
+       if (!S_ISDIR(inode->i_mode))    // Don't link directories
+       {
+               link = yaffs_Link(yaffs_InodeToObject(dir),dentry->d_name.name,obj);
+       }
        
 
        if(link)
@@ -926,7 +929,7 @@ static int yaffs_sync_object(struct file * file, struct dentry *dentry, int data
        
        T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_sync_object\n"));
        yaffs_GrossLock(dev);
-       yaffs_FlushFile(obj);
+       yaffs_FlushFile(obj,1);
        yaffs_GrossUnlock(dev);
        return 0;
 }
@@ -939,22 +942,44 @@ static int yaffs_sync_object(struct file * file, struct dentry *dentry, int data
 static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
 {
        yaffs_Device *dev;
-       int retVal;
+       int retVal = YAFFS_FAIL;
+       int removed = 0;
+       yaffs_Object *target;
        
        dev = yaffs_InodeToObject(old_dir)->myDev;
 
        yaffs_GrossLock(dev);
        
-       // Unlink the target if it exists
-       yaffs_Unlink(yaffs_InodeToObject(new_dir),new_dentry->d_name.name);
+       // Check if the target is an existing directory that is not empty.
+       target = yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),new_dentry->d_name.name);
+       
+       if(target &&
+          target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
+          !list_empty(&target->variant.directoryVariant.children))
+       {
+               retVal = YAFFS_FAIL;
+       }
+       else
+       {
+          
+               // Unlink the target if it exists
+               removed = yaffs_Unlink(yaffs_InodeToObject(new_dir),new_dentry->d_name.name);
 
        
-       retVal =  yaffs_RenameObject(yaffs_InodeToObject(old_dir),old_dentry->d_name.name,
-                                        yaffs_InodeToObject(new_dir),new_dentry->d_name.name);
+               retVal =  yaffs_RenameObject(yaffs_InodeToObject(old_dir),old_dentry->d_name.name,
+                                                                       yaffs_InodeToObject(new_dir),new_dentry->d_name.name);
+                                                                       
+       }
        yaffs_GrossUnlock(dev);
        
        if(retVal == YAFFS_OK)
        {
+               if(removed == YAFFS_OK)
+               {
+                       new_dentry->d_inode->i_nlink--;
+                       mark_inode_dirty(new_dentry->d_inode);
+               }
+               
                return 0;
        }
        else
@@ -1105,7 +1130,7 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
        T(YAFFS_TRACE_OS,("yaffs_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",(int)(sb->s_blocksize)));
 
 #ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY
-       T(YAFFS_TRACE_OS,("yaffs: Write verification disabled. All guarantees null and void\n");
+       T(YAFFS_TRACE_OS,("yaffs: Write verification disabled. All guarantees null and void\n"));
 #endif
 
 
@@ -1130,6 +1155,9 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                nBlocks = YAFFS_RAM_EMULATION_SIZE / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
                dev->startBlock = 1;  // Don't use block 0
                dev->endBlock = nBlocks - 1;
+               dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
+               dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
+               dev->nReservedBlocks = 5;
 
                dev->writeChunkToNAND = nandemul_WriteChunkToNAND;
                dev->readChunkFromNAND = nandemul_ReadChunkFromNAND;
@@ -1175,8 +1203,12 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                if(!mtd->erase ||
                   !mtd->read  ||
                   !mtd->write ||
+#ifndef CONFIG_YAFFS_USE_OLD_MTD
+                  !mtd->write_ecc ||
+                  !mtd->read_ecc ||
+#endif
                   !mtd->read_oob ||
-                  !mtd->write_oob)
+                  !mtd->write_oob )
                {
                        printk(KERN_DEBUG "yaffs: MTD device does not support required functions\n");
                        return NULL;
@@ -1210,6 +1242,10 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
                dev->startBlock = 1;  // Don't use block 0
                dev->endBlock = nBlocks - 1;
+               dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
+               dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
+               dev->nReservedBlocks = 5;
+               
 
                // ... and the functions.
                dev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
@@ -1218,6 +1254,10 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                dev->initialiseNAND = nandmtd_InitialiseNAND;
                                
                dev->putSuperFunc = yaffs_MTDPutSuper;
+               
+#ifdef CONFIG_YAFFS_USE_NANDECC
+               dev->useNANDECC = 1;
+#endif
 
                yaffs_dev = dev;
                
@@ -1298,6 +1338,7 @@ static char * yaffs_dump_dev(char *buf,yaffs_Device *dev,char *name)
        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",dev->passiveGarbageCollections);
        buf +=sprintf(buf,"nRetriedWrites..... %d\n",dev->nRetriedWrites);
        buf +=sprintf(buf,"nRetireBlocks...... %d\n",dev->nRetiredBlocks);
        buf +=sprintf(buf,"eccFixed........... %d\n",dev->eccFixed);
@@ -1308,6 +1349,8 @@ static char * yaffs_dump_dev(char *buf,yaffs_Device *dev,char *name)
        buf +=sprintf(buf,"nDeletedFiles...... %d\n",dev->nDeletedFiles);
        buf +=sprintf(buf,"nUnlinkedFiles..... %d\n",dev->nUnlinkedFiles);
        buf +=sprintf(buf,"nBackgroudDeletions %d\n",dev->nBackgroundDeletions);
+       buf +=sprintf(buf,"useNANDECC......... %d\n",dev->useNANDECC);
+
        
        return buf;     
 }