From: charles Date: Tue, 27 Aug 2002 03:31:38 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: https://yaffs.net/gitweb/?p=yaffs%2F.git;a=commitdiff_plain;h=daffb0c61b90abbfc5fd8c335c5b79b0feeff2ab *** empty log message *** --- diff --git a/Documentation/yaffs-todo.html b/Documentation/yaffs-todo.html index 831b2d3..ccef2e8 100644 --- a/Documentation/yaffs-todo.html +++ b/Documentation/yaffs-todo.html @@ -7,7 +7,7 @@ - +

YAFFS Todo as at 21/08/2002

@@ -22,7 +22,7 @@

Tools to be done

    -
  1. +
  2. Dumper and analyser to work off the mtd.

Recently done with no known problems (ie. probably needs significant testing)

@@ -49,16 +49,19 @@ significant testing) the spirit of mkcramfs).

  • Added support for special inodes (pipes, character & block devices, sockets).

    -
  • Added generic read/write support to use page caching.

    +
  • Added generic read/write support to use page caching. + Selectable by configuration of CONFIG_YAFFS_USE_GENERIC_RW.

    Done, but currently known to be broken

      -

      nothing.

      +
    1. If you fill yaffs and then try to copy more files into it, + you end up with a bunch of objxxx files when you do an ls.

    Longer term stuff to do

    1. Discuss improved NAND page interface with mtd group. This has - actually started.

      + actually started. Luc van Oostenryck is also looking at an + alternative layer to mtd.

    2. Pull out all YAFFS_OK and YAFFS_FAIL style errors and return with -ENOMEM style error messages.

    diff --git a/Makefile b/Makefile index 7642d47..fa4c171 100644 --- a/Makefile +++ b/Makefile @@ -16,11 +16,60 @@ ## comment out USE_xxxx if you don't want these features. KERNELDIR = /usr/src/kernel-headers-2.4.18 + +# Configurations... +# Comment out the stuff you don't want. +# + +# CONFIG_YAFFS_RAM_ENABLED. +# This adds the yaffsram file system support. Nice for testing on x86, but uses 2MB of RAM. +# Don't enable for NAND-based targets. + USE_RAM_FOR_TEST = -DCONFIG_YAFFS_RAM_ENABLED + + +# CONFIG_YAFFS_MTD_ENABLED. +# This adds the yaffs file system support for working with a NAND mtd. + USE_MTD = -DCONFIG_YAFFS_MTD_ENABLED -YAFFS_CONFIGS = -DCONFIG_YAFFS_USE_GENERIC_RW -CFLAGS = -D__KERNEL__ -DMODULE $(USE_RAM_FOR_TEST) $(USE_MTD) $(YAFFS_CONFIGS) -I$(KERNELDIR)/include -O2 -Wall +# CONFIG_YAFFS_USE_GENERIC_RW +# Use generic_read/generic_write for reading/writing files. This enables the use of the Linux +# file caching layer. +# +# If you disable this, then caching is disabled and file read/write is direct. + +USE_GENERIC_RW = -DCONFIG_YAFFS_USE_GENERIC_RW + +# CONFIG_YAFFS_USE_HEADER_FILE_SIZE +# When the flash is scanned, two file sizes are constructed: +# * The size taken from the object header for the file. +# * The size figured out by scanning the data chunks. +# If this option is enabled, then the object header size is ued, otherwise the scanned size is used. +# Suggest leaving this disabled. + +#USE_HEADER_FILE_SIZE = -DCONFIG_YAFFS_USE_HEADER_FILE_SIZE + +#CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK +# Enabling this turns off the test that chunks are erased in flash before writing to them. +# this is safe, since the write verification will fail. +# Suggest enabling the test (ie. keep the following line commented) during development to help debug things. + +#IGNORE_CHUNK_ERASED = -DCONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK + +#CONFIG_YAFFS_DISABLE_WRITE_VERIFY +# I am severely reluctant to provide this config. Disabling the verification is not a good thing to do +# since NAND writes can fail silently. +# Disabling the write verification will cause your teeth to rot, rats to eat your corn and give you split ends. +# You have been warned. ie. Don't uncomment the following line. + +#IGNORE_WRITE_VERIFY = -DCONFIG_YAFFS_DISBLE_WRITE_VERIFY + +# End of configuration options. + +YAFFS_CONFIGS = $(USE_RAM_FOR_TEST) $(USE_MTD) $(USE_GENERIC_RW) $(USE_HEADER_FILE_SIZE) $(IGNORE_CHUNK_ERASED) $(IGNORE_WRITE_VERIFY) + +CFLAGS = -D__KERNEL__ -DMODULE $(YAFFS_CONFIGS) -I$(KERNELDIR)/include -O2 -Wall OBJS = yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o nand_ecc.o @@ -28,7 +77,7 @@ OBJS = yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o nand_ecc.o all: yaffs.o -$(OBJS): %.o: %.c +$(OBJS): %.o: %.c Makefile gcc -c $(CFLAGS) $< -o $@ yaffs.o: $(OBJS) diff --git a/snMakefile b/snMakefile index 936c08d..dd819c8 100644 --- a/snMakefile +++ b/snMakefile @@ -1,6 +1,6 @@ ######################################################### # Makefile auto generated by Cygnus Source Navigator. -# Target: yaffsdev_disk Date: Aug 21 2002 Time: 03:51:36 PM +# Target: yaffsdev_disk Date: Aug 27 2002 Time: 03:17:30 PM # diff --git a/yaffs_fileem.c b/yaffs_fileem.c index dd77b37..b850581 100644 --- a/yaffs_fileem.c +++ b/yaffs_fileem.c @@ -56,6 +56,16 @@ static int IsAMarkedBadBlock(int blk) static __u8 yaffs_WriteFailCorruption(int chunkInNAND) { + + // Whole blocks that fail + switch(chunkInNAND/YAFFS_CHUNKS_PER_BLOCK) + { + case 50: + case 52: + return 7; + } + + // Single blocks that fail switch(chunkInNAND) { case 2000: @@ -70,9 +80,10 @@ static __u8 yaffs_WriteFailCorruption(int chunkInNAND) case 3006: case 3007: return 1;// ding one bit - default: return 0; } + + return 0; } static void yaffs_ModifyWriteData(int chunkInNAND,__u8 *data) diff --git a/yaffs_fs.c b/yaffs_fs.c index dc70098..d669793 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -20,7 +20,7 @@ * * * Acknowledgements: - * * Luc van OostenRyck for O_APPEND patch. + * * Luc van OostenRyck for numerous patches. * * Nick Bane for patches marked NCB. * * Some code bodily lifted from JFFS2. */ @@ -774,7 +774,7 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) struct inode *inode = dentry->d_inode; int error; - T((KERN_DEBUG"yaffs_setattr\n")); + T((KERN_DEBUG"yaffs_setattr of object %d\n",yaffs_InodeToObject(inode)->objectId)); if((error = inode_change_ok(inode,attr)) == 0) { @@ -831,6 +831,8 @@ static void yaffs_put_super(struct super_block *sb) { dev->putSuperFunc(sb); } + yaffs_Deinitialise(dev); + kfree(dev); } @@ -871,7 +873,7 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl -#if CONFIG_YAFFS_USE_CHUNK_SIZE +#ifdef CONFIG_YAFFS_USE_CHUNK_SIZE sb->s_blocksize = YAFFS_BYTES_PER_CHUNK; sb->s_blocksize_bits = YAFFS_CHUNK_SIZE_SHIFT; #else @@ -880,6 +882,11 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl #endif T(("yaffs_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",sb->s_blocksize)); +#ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY + T(("yaffs: Write verification disabled. All guarantees null and void\n"); +#endif + + if(useRam) { @@ -1070,7 +1077,7 @@ static int __init init_yaffs_fs(void) int error = 0; printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Initialisation\n"); -#if CONFIG_YAFFS_USE_GENERIC_RW +#ifdef CONFIG_YAFFS_USE_GENERIC_RW printk(KERN_DEBUG "yaffs is using generic read/write (caching)\n"); #else printk(KERN_DEBUG "yaffs is using direct read/write (uncached)\n"); diff --git a/yaffs_guts.c b/yaffs_guts.c index abb01e2..fa1c9d5 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -73,7 +73,7 @@ static int yaffs_PutChunkIntoFile(yaffs_Object *in,int chunkInInode, int chunkIn static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev,int number,yaffs_ObjectType type); static void yaffs_AddObjectToDirectory(yaffs_Object *directory, yaffs_Object *obj); -static int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name); +static int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name, int force); static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId); static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj); static int yaffs_CheckStructures(void); @@ -87,6 +87,7 @@ static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaf static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND); +static int yaffs_UnlinkWorker(yaffs_Object *obj); static int yaffs_VerifyCompare(const __u8 *d0, const __u8 * d1, const yaffs_Spare *s0, const yaffs_Spare *s1); @@ -187,7 +188,6 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND) { -#if 1 static int init = 0; static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK]; @@ -208,7 +208,6 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND if(memcmp(cmpbuf,data,YAFFS_BYTES_PER_CHUNK)) return YAFFS_FAIL; if(memcmp(cmpbuf,spare,16)) return YAFFS_FAIL; -#endif return YAFFS_OK; @@ -244,9 +243,14 @@ static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, const __u8 { // First check this chunk is erased... +#ifndef CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK writeOk = yaffs_CheckChunkErased(dev,chunk); - - if(writeOk) +#endif + if(!writeOk) + { + T((TSTR("**>> yaffs chunk %d was not erased" TENDSTR),chunk)); + } + else { writeOk = yaffs_WriteChunkToNAND(dev,chunk,data,spare); } @@ -260,14 +264,15 @@ static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, const __u8 // NB We check a raw read without ECC correction applied yaffs_ReadChunkFromNAND(dev,chunk,rbData,&rbSpare,0); +#ifndef CONFIG_YAFFS_DISABLE_WRITE_VERIFY if(!yaffs_VerifyCompare(data,rbData,spare,&rbSpare)) { // Didn't verify - T((TSTR("**>> yaffs write failed on chunk %d" TENDSTR), chunk)); - // yaffs_DeleteChunk(dev,chunk); + T((TSTR("**>> yaffs write verify failed on chunk %d" TENDSTR), chunk)); writeOk = 0; - } + } +#endif } if(writeOk) @@ -327,12 +332,19 @@ static int yaffs_RewriteBufferedBlock(yaffs_Device *dev) // Set current write block to the new block dev->doingBufferedBlockRewrite = 0; + + return 1; } static void yaffs_HandleReadDataError(yaffs_Device *dev,int chunkInNAND) { - + int blockInNAND = chunkInNAND/YAFFS_CHUNKS_PER_BLOCK; + + // Mark the block for retirement + dev->blockInfo[blockInNAND].needsRetiring = 1; + + //TODO // Just do a garbage collection on the affected block then retire the block // NB recursion } @@ -352,6 +364,12 @@ static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaf static void yaffs_HandleWriteChunkError(yaffs_Device *dev,int chunkInNAND) { + int blockInNAND = chunkInNAND/YAFFS_CHUNKS_PER_BLOCK; + + // Mark the block for retirement + dev->blockInfo[blockInNAND].needsRetiring = 1; + // Delete the chunk + yaffs_DeleteChunk(dev,chunkInNAND); } @@ -360,6 +378,7 @@ static void yaffs_HandleWriteChunkError(yaffs_Device *dev,int chunkInNAND) static int yaffs_VerifyCompare(const __u8 *d0, const __u8 * d1, const yaffs_Spare *s0, const yaffs_Spare *s1) { + if( memcmp(d0,d1,YAFFS_BYTES_PER_CHUNK) != 0 || s0->tagByte0 != s1->tagByte0 || s0->tagByte1 != s1->tagByte1 || @@ -1411,7 +1430,7 @@ yaffs_Object *yaffs_MknodObject( yaffs_ObjectType type, break; } - if(yaffs_UpdateObjectHeader(in,name) < 0) + if(yaffs_UpdateObjectHeader(in,name,0) < 0) { // Could not create the object header, fail the creation yaffs_UnlinkWorker(in); @@ -1479,7 +1498,7 @@ static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir, const obj->dirty = 1; yaffs_AddObjectToDirectory(newDir,obj); - if(yaffs_UpdateObjectHeader(obj,newName) >= 0) + if(yaffs_UpdateObjectHeader(obj,newName,0) >= 0) { return YAFFS_OK; } @@ -1638,21 +1657,52 @@ static int yaffs_FindDirtiestBlock(yaffs_Device *dev) } -static int yaffs_FindBlockForAllocation(yaffs_Device *dev,int useReserve) +static void yaffs_BlockBecameDirty(yaffs_Device *dev,int blockNo) +{ + yaffs_BlockInfo *bi = &dev->blockInfo[blockNo]; + + int erasedOk = 0; + + // If the block is still healthy erase it and mark as clean. + // If the block has had a data failure, then retire it. + bi->blockState = YAFFS_BLOCK_STATE_DIRTY; + + if(!bi->needsRetiring) + { + erasedOk = yaffs_EraseBlockInNAND(dev,blockNo); + if(!erasedOk) + { + T((TSTR("**>> Erasure failed %d" TENDSTR),blockNo)); + } + } + + if( erasedOk ) + { + bi->blockState = YAFFS_BLOCK_STATE_EMPTY; + dev->nErasedBlocks++; + bi->pagesInUse = 0; + bi->pageBits = 0; + + T((TSTR("Erased block %d" TENDSTR),blockNo)); + } + else + { + yaffs_RetireBlock(dev,blockNo); + T((TSTR("**>> Block %d retired" TENDSTR),blockNo)); + } +} + + +static int yaffs_FindBlockForAllocation(yaffs_Device *dev) { int i; - if(useReserve && dev->nErasedBlocks < 1) + if(dev->nErasedBlocks < 1) { // Hoosterman we've got a problem. // Can't get space to gc return -1; } - else if(!useReserve && dev->nErasedBlocks <= YAFFS_RESERVED_BLOCKS) - { - // We are not in GC, so we hold some in reserve so we can get - // a gc done. - } // Find an empty block. @@ -1676,31 +1726,6 @@ static int yaffs_FindBlockForAllocation(yaffs_Device *dev,int useReserve) } -static void yaffs_BlockBecameDirty(yaffs_Device *dev,int blockNo) -{ - yaffs_BlockInfo *bi = &dev->blockInfo[blockNo]; - - // Mark as dirty. - // If the block is still healthy erase it and mark as clean. - // If the block has had a data failure, then retire it. - bi->blockState = YAFFS_BLOCK_STATE_DIRTY; - - if(!bi->needsRetiring && yaffs_EraseBlockInNAND(dev,blockNo)) - { - bi->blockState = YAFFS_BLOCK_STATE_EMPTY; - dev->nErasedBlocks++; - bi->pagesInUse = 0; - bi->pageBits = 0; - - T((TSTR("Erased block %d" TENDSTR),blockNo)); - } - else - { - yaffs_RetireBlock(dev,blockNo); - T((TSTR("**>> Block %d retired" TENDSTR),blockNo)); - } -} - static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve) { @@ -1709,10 +1734,16 @@ static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve) if(dev->allocationBlock < 0) { // Get next block to allocate off - dev->allocationBlock = yaffs_FindBlockForAllocation(dev,useReserve); + dev->allocationBlock = yaffs_FindBlockForAllocation(dev); dev->allocationPage = 0; } + if(!useReserve && dev->nErasedBlocks <= YAFFS_RESERVED_BLOCKS) + { + // Not enough space to allocate unless we're allowed to use the reserve. + return -1; + } + // Next page please.... if(dev->allocationBlock >= 0) { @@ -1733,12 +1764,7 @@ static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve) dev->allocationBlock = -1; } -#ifdef YAFFS_PARANOID - if(yaffs_CheckChunkErased(dev,retVal) == YAFFS_FAIL) - { - T((TSTR("..................Trying to allocate non-erased page %d" TENDSTR),retVal)); - } -#endif + return retVal; } @@ -2373,7 +2399,7 @@ int yaffs_WriteChunkDataToObject(yaffs_Object *in,int chunkInInode, const __u8 * // UpdateObjectHeader updates the header on NAND for an object. // If name is not NULL, then that new name is used. // -int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name) +int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name, int force) { yaffs_Device *dev = in->myDev; @@ -2388,7 +2414,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name) yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)bufferNew; yaffs_ObjectHeader *ohOld = (yaffs_ObjectHeader *)bufferOld; - if(!in->fake) + if(!in->fake || force) { yaffs_CheckGarbageCollection(dev); @@ -2413,17 +2439,29 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name) oh->st_ctime = in->st_ctime; oh->st_rdev = in->st_rdev; - oh->parentObjectId = in->parent->objectId; + if(in->parent) + { + oh->parentObjectId = in->parent->objectId; + } + else + { + oh->parentObjectId = 0; + } + oh->sum = in->sum; if(name && *name) { memset(oh->name,0,YAFFS_MAX_NAME_LENGTH + 1); strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH); } - else + else if(prevChunkId) { memcpy(oh->name, ohOld->name,YAFFS_MAX_NAME_LENGTH + 1); } + else + { + memset(oh->name,0,YAFFS_MAX_NAME_LENGTH + 1); + } switch(in->variantType) { @@ -2746,7 +2784,7 @@ int yaffs_FlushFile(yaffs_Object *in) in->st_mtime = CURRENT_TIME; - retVal = yaffs_UpdateObjectHeader(in,NULL); + retVal = yaffs_UpdateObjectHeader(in,NULL,0); } else { @@ -2896,7 +2934,7 @@ static int yaffs_UnlinkWorker(yaffs_Object *obj) yaffs_HashObject(hl); // Update the hardlink which has become an object - yaffs_UpdateObjectHeader(hl,NULL); + yaffs_UpdateObjectHeader(hl,NULL,0); // Finally throw away the deleted object yaffs_DeleteChunk(obj->myDev,obj->chunkId); @@ -3117,6 +3155,11 @@ static int yaffs_Scan(yaffs_Device *dev) if(in->variant.fileVariant.scannedFileSize variant.fileVariant.scannedFileSize = endpos; +#ifndef CONFIG_YAFFS_USE_HEADER_FILE_SIZE + in->variant.fileVariant.fileSize = + in->variant.fileVariant.scannedFileSize; +#endif + } //T((" %d %d data %d %d\n",blk,c,tags.objectId,tags.chunkId)); } @@ -3153,7 +3196,25 @@ static int yaffs_Scan(yaffs_Device *dev) } } - if(!in->valid) + if(!in->valid && + (tags.objectId == YAFFS_OBJECTID_ROOT || + tags.objectId == YAFFS_OBJECTID_LOSTNFOUND)) + { + // We only load some info, don't fiddle with directory structure + in->valid = 1; + in->variantType = oh->type; + + in->st_mode = oh->st_mode; + in->st_uid = oh->st_uid; + in->st_gid = oh->st_gid; + in->st_atime = oh->st_atime; + in->st_mtime = oh->st_mtime; + in->st_ctime = oh->st_ctime; + in->st_rdev = oh->st_rdev; + in->chunkId = chunk; + + } + else if(!in->valid) { // we need to load this info @@ -3202,7 +3263,9 @@ static int yaffs_Scan(yaffs_Device *dev) case YAFFS_OBJECT_TYPE_UNKNOWN: // Todo got a problem break; case YAFFS_OBJECT_TYPE_FILE: +#ifdef CONFIG_YAFFS_USE_HEADER_FILE_SIZE in->variant.fileVariant.fileSize = oh->fileSize; +#endif break; case YAFFS_OBJECT_TYPE_HARDLINK: in->variant.hardLinkVariant.equivalentObjectId = oh->equivalentObjectId; @@ -3496,7 +3559,7 @@ int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr) if(valid & ATTR_SIZE) yaffs_ResizeFile(obj,attr->ia_size); - yaffs_UpdateObjectHeader(obj,NULL); + yaffs_UpdateObjectHeader(obj,NULL,1); return YAFFS_OK; diff --git a/yaffs_mtdif.c b/yaffs_mtdif.c index 3f1e924..7f74b6f 100644 --- a/yaffs_mtdif.c +++ b/yaffs_mtdif.c @@ -12,7 +12,7 @@ * published by the Free Software Foundation. * */ - #ifdef YAFFS_MTD_ENABLED +#ifdef CONFIG_YAFFS_MTD_ENABLED #include "yportenv.h" @@ -100,5 +100,5 @@ int nandmtd_InitialiseNAND(yaffs_Device *dev) return YAFFS_OK; } -#endif // YAFFS_MTD_ENABLED +#endif // CONFIG_YAFFS_MTD_ENABLED diff --git a/yaffs_ramem.c b/yaffs_ramem.c index 2c8d0bc..2aebfe9 100644 --- a/yaffs_ramem.c +++ b/yaffs_ramem.c @@ -16,10 +16,10 @@ // Since this creates the RAM block at start up it is pretty useless for testing the scanner. #ifndef __KERNEL__ -#define YAFFS_RAM_ENABLED +#define CONFIG_YAFFS_RAM_ENABLED #endif -#ifdef YAFFS_RAM_ENABLED +#ifdef CONFIG_YAFFS_RAM_ENABLED #include "yportenv.h" diff --git a/yaffsdev b/yaffsdev index 551fec2..b217ad6 100755 Binary files a/yaffsdev and b/yaffsdev differ diff --git a/yaffsdev.c b/yaffsdev.c index 23d8f0c..ff4b7e6 100644 --- a/yaffsdev.c +++ b/yaffsdev.c @@ -160,8 +160,41 @@ void TestTime(yaffs_Device *dev) printf("Start\n"); - + // Test the problem of: + // Create file + // Delete file + // Create file with same name + // Delete file <== crash + 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"); + } + yaffs_Unlink(yaffs_Root(dev),"Name1"); + + + 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"); + } + yaffs_Unlink(yaffs_Root(dev),"Name1"); + + + + // Other tests + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); if(f) { diff --git a/yaffsdev.proj b/yaffsdev.proj index e57aca8..c0bc233 100644 Binary files a/yaffsdev.proj and b/yaffsdev.proj differ