X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs%2F.git;a=blobdiff_plain;f=yaffs_fs.c;h=ff7221baf2e9147dba00082e56c02abd46441f4c;hp=da3b7f923daa288db1bca8efa4eaf0d635abb940;hb=37122d7644239983d55096a85bca6fb8e248cf20;hpb=ce96b5b9742c81cad6d902eaf793b792c1b8943b diff --git a/yaffs_fs.c b/yaffs_fs.c index da3b7f9..ff7221b 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -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; }