From: charles Date: Sun, 9 Jun 2002 07:36:54 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs%2F.git;a=commitdiff_plain;h=3f107ebf545c27322a15a458198a3cd5dbc876f3 *** empty log message *** --- diff --git a/Documentation/taffs-todo.html b/Documentation/taffs-todo.html deleted file mode 100644 index 1a81f4c..0000000 --- a/Documentation/taffs-todo.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - -

YAFFS Todo

-
    -
  1. Locking

    -
  2. Fix statfs. df does not give correct results.

    -
  3. Fix disk full condition. -

    -
  4. ECC and write failure handling.

    -
  5. Add symlinks and links to VFS interface.

    -
  6. Add memory mapping (to allow file execution).

    -
  7. Test with nandemul mtd.

    -
  8. Discuss improved NAND page interface with mtd group.

    -
-

NANDEmul MTD

-
    -
  1. Complete and test.

    -
  2. -

    -
-



-

- - \ No newline at end of file diff --git a/Documentation/yaffs-todo.html b/Documentation/yaffs-todo.html new file mode 100644 index 0000000..8489d72 --- /dev/null +++ b/Documentation/yaffs-todo.html @@ -0,0 +1,53 @@ + + + + + + + + + + + + +

YAFFS Todo as at 08/06/2002

+

Stuff not yet done

+
    +
  1. Directory locking during directory walk.

    +
  2. Other locking....

    +
  3. Test disk full condition. Might not be being handled + correctly.

    +
  4. Add write memory mapping. We probably need this to support + loop mounting.

    +
+

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

+
    +
  1. ECC and write failure handling.

    +
  2. Added symlinks and hard links to VFS interface.

    +
  3. Fixed problem with persistence. Object header was not being + updated at end of write and the file size was getting corrupted.

    +
  4. Fixed problem where obsoleted object headers were not being + deleted on NAND. This caused multiple file entries. Looks like it is + working properly now.

    +
  5. Read memory mapping. Can now execute a file from yaffs.

    +
  6. We now mark a chunk as deleted by marking the OOB data + validity flag. Before this we just stomped on the tags, which was + mot such a good thing to do with newer NANDs which do not like this + sort of thing.

    +
+

Done, but currently known to be broken

+
    +

    nothing.

    +
+

Longer term stuff to do

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

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

    +
+



+

+ + \ No newline at end of file diff --git a/snMakefile b/snMakefile index d7f5966..0872820 100644 --- a/snMakefile +++ b/snMakefile @@ -1,6 +1,6 @@ ######################################################### # Makefile auto generated by Cygnus Source Navigator. -# Target: yaffsdev_disk Date: May 29 2002 Time: 08:12:41 PM +# Target: yaffsdev_disk Date: Jun 05 2002 Time: 02:41:55 PM # diff --git a/yaffs_fs.c b/yaffs_fs.c index c3f57d7..6a2ddb3 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -83,11 +83,18 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf); static void yaffs_read_inode (struct inode *inode); static struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent); static void yaffs_put_inode (struct inode *inode); +static int yaffs_readpage(struct file *file, struct page * page); -//static int yaffs_readpage(struct file*,struct page * -static struct address_space_operations yaffs_address_ops = { -// readpage: yaffs_readpage, +static int yaffs_readlink(struct dentry *dentry, char *buffer, int buflen); +static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); + + + + + +static struct address_space_operations yaffs_file_address_operations = { + readpage: yaffs_readpage, // prepare_write: yaffs_prepare_write, // commit_write: yaffs_commit_write }; @@ -96,7 +103,7 @@ static struct address_space_operations yaffs_address_ops = { static struct file_operations yaffs_file_operations = { read: yaffs_file_read, write: yaffs_file_write, -// mmap: generic_file_mmap, + mmap: generic_file_mmap, fsync: yaffs_sync_object, }; @@ -106,11 +113,11 @@ static struct inode_operations yaffs_file_inode_operations = { }; - -static struct file_operations yaffs_dir_operations = { - read: generic_read_dir, - readdir: yaffs_readdir, - fsync: yaffs_sync_object, +struct inode_operations yaffs_symlink_inode_operations = +{ + readlink: yaffs_readlink, + follow_link: yaffs_follow_link, + setattr: yaffs_setattr }; static struct inode_operations yaffs_dir_inode_operations = { @@ -126,6 +133,13 @@ static struct inode_operations yaffs_dir_inode_operations = { setattr: yaffs_setattr, }; +static struct file_operations yaffs_dir_operations = { + read: generic_read_dir, + readdir: yaffs_readdir, + fsync: yaffs_sync_object, +}; + + static struct super_operations yaffs_super_ops = { statfs: yaffs_statfs, read_inode: yaffs_read_inode, @@ -137,6 +151,39 @@ static struct super_operations yaffs_super_ops = { }; + + + +static int yaffs_readlink(struct dentry *dentry, char *buffer, int buflen) +{ + unsigned char *alias; + int ret; + + alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); + + if(!alias) + return -ENOMEM; + + ret = vfs_readlink(dentry, buffer, buflen, alias); + kfree(alias); + return ret; +} + +static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + unsigned char *alias; + int ret; + alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); + + if(!alias) + return -ENOMEM; + + ret = vfs_follow_link(nd,alias); + kfree(alias); + return ret; +} + + struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,yaffs_Object *obj); /* @@ -152,6 +199,8 @@ static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry) obj = yaffs_FindObjectByName(yaffs_InodeToObject(dir),dentry->d_name.name); + obj = yaffs_GetEquivalentObject(obj); // in case it was a hardlink + if(obj) { T((KERN_DEBUG"yaffs_lookup found %d\n",obj->objectId)); @@ -185,15 +234,52 @@ static void yaffs_put_inode(struct inode *inode) } -#ifdef YAFFS_ADDRESS_OPS -static int yaffs_readpage(struct file *file, struct page * page) + + +static int yaffs_readpage(struct file *f, struct page * pg) { - T((KERN_DEBUG"yaffs_readpage\n")); + struct yaffs_Object *obj; + unsigned char *pg_buf; + int ret; + + T((KERN_DEBUG"yaffs_readpage at %08x, size %08x\n", + pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE)); - // TODO - return 0; + obj = yaffs_DentryToObject(f->f_dentry); + + //down(obj->sem); + + if (!PageLocked(pg)) + PAGE_BUG(pg); + + pg_buf = kmap(pg); + /* FIXME: Can kmap fail? */ + + ret = yaffs_ReadDataFromFile(obj,pg_buf, pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE); + + if(ret >= 0) ret = 0; + + if (ret) { + ClearPageUptodate(pg); + SetPageError(pg); + } else { + SetPageUptodate(pg); + ClearPageError(pg); + } + + flush_dcache_page(pg); + kunmap(pg); + + UnlockPage(pg); + + //up(&obj->sem); + + T((KERN_DEBUG"yaffs_readpage done\n")); + return ret; } +#ifdef YAFFS_ADDRESS_OPS + static int yaffs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) { T((KERN_DEBUG"yaffs_prepare_write\n")); @@ -227,7 +313,6 @@ static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj) inode->i_blksize = YAFFS_BYTES_PER_CHUNK; inode->i_blocks = 0; inode->i_rdev = NODEV; - inode->i_mapping->a_ops = &yaffs_address_ops; inode->i_atime = obj->st_atime; inode->i_mtime = obj->st_mtime; inode->i_ctime = obj->st_ctime; @@ -240,18 +325,19 @@ static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj) switch (obj->st_mode & S_IFMT) { default: - // init_special_inode(inode, mode, dev); + // init_special_inode(inode, mode, dev); break; case S_IFREG: // file inode->i_op = &yaffs_file_inode_operations; inode->i_fop = &yaffs_file_operations; + inode->i_mapping->a_ops = &yaffs_file_address_operations; break; case S_IFDIR: // directory inode->i_op = &yaffs_dir_inode_operations; inode->i_fop = &yaffs_dir_operations; break; case S_IFLNK: // symlink - inode->i_op = &page_symlink_inode_operations; + inode->i_op = &yaffs_symlink_inode_operations; break; } @@ -458,16 +544,13 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int d break; case S_IFLNK: // symlink T((KERN_DEBUG"yaffs_mknod: making file\n")); - obj = NULL; // Todo + obj = NULL; // Do we ever get here? break; } if(obj) { inode = yaffs_get_inode(dir->i_sb, mode, dev, obj); - -// did not fix dir bug if((mode & S_IFMT) == S_IFDIR) atomic_inc(&inode->i_count); - d_instantiate(dentry, inode); T((KERN_DEBUG"yaffs_mknod created object %d count = %d\n",obj->objectId,atomic_read(&inode->i_count))); error = 0; @@ -521,36 +604,52 @@ static int yaffs_unlink(struct inode * dir, struct dentry *dentry) /* - * Link a file.. + * Create a link... */ static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry) { struct inode *inode = old_dentry->d_inode; + yaffs_Object *obj = NULL; + yaffs_Object *link=NULL; T((KERN_DEBUG"yaffs_link\n")); - return -EPERM; //Todo + obj = yaffs_InodeToObject(inode); - - if (S_ISDIR(inode->i_mode)) - return -EPERM; - - - return 0; + link = yaffs_Link(yaffs_InodeToObject(dir),dentry->d_name.name,obj); + + if(link) + { + return 0; + } + + + return -EPERM; } static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) { - int error; + yaffs_Object *obj; T((KERN_DEBUG"yaffs_symlink\n")); - - return -ENOMEM; //Todo + obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name, + S_IFLNK | S_IRWXUGO, current->uid, current->gid, + symname); - error = yaffs_mknod(dir, dentry, S_IFLNK | S_IRWXUGO, 0); - return error; + if(obj) + { + T((KERN_DEBUG"symlink created OK\n")); + return 0; + } + else + { + T((KERN_DEBUG"symlink not created\n")); + + } + + return -ENOMEM; } static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync) diff --git a/yaffs_guts.c b/yaffs_guts.c index 88b02a3..4c7e81a 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -75,7 +75,6 @@ static int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name); static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId); static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj); static int yaffs_CheckStructures(void); -static yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj); loff_t yaffs_GetFileSize(yaffs_Object *obj); @@ -1127,6 +1126,12 @@ yaffs_Object *yaffs_MknodObject( yaffs_ObjectType type, yaffs_Device *dev = parent->myDev; + // Check if the entry exists. If it does then fail the call since we don't want a dup. + if(yaffs_FindObjectByName(parent,name)) + { + return NULL; + } + in = yaffs_CreateNewObject(dev,-1,type); if(in) @@ -1221,7 +1226,10 @@ static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir, const obj->dirty = 1; yaffs_AddObjectToDirectory(newDir,obj); - return yaffs_UpdateObjectHeader(obj,newName); + if(yaffs_UpdateObjectHeader(obj,newName) >= 0) + { + return YAFFS_OK; + } } return YAFFS_FAIL; @@ -1631,6 +1639,7 @@ static int yaffs_ReadChunkTagsFromNAND(yaffs_Device *dev,int chunkInNAND, yaffs_ return YAFFS_OK; } +#if 0 static int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND, const __u8 *buffer, yaffs_Tags *tags) { // NB There must be tags, data is optional @@ -1656,6 +1665,8 @@ static int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND, con return yaffs_WriteChunkToNAND(dev,chunkInNAND,buffer,&spare); } +#endif + static int yaffs_WriteNewChunkWithTagsToNAND(yaffs_Device *dev, const __u8 *buffer, yaffs_Tags *tags, int useReserve) { @@ -1921,18 +1932,18 @@ static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId) { int block = chunkId / YAFFS_CHUNKS_PER_BLOCK; int page = chunkId % YAFFS_CHUNKS_PER_BLOCK; - yaffs_Tags tags; + yaffs_Spare spare; + + yaffs_SpareInitialise(&spare); - // Mark the deleted NAND page as deleted - tags.chunkId = 0; - tags.objectId = 0; - tags.byteCount = 0; - tags.ecc = 0; + spare.pageStatus = 0; // To mark it as deleted. + - yaffs_WriteChunkWithTagsToNAND(dev,chunkId,NULL,&tags); + yaffs_WriteChunkToNAND(dev,chunkId,NULL,&spare); // Pull out of the management area. + // If the whole block became dirty, this will kick off an erasure. if( dev->blockInfo[block].blockState == YAFFS_BLOCK_STATE_ALLOCATING || dev->blockInfo[block].blockState == YAFFS_BLOCK_STATE_FULL) { @@ -2573,12 +2584,14 @@ static int yaffs_UnlinkWorker(yaffs_Object *obj) char name[YAFFS_MAX_NAME_LENGTH+1]; hl = list_entry(obj->hardLinks.next,yaffs_Object,hardLinks); + list_del_init(&hl->hardLinks); list_del_init(&hl->siblings); yaffs_GetObjectName(hl,name,YAFFS_MAX_NAME_LENGTH+1); retVal = yaffs_ChangeObjectName(obj, hl->parent, name); + if(retVal == YAFFS_OK) { retVal = yaffs_DoGenericObjectDeletion(hl); @@ -2636,12 +2649,12 @@ static int yaffs_Scan(yaffs_Device *dev) int chunk; int c; int deleted; - int inuse; yaffs_BlockState state; yaffs_Object *hardList = NULL; yaffs_Object *hl; - __u32 pageBits; +// int inuse; +// __u32 pageBits; yaffs_ObjectHeader *oh; yaffs_Object *in; @@ -2649,18 +2662,24 @@ static int yaffs_Scan(yaffs_Device *dev) __u8 chunkData[YAFFS_BYTES_PER_CHUNK]; + + // Scan all the blocks... + for(blk = dev->startBlock; blk <= dev->endBlock; blk++) { deleted = 0; - pageBits = 0; - inuse = 0; - state = YAFFS_BLOCK_STATE_UNKNOWN; + dev->blockInfo[blk].pageBits = 0; + dev->blockInfo[blk].pagesInUse = 0; + state = YAFFS_BLOCK_STATE_SCANNING; + + // Read each chunk in the block. for(c = 0; c < YAFFS_CHUNKS_PER_BLOCK && - state == YAFFS_BLOCK_STATE_UNKNOWN; c++) + state == YAFFS_BLOCK_STATE_SCANNING; c++) { // Read the spare area and decide what to do chunk = blk * YAFFS_CHUNKS_PER_BLOCK + c; + yaffs_ReadChunkFromNAND(dev,chunk,NULL,&spare); @@ -2670,7 +2689,14 @@ static int yaffs_Scan(yaffs_Device *dev) // This block looks ok, now what's in this chunk? yaffs_GetTagsFromSpare(&spare,&tags); - if(tags.objectId == YAFFS_UNUSED_OBJECT_ID) + if(yaffs_countBits[spare.pageStatus] < 6) + { + // A deleted chunk + deleted++; + dev->nFreeChunks ++; + T((" %d %d deleted\n",blk,c)); + } + else if(tags.objectId == YAFFS_UNUSED_OBJECT_ID) { // An unassigned chunk in the block // This means that either the block is empty or @@ -2693,20 +2719,14 @@ static int yaffs_Scan(yaffs_Device *dev) dev->nFreeChunks += (YAFFS_CHUNKS_PER_BLOCK - c); } - else if(tags.objectId == 0) - { - // A deleted chunk - deleted++; - dev->nFreeChunks ++; - T((" %d %d deleted\n",blk,c)); - } else if(tags.chunkId > 0) { // A data chunk. - inuse++; - pageBits |= ( 1 <blockInfo[blk].pageBits |= (1 << c); + dev->blockInfo[blk].pagesInUse++; + in = yaffs_FindOrCreateObjectByNumber(dev,tags.objectId,YAFFS_OBJECT_TYPE_FILE); - // PutChuunkIntoFIle checks for a clash (two data chunks with + // PutChunkIntoFIle checks for a clash (two data chunks with // the same chunkId). yaffs_PutChunkIntoFile(in,tags.chunkId,chunk,1); T((" %d %d data %d %d\n",blk,c,tags.objectId,tags.chunkId)); @@ -2714,78 +2734,99 @@ static int yaffs_Scan(yaffs_Device *dev) else { // chunkId == 0, so it is an ObjectHeader. - inuse++; - pageBits |= ( 1 <blockInfo[blk].pageBits |= (1 << c); + dev->blockInfo[blk].pagesInUse++; + yaffs_ReadChunkFromNAND(dev,chunk,chunkData,NULL); + oh = (yaffs_ObjectHeader *)chunkData; in = yaffs_FindOrCreateObjectByNumber(dev,tags.objectId,oh->type); + if(in->valid) { - // todo we have already filled this one. We have - // a duplicate. Need to fix + // We have already filled this one. We have a duplicate and need to resolve it. + + unsigned existingSerial = in->serial; + unsigned newSerial = tags.serialNumber; + + if(((existingSerial+1) & 3) == newSerial) + { + // Use new one - destroy the exisiting one + yaffs_DeleteChunk(dev,in->chunkId); + in->valid = 0; + } + else + { + // Use existing - destroy this one. + yaffs_DeleteChunk(dev,chunk); + } } - // we don't have a duplicate... + if(!in->valid) + { + // we need to load this info - 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->chunkId = chunk; - - in->sum = oh->sum; - in->dirty = 0; + 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->chunkId = chunk; + + in->sum = oh->sum; + in->dirty = 0; - // directory stuff... - // hook up to parent - - parent = yaffs_FindOrCreateObjectByNumber(dev,oh->parentObjectId,YAFFS_OBJECT_TYPE_DIRECTORY); - if(parent->variantType == YAFFS_OBJECT_TYPE_UNKNOWN) - { - // Set up as a directory - parent->variantType = YAFFS_OBJECT_TYPE_DIRECTORY; - INIT_LIST_HEAD(&parent->variant.directoryVariant.children); - } - else if(parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) - { - // Hoosterman, another problem.... - // We're trying to use a non-directory as a directory - // Todo ... handle - } + // directory stuff... + // hook up to parent + + parent = yaffs_FindOrCreateObjectByNumber(dev,oh->parentObjectId,YAFFS_OBJECT_TYPE_DIRECTORY); + if(parent->variantType == YAFFS_OBJECT_TYPE_UNKNOWN) + { + // Set up as a directory + parent->variantType = YAFFS_OBJECT_TYPE_DIRECTORY; + INIT_LIST_HEAD(&parent->variant.directoryVariant.children); + } + else if(parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) + { + // Hoosterman, another problem.... + // We're trying to use a non-directory as a directory + // Todo ... handle + } - yaffs_AddObjectToDirectory(parent,in); + yaffs_AddObjectToDirectory(parent,in); - // Note re hardlinks. - // Since we might scan a hardlink before its equivalent object is scanned - // we put them all in a list. - // After scanning is complete, we should have all the objects, so we run through this - // list and fix up all the chains. - - switch(in->variantType) - { - case YAFFS_OBJECT_TYPE_UNKNOWN: // Todo got a problem - break; - case YAFFS_OBJECT_TYPE_FILE: - in->variant.fileVariant.fileSize = oh->fileSize; - break; - case YAFFS_OBJECT_TYPE_HARDLINK: - in->variant.hardLinkVariant.equivalentObjectId = oh->equivalentObjectId; - (yaffs_Object *)(in->hardLinks.next) = hardList; - hardList = in; - break; - case YAFFS_OBJECT_TYPE_DIRECTORY: // Do nothing - break; - case YAFFS_OBJECT_TYPE_SYMLINK: // Do nothing - in->variant.symLinkVariant.alias = yaffs_CloneString(oh->alias); - break; + // Note re hardlinks. + // Since we might scan a hardlink before its equivalent object is scanned + // we put them all in a list. + // After scanning is complete, we should have all the objects, so we run through this + // list and fix up all the chains. + + switch(in->variantType) + { + case YAFFS_OBJECT_TYPE_UNKNOWN: // Todo got a problem + break; + case YAFFS_OBJECT_TYPE_FILE: + in->variant.fileVariant.fileSize = oh->fileSize; + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + in->variant.hardLinkVariant.equivalentObjectId = oh->equivalentObjectId; + (yaffs_Object *)(in->hardLinks.next) = hardList; + hardList = in; + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: // Do nothing + break; + case YAFFS_OBJECT_TYPE_SYMLINK: // Do nothing + in->variant.symLinkVariant.alias = yaffs_CloneString(oh->alias); + break; + } + T((" %d %d header %d \"%s\" type %d\n",blk,c,tags.objectId,oh->name,in->variantType)); } - T((" %d %d header %d \"%s\" type %d\n",blk,c,tags.objectId,oh->name,in->variantType)); } } else @@ -2795,21 +2836,26 @@ static int yaffs_Scan(yaffs_Device *dev) } } - if(state == YAFFS_BLOCK_STATE_UNKNOWN) + if(state == YAFFS_BLOCK_STATE_SCANNING) { - // If we got this far, then the block is fully allocated. - // ie. Full or Dirty - state = (inuse) ? YAFFS_BLOCK_STATE_FULL : YAFFS_BLOCK_STATE_DIRTY; - + // If we got this far while scanning, then the block is fully allocated. + state = YAFFS_BLOCK_STATE_FULL; } - dev->blockInfo[blk].pageBits = pageBits; - dev->blockInfo[blk].pagesInUse = inuse; dev->blockInfo[blk].blockState = state; + // Now let's see if it was dirty + if( dev->blockInfo[blk].pagesInUse == 0 && + dev->blockInfo[blk].blockState == YAFFS_BLOCK_STATE_FULL) + { + yaffs_BlockBecameDirty(dev,blk); + } + } - // Todo fix up the hard link chains + // Fix up the hard link chains. + // We should now have scanned all the objects, now it's time to add these + // hardlinks. while(hardList) { hl = hardList; @@ -2819,12 +2865,14 @@ static int yaffs_Scan(yaffs_Device *dev) if(in) { + // Add the hardlink pointers hl->variant.hardLinkVariant.equivalentObject=in; list_add(&hl->hardLinks,&in->hardLinks); } else { - //Todo Need to report this better. + //Todo Need to report/handle this better. + // Got a problem... hardlink to a non-existant object hl->variant.hardLinkVariant.equivalentObject=NULL; INIT_LIST_HEAD(&hl->hardLinks); @@ -2930,7 +2978,7 @@ int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,int (*fn)(yaffs_Object * // GetEquivalentObject dereferences any hard links to get to the // actual object. -static yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj) +yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj) { if(obj && obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) { @@ -3092,8 +3140,8 @@ int yaffs_DumpObject(yaffs_Object *obj) yaffs_GetObjectName(obj,name,256); - YPRINTF(("Object %d \"%s\"\n dirty %d valid %d serial %d sum %d chunk %d type %d size %d\n", - yaffs_GetObjectInode(obj), name, obj->dirty, obj->valid, obj->serial, + YPRINTF(("Object %d, inode %d \"%s\"\n dirty %d valid %d serial %d sum %d chunk %d type %d size %d\n", + obj->objectId,yaffs_GetObjectInode(obj), name, obj->dirty, obj->valid, obj->serial, obj->sum, obj->chunkId, yaffs_GetObjectType(obj), yaffs_GetObjectFileLength(obj))); #if 0 diff --git a/yaffs_guts.h b/yaffs_guts.h index 7b059aa..3ae36e7 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -108,7 +108,9 @@ typedef struct // Block data in RAM typedef enum { - YAFFS_BLOCK_STATE_UNKNOWN = 0, + YAFFS_BLOCK_STATE_UddNKNOWN = 0, + YAFFS_BLOCK_STATE_SCANNING, // Used while the block is being scanned. + // NB Don't erase blocks while they're being scanned YAFFS_BLOCK_STATE_EMPTY, // This block is empty @@ -420,6 +422,8 @@ yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev,int number); // Link operations yaffs_Object *yaffs_Link(yaffs_Object *parent, const char *name, yaffs_Object *equivalentObject); +yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj); + // Symlink operations yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent, const char *name, __u32 mode, __u32 uid, __u32 gid, const char *alias); char *yaffs_GetSymlinkAlias(yaffs_Object *obj); diff --git a/yaffsdev b/yaffsdev index 70d4cc2..1477789 100755 Binary files a/yaffsdev and b/yaffsdev differ diff --git a/yaffsdev.c b/yaffsdev.c index e38a983..9675dab 100644 --- a/yaffsdev.c +++ b/yaffsdev.c @@ -155,8 +155,16 @@ void TestTime(yaffs_Device *dev) 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) @@ -285,6 +293,10 @@ void TestTime(yaffs_Device *dev) x = yaffs_RenameObject(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME,NULL,"Renamed"); yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + f = yaffs_MknodFile(yaffs_Root(dev),"pfile",0,0,0); + yaffs_WriteDataToFile(f,testStr,0,strlen(testStr)); + + yaffs_Link(yaffs_Root(dev),"phl4",f); } int main(int argc,char *argv[]) diff --git a/yaffsdev.proj b/yaffsdev.proj index fc2bac3..e3e07f4 100644 Binary files a/yaffsdev.proj and b/yaffsdev.proj differ