*/
-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;
yaffs_GrossLock(dev);
- yaffs_FlushFile(obj);
+ yaffs_FlushFile(obj,1);
yaffs_GrossUnlock(dev);
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)
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;
}
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
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
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;
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;
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;
dev->initialiseNAND = nandmtd_InitialiseNAND;
dev->putSuperFunc = yaffs_MTDPutSuper;
+
+#ifdef CONFIG_YAFFS_USE_NANDECC
+ dev->useNANDECC = 1;
+#endif
yaffs_dev = dev;
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);
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;
}