* it under the terms of the GNU Lesser General Public License version 2.1 as\r
* published by the Free Software Foundation.\r
*\r
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.\r
+ *\r
* This file is just holds extra declarations used during development.\r
* Most of these are from kernel includes placed here so we can use them in \r
* applications.\r
#########################################################
# Makefile auto generated by Cygnus Source Navigator.
-# Target: yaffsdev_disk_dump_disk Date: Sep 17 2002 Time: 06:47:40 AM
+# Target: yaffsdev_disk Date: Sep 18 2002 Time: 10:19:04 AM
#
YACC_FLAGS =
LEX_FLAGS =
JAVA_FLAGS =
-CC_FLAGS = -g -Wall -DYAFFS_DUMP -DYAFFS_START=1281 -DYAFFS_END=32767 -DCONFIG_YAFFS_SHORT_OP_CACHE -DYAFFS_PARANOID -DYAFFS_FILEEM
+CC_FLAGS = -g -Wall -DCONFIG_YAFFS_SHORT_OP_CACHE -DYAFFS_PARANOID -DYAFFS_FILEEM
CPP_FLAGS =
YACC_INCLUDES =
LEX_INCLUDES =
JAVA_DEFINES =
CC_DEFINES =
CPP_DEFINES =
-yaffsdev_disk_dump_disk_LIBS =
+yaffsdev_disk_LIBS =
LINKER = gcc
LINKER_FLAGS =
LINKER_ENTRY =
-yaffsdev_disk_dump_disk_OBJECTS = nand_ecc.o yaffs_fileem.o yaffs_guts.o yaffsdev.o
+yaffsdev_disk_OBJECTS = nand_ecc.o yaffs_fileem.o yaffs_guts.o yaffsdev.o
-all: yaffsdumpdisk
+all: yaffsdev
-yaffsdumpdisk: $(yaffsdev_disk_dump_disk_OBJECTS)
- $(LINKER) -o yaffsdumpdisk $(LINKER_ENTRY) $(LINKER_FLAGS) $(yaffsdev_disk_dump_disk_OBJECTS) $(yaffsdev_disk_dump_disk_LIBS)
+yaffsdev: $(yaffsdev_disk_OBJECTS)
+ $(LINKER) -o yaffsdev $(LINKER_ENTRY) $(LINKER_FLAGS) $(yaffsdev_disk_OBJECTS) $(yaffsdev_disk_LIBS)
.y.c:
$(YACC) $< $(YACC_FLAGS) $(YACC_DEFINES) $(YACC_INCLUDES)
clean:
rm -f *.o
- rm -f yaffsdumpdisk
+ rm -f yaffsdev
}
+
+static yaffs_Device *yaffs_dev;
+static yaffs_Device *yaffsram_dev;
+
+
+
static void yaffs_put_super(struct super_block *sb)
{
yaffs_Device *dev = yaffs_SuperToDevice(sb);
}
yaffs_Deinitialise(dev);
yaffs_GrossUnlock(dev);
-
+
+ if(dev == yaffs_dev) yaffs_dev = NULL;
+ if(dev == yaffsram_dev) yaffsram_dev = NULL;
+
kfree(dev);
}
#endif
+
static struct super_block *yaffs_internal_read_super(int useRam, struct super_block * sb, void * data, int silent)
{
int nBlocks;
dev->readChunkFromNAND = nandemul_ReadChunkFromNAND;
dev->eraseBlockInNAND = nandemul_EraseBlockInNAND;
dev->initialiseNAND = nandemul_InitialiseNAND;
+
+ yaffsram_dev = dev;
#endif
dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
dev->initialiseNAND = nandmtd_InitialiseNAND;
-
+
dev->putSuperFunc = yaffs_MTDPutSuper;
+
+ yaffs_dev = dev;
+
#endif
}
static struct proc_dir_entry *my_proc_entry;
static struct proc_dir_entry *my_proc_ram_write_entry;
+static char * yaffs_dump_dev(char *buf,yaffs_Device *dev,char *name)
+{
+ buf +=sprintf(buf,"\nDevice %s\n",name);
+ buf +=sprintf(buf,"startBlock......... %d\n",dev->startBlock);
+ buf +=sprintf(buf,"endBlock........... %d\n",dev->endBlock);
+ buf +=sprintf(buf,"chunkGroupBits..... %d\n",dev->chunkGroupBits);
+ buf +=sprintf(buf,"chunkGroupSize..... %d\n",dev->chunkGroupSize);
+ buf +=sprintf(buf,"nErasedBlocks...... %d\n",dev->nErasedBlocks);
+ buf +=sprintf(buf,"nTnodesCreated..... %d\n",dev->nTnodesCreated);
+ buf +=sprintf(buf,"nFreeTnodes........ %d\n",dev->nFreeTnodes);
+ buf +=sprintf(buf,"nObjectsCreated.... %d\n",dev->nObjectsCreated);
+ buf +=sprintf(buf,"nFreeObjects....... %d\n",dev->nFreeObjects);
+ buf +=sprintf(buf,"nFreeChunks........ %d\n",dev->nFreeChunks);
+ buf +=sprintf(buf,"nPageWrites........ %d\n",dev->nPageWrites);
+ 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,"nRetriedWrites..... %d\n",dev->nRetriedWrites);
+ buf +=sprintf(buf,"nRetireBlocks...... %d\n",dev->nRetiredBlocks);
+ buf +=sprintf(buf,"cacheHits.......... %d\n",dev->cacheHits);
+ buf +=sprintf(buf,"nDeletedFiles...... %d\n",dev->nDeletedFiles);
+ buf +=sprintf(buf,"nUnlinkedFiles..... %d\n",dev->nUnlinkedFiles);
+ buf +=sprintf(buf,"nBackgroudDeletions %d\n",dev->nBackgroundDeletions);
+
+ return buf;
+}
static int yaffs_proc_read(
char *page,
)
{
- static char my_buffer[1000];
+ char my_buffer[2000];
+ char *buf;
+ buf = my_buffer;
if (offset > 0) return 0;
/* Fill the buffer and get its length */
- sprintf( my_buffer,
- "YAFFS built:"__DATE__ " "__TIME__"\n"
-
- );
+ buf +=sprintf(buf,"YAFFS built:"__DATE__ " "__TIME__"\n");
+
+ if(yaffs_dev) buf = yaffs_dump_dev(buf,yaffs_dev,"yaffs");
+ if(yaffsram_dev) buf = yaffs_dump_dev(buf,yaffsram_dev,"yaffsram");
+
strcpy(page,my_buffer);
return strlen(my_buffer);
{
int error = 0;
+ yaffs_dev = yaffsram_dev = NULL;
+
printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Initialisation\n");
#ifdef CONFIG_YAFFS_USE_GENERIC_RW
printk(KERN_DEBUG "yaffs is using generic read/write (caching)\n");
static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId);
static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj);
static int yaffs_CheckStructures(void);
-static void yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit);
+static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit);
static int yaffs_DoGenericObjectDeletion(yaffs_Object *in);
static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device *dev,int blockNo);
// DeleteWorker scans backwards through the tnode tree and deletes all the
// chunks and tnodes in the file
+// Returns 1 if the tree was deleted. Returns 0 if it stopped early due to hitting the limit and the delete is incomplete.
-static void yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit)
+static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit)
{
int i;
int chunkInInode;
yaffs_Tags tags;
int found;
int chunkDeleted;
+ int allDone = 1;
if(tn)
if(level > 0)
{
- for(i = YAFFS_NTNODES_INTERNAL -1; i >= 0 && (!limit || *limit > 0); i--)
+ for(i = YAFFS_NTNODES_INTERNAL -1; allDone && i >= 0; i--)
{
if(tn->internal[i])
{
- yaffs_DeleteWorker(in,tn->internal[i],level - 1,
+ if(limit && (*limit) < 0)
+ {
+ allDone = 0;
+ }
+ else
+ {
+ allDone = yaffs_DeleteWorker(in,tn->internal[i],level - 1,
(chunkOffset << YAFFS_TNODES_INTERNAL_BITS ) + i ,limit);
- yaffs_FreeTnode(in->myDev,tn->internal[i]);
- tn->internal[i] = NULL;
+ }
+ if(allDone)
+ {
+ yaffs_FreeTnode(in->myDev,tn->internal[i]);
+ tn->internal[i] = NULL;
+ }
}
}
+ return (allDone) ? 1 : 0;
}
else if(level == 0)
{
}
}
+ return 1;
+
}
}
+ return 1;
+
}
{
yaffs_Object *obj = dev->unlinkedDeletion;
int limit;
+ int delresult;
limit = 50; // Max number of chunks to delete in a file. NB this can be exceeded, but not by much.
- yaffs_DeleteWorker(obj, obj->variant.fileVariant.top, obj->variant.fileVariant.topLevel, 0,&limit);
+ delresult = yaffs_DeleteWorker(obj, obj->variant.fileVariant.top, obj->variant.fileVariant.topLevel, 0,&limit);
+
if(obj->nDataChunks == 0)
{
// Done all the deleting of data chunks.
// Now dump the header and clean up
- yaffs_DoGenericObjectDeletion(dev->unlinkedDeletion);
+ yaffs_FreeTnode(dev,obj->variant.fileVariant.top);
+ yaffs_DoGenericObjectDeletion(obj);
dev->nDeletedFiles--;
+ dev->nUnlinkedFiles--;
+ dev->nBackgroundDeletions++;
dev->unlinkedDeletion = NULL;
}
}
return yaffs_DoGenericObjectDeletion(in);
#else
int retVal;
+ int immediateDeletion=0;
retVal = yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,NULL);
if(retVal == YAFFS_OK)
{
- in->unlinked = 1;
- in->renameAllowed = 0;
+ //in->unlinked = 1;
+ //in->myDev->nUnlinkedFiles++;
+ //in->renameAllowed = 0;
+#ifdef __KERNEL__
+ if(in->myInode)
+ {
+ immediateDeletion = 1;
+
+ }
+#endif
+#if WIN32
+ if(in->inUse <= 0)
+ {
+ immediateDeletion = 1;
+
+ }
+#endif
+
+ if(immediateDeletion)
+ {
+ T((TSTR("yaffs: immediate deletion of file %d" TENDSTR),in->objectId));
+ in->deleted=1;
+ in->myDev->nDeletedFiles++;
+ }
+
}
return retVal;
{
retVal = yaffs_UnlinkFile(in);
}
- if(retVal == YAFFS_OK && in->unlinked)
+ if(retVal == YAFFS_OK &&
+ in->unlinked &&
+ !in->deleted)
{
in->deleted = 1;
+ in->myDev->nDeletedFiles++;
}
return in->deleted ? YAFFS_OK : YAFFS_FAIL;
}
if(directory == obj->myDev->unlinkedDir)
{
obj->unlinked = 1;
+ obj->myDev->nUnlinkedFiles++;
obj->renameAllowed = 0;
}
}
dev->doingBufferedBlockRewrite = 0;
dev->blockSelectedForGC = -1;
dev->nDeletedFiles = 0;
+ dev->nBackgroundDeletions=0;
+ dev->nUnlinkedFiles = 0;
yaffs_InitialiseBlocks(dev,nBlocks);
* it under the terms of the GNU Lesser General Public License version 2.1 as
* published by the Free Software Foundation.
*
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
*/
#ifndef __YAFFS_GUTS_H__
// Stuff for background deletion and unlinked files.
yaffs_Object *unlinkedDir; // Directory where unlinked and deleted files live.
yaffs_Object *unlinkedDeletion; // Current file being background deleted.
- int nDeletedFiles; // Count of files awaiting deletion;
-
+ int nDeletedFiles; // Count of files awaiting deletion;
+ int nUnlinkedFiles; // Count of unlinked files.
+ int nBackgroundDeletions; // Count of background deletions.
};
* it under the terms of the GNU Lesser General Public License version 2.1 as
* published by the Free Software Foundation.
*
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ *
*/
#ifndef __YAFFS_MTDIF_H__
* it under the terms of the GNU Lesser General Public License version 2.1 as
* published by the Free Software Foundation.
*
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ *
* yaffs_nandemul.h: Interface to emulated NAND functions
*
*/
+}
+
+void TestTimeBigDeletes(yaffs_Device *dev)
+{
+ yaffs_Object *f;
+ yaffs_Object *sl;
+ yaffs_Object *lnf;
+
+ yaffs_Object *hl1;
+ yaffs_Object *hl2;
+ yaffs_Object *hl3;
+ yaffs_Object *d, *df;
+
+ int x;
+ int i;
+ int b;
+ char data[200];
+
+ char * alias;
+ int written;
+
+
+ printf("Exisiting objects\n");
+ yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
+ printf("Exisiting objects in lost+found\n");
+ lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
+ yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject);
+
+ printf("Start\n");
+
+
+
+ f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
+ if(f)
+ {
+ printf("Found\n");
+ }
+ else
+ {
+ f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
+ printf("Created\n");
+ }
+
+ for(i = 0; i < 100000; i+=20)
+ {
+
+ b++;
+ if(b & 1)
+ written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
+ else
+ written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
+ }
+
+ yaffs_FlushFile(f);
+ yaffs_DeleteFile(f);
+
+ f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
+ if(f)
+ {
+ printf("Found\n");
+ }
+ else
+ {
+ f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
+ printf("Created\n");
+ }
+
+ for(i = 0; i < 100000; i+=20)
+ {
+
+ b++;
+ if(b & 1)
+ written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
+ else
+ written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
+ }
+
+ yaffs_FlushFile(f);
+ yaffs_DeleteFile(f);
+
+ f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
+ if(f)
+ {
+ printf("Found\n");
+ }
+ else
+ {
+ f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
+ printf("Created\n");
+ }
+
+ for(i = 0; i < 100000; i+=20)
+ {
+
+ b++;
+ if(b & 1)
+ written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
+ else
+ written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
+ }
+
+ yaffs_FlushFile(f);
+ yaffs_DeleteFile(f);
+
}
void TestTime(yaffs_Device *dev)
printf("Unlink file: %d\n",yaffs_Unlink(yaffs_Root(dev),"Rename"));
+ yaffs_DeleteFile(f);
+
yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
// Create a directory and play with it
// yaffs_GutsTest();
- TestTime(&device);
+ TestTimeBigDeletes(&device);
printf("Cache hits %d\n",device.cacheHits);
printf("Retired blocks %d\n",device.nRetiredBlocks);
* it under the terms of the GNU Lesser General Public License version 2.1 as
* published by the Free Software Foundation.
*
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ *
*/
#ifndef __YAFFSINTERFACE_H__
* it under the terms of the GNU Lesser General Public License version 2.1 as\r
* published by the Free Software Foundation.\r
*\r
+ *\r
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.\r
+ *\r
*/\r
\r
#ifndef __PORTENV_H__\r