- if (in && in->valid) {
- /* 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->hdrChunk,
- 1, __LINE__);
- in->valid = 0;
- } else {
- /* Use existing - destroy this one. */
- yaffs_DeleteChunk(dev, chunk, 1,
- __LINE__);
- }
- }
-
- if (in && !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->yst_mode = oh->yst_mode;
-#ifdef CONFIG_YAFFS_WINCE
- in->win_atime[0] = oh->win_atime[0];
- in->win_ctime[0] = oh->win_ctime[0];
- in->win_mtime[0] = oh->win_mtime[0];
- in->win_atime[1] = oh->win_atime[1];
- in->win_ctime[1] = oh->win_ctime[1];
- in->win_mtime[1] = oh->win_mtime[1];
-#else
- in->yst_uid = oh->yst_uid;
- in->yst_gid = oh->yst_gid;
- in->yst_atime = oh->yst_atime;
- in->yst_mtime = oh->yst_mtime;
- in->yst_ctime = oh->yst_ctime;
- in->yst_rdev = oh->yst_rdev;
-#endif
- in->hdrChunk = chunk;
- in->serial = tags.serialNumber;
-
- } else if (in && !in->valid) {
- /* we need to load this info */
-
- in->valid = 1;
- in->variantType = oh->type;
-
- in->yst_mode = oh->yst_mode;
-#ifdef CONFIG_YAFFS_WINCE
- in->win_atime[0] = oh->win_atime[0];
- in->win_ctime[0] = oh->win_ctime[0];
- in->win_mtime[0] = oh->win_mtime[0];
- in->win_atime[1] = oh->win_atime[1];
- in->win_ctime[1] = oh->win_ctime[1];
- in->win_mtime[1] = oh->win_mtime[1];
-#else
- in->yst_uid = oh->yst_uid;
- in->yst_gid = oh->yst_gid;
- in->yst_atime = oh->yst_atime;
- in->yst_mtime = oh->yst_mtime;
- in->yst_ctime = oh->yst_ctime;
- in->yst_rdev = oh->yst_rdev;
-#endif
- in->hdrChunk = chunk;
- in->serial = tags.serialNumber;
-
- yaffs_SetObjectName(in, oh->name);
- 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;
- YINIT_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
- */
-
- T(YAFFS_TRACE_ERROR,
- (TSTR
- ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
- TENDSTR)));
- parent = dev->lostNFoundDir;
- }
-
- yaffs_AddObjectToDirectory(parent, in);
-
- if (0 && (parent == dev->deletedDir ||
- parent == dev->unlinkedDir)) {
- in->deleted = 1; /* If it is unlinked at start up then it wants deleting */
- dev->nDeletedFiles++;
- }
- /* 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:
- if (dev->useHeaderFileSize)
-
- in->variant.fileVariant.
- fileSize =
- oh->fileSize;
-
- break;
- case YAFFS_OBJECT_TYPE_HARDLINK:
- in->variant.hardLinkVariant.
- equivalentObjectId =
- oh->equivalentObjectId;
- in->hardLinks.next =
- (struct ylist_head *)
- hardList;
- hardList = in;
- break;
- case YAFFS_OBJECT_TYPE_DIRECTORY:
- /* Do nothing */
- break;
- case YAFFS_OBJECT_TYPE_SPECIAL:
- /* Do nothing */
- break;
- case YAFFS_OBJECT_TYPE_SYMLINK:
- in->variant.symLinkVariant.alias =
- yaffs_CloneString(oh->alias);
- if(!in->variant.symLinkVariant.alias)
- alloc_failed = 1;
- break;
- }
-
-/*
- if (parent == dev->deletedDir) {
- yaffs_DestroyObject(in);
- bi->hasShrinkHeader = 1;
- }
-*/
- }
- }
- }
-
- if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
- /* If we got this far while scanning, then the block is fully allocated.*/
- state = YAFFS_BLOCK_STATE_FULL;
- }
-
- bi->blockState = state;
-
- /* Now let's see if it was dirty */
- if (bi->pagesInUse == 0 &&
- !bi->hasShrinkHeader &&
- bi->blockState == YAFFS_BLOCK_STATE_FULL) {
- yaffs_BlockBecameDirty(dev, blk);
- }
-
- }
-
-
- /* Ok, we've done all the scanning.
- * Fix up the hard link chains.
- * We should now have scanned all the objects, now it's time to add these
- * hardlinks.
- */
-
- yaffs_HardlinkFixup(dev,hardList);
-
- /* Handle the unlinked files. Since they were left in an unlinked state we should
- * just delete them.
- */
- {
- struct ylist_head *i;
- struct ylist_head *n;
-
- yaffs_Object *l;
- /* Soft delete all the unlinked files */
- ylist_for_each_safe(i, n,
- &dev->unlinkedDir->variant.directoryVariant.
- children) {
- if (i) {
- l = ylist_entry(i, yaffs_Object, siblings);
- yaffs_DestroyObject(l);
- }
- }
- }
-
- /* Fix up any shadowed objects */
- {
- struct yaffs_ShadowFixerStruct *fixer;
- yaffs_Object *obj;
-
- while(shadowFixerList){
- fixer = shadowFixerList;
- shadowFixerList = fixer->next;
- /* Complete the rename transaction by deleting the shadowed object
- * then setting the object header to unshadowed.
- */
- obj = yaffs_FindObjectByNumber(dev,fixer->shadowedId);
- if(obj)
- yaffs_DestroyObject(obj);
-
- obj = yaffs_FindObjectByNumber(dev,fixer->objectId);
- if(obj){
- yaffs_UpdateObjectHeader(obj,NULL,1,0,0);
- }
-
- YFREE(fixer);
- }
- }
-
- yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
-
- if(alloc_failed){
- return YAFFS_FAIL;
- }
-
- T(YAFFS_TRACE_SCAN, (TSTR("yaffs_Scan ends" TENDSTR)));
-
-
- return YAFFS_OK;
-}
-
-static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in)
-{
- __u8 *chunkData;
- yaffs_ObjectHeader *oh;
- yaffs_Device *dev;
- yaffs_ExtendedTags tags;
- int result;
- int alloc_failed = 0;
-
- if(!in)
- return;
-
- dev = in->myDev;
-
-#if 0
- T(YAFFS_TRACE_SCAN,(TSTR("details for object %d %s loaded" TENDSTR),
- in->objectId,
- in->lazyLoaded ? "not yet" : "already"));
-#endif
-
- if(in->lazyLoaded && in->hdrChunk > 0){
- in->lazyLoaded = 0;
- chunkData = yaffs_GetTempBuffer(dev, __LINE__);
-
- result = yaffs_ReadChunkWithTagsFromNAND(dev,in->hdrChunk,chunkData,&tags);
- oh = (yaffs_ObjectHeader *) chunkData;
-
- in->yst_mode = oh->yst_mode;
-#ifdef CONFIG_YAFFS_WINCE
- in->win_atime[0] = oh->win_atime[0];
- in->win_ctime[0] = oh->win_ctime[0];
- in->win_mtime[0] = oh->win_mtime[0];
- in->win_atime[1] = oh->win_atime[1];
- in->win_ctime[1] = oh->win_ctime[1];
- in->win_mtime[1] = oh->win_mtime[1];
-#else
- in->yst_uid = oh->yst_uid;
- in->yst_gid = oh->yst_gid;
- in->yst_atime = oh->yst_atime;
- in->yst_mtime = oh->yst_mtime;
- in->yst_ctime = oh->yst_ctime;
- in->yst_rdev = oh->yst_rdev;
-
-#endif
- yaffs_SetObjectName(in, oh->name);
-
- if(in->variantType == YAFFS_OBJECT_TYPE_SYMLINK){
- in->variant.symLinkVariant.alias =
- yaffs_CloneString(oh->alias);
- if(!in->variant.symLinkVariant.alias)
- alloc_failed = 1; /* Not returned to caller */
- }
-
- yaffs_ReleaseTempBuffer(dev,chunkData, __LINE__);
- }
-}
-
-static int yaffs_ScanBackwards(yaffs_Device * dev)
-{
- yaffs_ExtendedTags tags;
- int blk;
- int blockIterator;
- int startIterator;
- int endIterator;
- int nBlocksToScan = 0;
-
- int chunk;
- int result;
- int c;
- int deleted;
- yaffs_BlockState state;
- yaffs_Object *hardList = NULL;
- yaffs_BlockInfo *bi;
- __u32 sequenceNumber;
- yaffs_ObjectHeader *oh;
- yaffs_Object *in;
- yaffs_Object *parent;
- int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1;
- int itsUnlinked;
- __u8 *chunkData;
-
- int fileSize;
- int isShrink;
- int foundChunksInBlock;
- int equivalentObjectId;
- int alloc_failed = 0;
-
-
- yaffs_BlockIndex *blockIndex = NULL;
- int altBlockIndex = 0;
-
- if (!dev->isYaffs2) {
- T(YAFFS_TRACE_SCAN,
- (TSTR("yaffs_ScanBackwards is only for YAFFS2!" TENDSTR)));
- return YAFFS_FAIL;
- }
-
- T(YAFFS_TRACE_SCAN,
- (TSTR
- ("yaffs_ScanBackwards starts intstartblk %d intendblk %d..."
- TENDSTR), dev->internalStartBlock, dev->internalEndBlock));
-
-
- dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;
-
- blockIndex = YMALLOC(nBlocks * sizeof(yaffs_BlockIndex));
-
- if(!blockIndex) {
- blockIndex = YMALLOC_ALT(nBlocks * sizeof(yaffs_BlockIndex));
- altBlockIndex = 1;
- }
-
- if(!blockIndex) {
- T(YAFFS_TRACE_SCAN,
- (TSTR("yaffs_Scan() could not allocate block index!" TENDSTR)));
- return YAFFS_FAIL;
- }
-
- dev->blocksInCheckpoint = 0;
-
- chunkData = yaffs_GetTempBuffer(dev, __LINE__);
-
- /* Scan all the blocks to determine their state */
- for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) {
- bi = yaffs_GetBlockInfo(dev, blk);
- yaffs_ClearChunkBits(dev, blk);
- bi->pagesInUse = 0;
- bi->softDeletions = 0;
-
- yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber);
-
- bi->blockState = state;
- bi->sequenceNumber = sequenceNumber;
-
- if(bi->sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA)
- bi->blockState = state = YAFFS_BLOCK_STATE_CHECKPOINT;
-
- T(YAFFS_TRACE_SCAN_DEBUG,
- (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
- state, sequenceNumber));
-
-
- if(state == YAFFS_BLOCK_STATE_CHECKPOINT){
- dev->blocksInCheckpoint++;
-
- } else if (state == YAFFS_BLOCK_STATE_DEAD) {
- T(YAFFS_TRACE_BAD_BLOCKS,
- (TSTR("block %d is bad" TENDSTR), blk));
- } else if (state == YAFFS_BLOCK_STATE_EMPTY) {
- T(YAFFS_TRACE_SCAN_DEBUG,
- (TSTR("Block empty " TENDSTR)));
- dev->nErasedBlocks++;
- dev->nFreeChunks += dev->nChunksPerBlock;
- } else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
-
- /* Determine the highest sequence number */
- if (sequenceNumber >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
- sequenceNumber < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
-
- blockIndex[nBlocksToScan].seq = sequenceNumber;
- blockIndex[nBlocksToScan].block = blk;
-
- nBlocksToScan++;
-
- if (sequenceNumber >= dev->sequenceNumber) {
- dev->sequenceNumber = sequenceNumber;
- }
- } else {
- /* TODO: Nasty sequence number! */
- T(YAFFS_TRACE_SCAN,
- (TSTR
- ("Block scanning block %d has bad sequence number %d"
- TENDSTR), blk, sequenceNumber));
-
- }
- }
- }
-
- T(YAFFS_TRACE_SCAN,
- (TSTR("%d blocks to be sorted..." TENDSTR), nBlocksToScan));
-
-
-
- YYIELD();
-
- /* Sort the blocks */
-#ifndef CONFIG_YAFFS_USE_OWN_SORT
- {
- /* Use qsort now. */
- yaffs_qsort(blockIndex, nBlocksToScan, sizeof(yaffs_BlockIndex), ybicmp);
- }
-#else
- {
- /* Dungy old bubble sort... */
-
- yaffs_BlockIndex temp;
- int i;
- int j;
-
- for (i = 0; i < nBlocksToScan; i++)
- for (j = i + 1; j < nBlocksToScan; j++)
- if (blockIndex[i].seq > blockIndex[j].seq) {
- temp = blockIndex[j];
- blockIndex[j] = blockIndex[i];
- blockIndex[i] = temp;
- }
- }
-#endif
-
- YYIELD();
-
- T(YAFFS_TRACE_SCAN, (TSTR("...done" TENDSTR)));
-
- /* Now scan the blocks looking at the data. */
- startIterator = 0;
- endIterator = nBlocksToScan - 1;
- T(YAFFS_TRACE_SCAN_DEBUG,
- (TSTR("%d blocks to be scanned" TENDSTR), nBlocksToScan));
-
- /* For each block.... backwards */
- for (blockIterator = endIterator; !alloc_failed && blockIterator >= startIterator;
- blockIterator--) {
- /* Cooperative multitasking! This loop can run for so
- long that watchdog timers expire. */
- YYIELD();
-
- /* get the block to scan in the correct order */
- blk = blockIndex[blockIterator].block;
-
- bi = yaffs_GetBlockInfo(dev, blk);
-
-
- state = bi->blockState;
-
- deleted = 0;
-
- /* For each chunk in each block that needs scanning.... */
- foundChunksInBlock = 0;
- for (c = dev->nChunksPerBlock - 1;
- !alloc_failed && c >= 0 &&
- (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
- state == YAFFS_BLOCK_STATE_ALLOCATING); c--) {
- /* Scan backwards...
- * Read the tags and decide what to do
- */
-
- chunk = blk * dev->nChunksPerBlock + c;
-
- result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL,
- &tags);
-
- /* Let's have a good look at this chunk... */
-
- if (!tags.chunkUsed) {
- /* An unassigned chunk in the block.
- * If there are used chunks after this one, then
- * it is a chunk that was skipped due to failing the erased
- * check. Just skip it so that it can be deleted.
- * But, more typically, We get here when this is an unallocated
- * chunk and his means that either the block is empty or
- * this is the one being allocated from
- */
-
- if(foundChunksInBlock)
- {
- /* This is a chunk that was skipped due to failing the erased check */
-
- } else if (c == 0) {
- /* We're looking at the first chunk in the block so the block is unused */
- state = YAFFS_BLOCK_STATE_EMPTY;
- dev->nErasedBlocks++;
- } else {
- if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
- state == YAFFS_BLOCK_STATE_ALLOCATING) {
- if(dev->sequenceNumber == bi->sequenceNumber) {
- /* this is the block being allocated from */
-
- T(YAFFS_TRACE_SCAN,
- (TSTR
- (" Allocating from %d %d"
- TENDSTR), blk, c));
-
- state = YAFFS_BLOCK_STATE_ALLOCATING;
- dev->allocationBlock = blk;
- dev->allocationPage = c;
- dev->allocationBlockFinder = blk;
- }
- else {
- /* This is a partially written block that is not
- * the current allocation block. This block must have
- * had a write failure, so set up for retirement.
- */
-
- /* bi->needsRetiring = 1; ??? TODO */
- bi->gcPrioritise = 1;
-
- T(YAFFS_TRACE_ALWAYS,
- (TSTR("Partially written block %d detected" TENDSTR),
- blk));
- }
-
- }
-
- }
-
- dev->nFreeChunks++;
-
- } else if (tags.chunkId > 0) {
- /* chunkId > 0 so it is a data chunk... */
- unsigned int endpos;
- __u32 chunkBase =
- (tags.chunkId - 1) * dev->nDataBytesPerChunk;
-
- foundChunksInBlock = 1;
-
-
- yaffs_SetChunkBit(dev, blk, c);
- bi->pagesInUse++;
-
- in = yaffs_FindOrCreateObjectByNumber(dev,
- tags.
- objectId,
- YAFFS_OBJECT_TYPE_FILE);
- if(!in){
- /* Out of memory */
- alloc_failed = 1;
- }
-
- if (in &&
- in->variantType == YAFFS_OBJECT_TYPE_FILE
- && chunkBase <
- in->variant.fileVariant.shrinkSize) {
- /* This has not been invalidated by a resize */
- if(!yaffs_PutChunkIntoFile(in, tags.chunkId,
- chunk, -1)){
- alloc_failed = 1;
- }
-
- /* File size is calculated by looking at the data chunks if we have not
- * seen an object header yet. Stop this practice once we find an object header.
- */
- endpos =
- (tags.chunkId -
- 1) * dev->nDataBytesPerChunk +
- tags.byteCount;
-
- if (!in->valid && /* have not got an object header yet */
- in->variant.fileVariant.
- scannedFileSize < endpos) {
- in->variant.fileVariant.
- scannedFileSize = endpos;
- in->variant.fileVariant.
- fileSize =
- in->variant.fileVariant.
- scannedFileSize;
- }
-
- } else if(in) {
- /* This chunk has been invalidated by a resize, so delete */
- yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
-
- }
- } else {
- /* chunkId == 0, so it is an ObjectHeader.
- * Thus, we read in the object header and make the object
- */
- foundChunksInBlock = 1;
-
- yaffs_SetChunkBit(dev, blk, c);
- bi->pagesInUse++;
-
- oh = NULL;
- in = NULL;
-
- if (tags.extraHeaderInfoAvailable) {
- in = yaffs_FindOrCreateObjectByNumber
- (dev, tags.objectId,
- tags.extraObjectType);
- }
-
- if (!in ||
-#ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD
- !in->valid ||
-#endif
- tags.extraShadows ||
- (!in->valid &&
- (tags.objectId == YAFFS_OBJECTID_ROOT ||
- tags.objectId == YAFFS_OBJECTID_LOSTNFOUND))
- ) {
-
- /* If we don't have valid info then we need to read the chunk
- * TODO In future we can probably defer reading the chunk and
- * living with invalid data until needed.
- */
-
- result = yaffs_ReadChunkWithTagsFromNAND(dev,
- chunk,
- chunkData,
- NULL);
-
- oh = (yaffs_ObjectHeader *) chunkData;
-
- if(dev->inbandTags){
- /* Fix up the header if they got corrupted by inband tags */
- oh->shadowsObject = oh->inbandShadowsObject;
- oh->isShrink = oh->inbandIsShrink;
- }
-
- if (!in)
- in = yaffs_FindOrCreateObjectByNumber(dev, tags.objectId, oh->type);
-
- }
-
- if (!in) {
- /* TODO Hoosterman we have a problem! */
- T(YAFFS_TRACE_ERROR,
- (TSTR
- ("yaffs tragedy: Could not make object for object %d at chunk %d during scan"
- TENDSTR), tags.objectId, chunk));
-
- }
-
- if (in->valid) {
- /* We have already filled this one.
- * We have a duplicate that will be discarded, but
- * we first have to suck out resize info if it is a file.
- */
-
- if ((in->variantType == YAFFS_OBJECT_TYPE_FILE) &&
- ((oh &&
- oh-> type == YAFFS_OBJECT_TYPE_FILE)||
- (tags.extraHeaderInfoAvailable &&
- tags.extraObjectType == YAFFS_OBJECT_TYPE_FILE))
- ) {
- __u32 thisSize =
- (oh) ? oh->fileSize : tags.
- extraFileLength;
- __u32 parentObjectId =
- (oh) ? oh->
- parentObjectId : tags.
- extraParentObjectId;
-
-
- isShrink =
- (oh) ? oh->isShrink : tags.
- extraIsShrinkHeader;
-
- /* If it is deleted (unlinked at start also means deleted)
- * we treat the file size as being zeroed at this point.
- */
- if (parentObjectId ==
- YAFFS_OBJECTID_DELETED
- || parentObjectId ==
- YAFFS_OBJECTID_UNLINKED) {
- thisSize = 0;
- isShrink = 1;
- }
-
- if (isShrink &&
- in->variant.fileVariant.
- shrinkSize > thisSize) {
- in->variant.fileVariant.
- shrinkSize =
- thisSize;
- }
-
- if (isShrink) {
- bi->hasShrinkHeader = 1;
- }
-
- }
- /* Use existing - destroy this one. */
- yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
-
- }
-
- 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;
-
- if(oh) {
- in->variantType = oh->type;
-
- in->yst_mode = oh->yst_mode;
-#ifdef CONFIG_YAFFS_WINCE
- in->win_atime[0] = oh->win_atime[0];
- in->win_ctime[0] = oh->win_ctime[0];
- in->win_mtime[0] = oh->win_mtime[0];
- in->win_atime[1] = oh->win_atime[1];
- in->win_ctime[1] = oh->win_ctime[1];
- in->win_mtime[1] = oh->win_mtime[1];
-#else
- in->yst_uid = oh->yst_uid;
- in->yst_gid = oh->yst_gid;
- in->yst_atime = oh->yst_atime;
- in->yst_mtime = oh->yst_mtime;
- in->yst_ctime = oh->yst_ctime;
- in->yst_rdev = oh->yst_rdev;
-
-#endif
- } else {
- in->variantType = tags.extraObjectType;
- in->lazyLoaded = 1;
- }
-
- in->hdrChunk = chunk;
-
- } else if (!in->valid) {
- /* we need to load this info */
-
- in->valid = 1;
- in->hdrChunk = chunk;
-
- if(oh) {
- in->variantType = oh->type;
-
- in->yst_mode = oh->yst_mode;
-#ifdef CONFIG_YAFFS_WINCE
- in->win_atime[0] = oh->win_atime[0];
- in->win_ctime[0] = oh->win_ctime[0];
- in->win_mtime[0] = oh->win_mtime[0];
- in->win_atime[1] = oh->win_atime[1];
- in->win_ctime[1] = oh->win_ctime[1];
- in->win_mtime[1] = oh->win_mtime[1];
-#else
- in->yst_uid = oh->yst_uid;
- in->yst_gid = oh->yst_gid;
- in->yst_atime = oh->yst_atime;
- in->yst_mtime = oh->yst_mtime;
- in->yst_ctime = oh->yst_ctime;
- in->yst_rdev = oh->yst_rdev;
-#endif
-
- if (oh->shadowsObject > 0)
- yaffs_HandleShadowedObject(dev,
- oh->
- shadowsObject,
- 1);
-
-
- yaffs_SetObjectName(in, oh->name);
- parent =
- yaffs_FindOrCreateObjectByNumber
- (dev, oh->parentObjectId,
- YAFFS_OBJECT_TYPE_DIRECTORY);
-
- fileSize = oh->fileSize;
- isShrink = oh->isShrink;
- equivalentObjectId = oh->equivalentObjectId;
-
- }
- else {
- in->variantType = tags.extraObjectType;
- parent =
- yaffs_FindOrCreateObjectByNumber
- (dev, tags.extraParentObjectId,
- YAFFS_OBJECT_TYPE_DIRECTORY);
- fileSize = tags.extraFileLength;
- isShrink = tags.extraIsShrinkHeader;
- equivalentObjectId = tags.extraEquivalentObjectId;
- in->lazyLoaded = 1;
-
- }
- in->dirty = 0;
-
- /* directory stuff...
- * hook up to parent
- */
-
- if (parent->variantType ==
- YAFFS_OBJECT_TYPE_UNKNOWN) {
- /* Set up as a directory */
- parent->variantType =
- YAFFS_OBJECT_TYPE_DIRECTORY;
- YINIT_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
- */
-
- T(YAFFS_TRACE_ERROR,
- (TSTR
- ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
- TENDSTR)));
- parent = dev->lostNFoundDir;
- }
-
- yaffs_AddObjectToDirectory(parent, in);
-
- itsUnlinked = (parent == dev->deletedDir) ||
- (parent == dev->unlinkedDir);
-
- if (isShrink) {
- /* Mark the block as having a shrinkHeader */
- bi->hasShrinkHeader = 1;
- }
-
- /* 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:
-
- if (in->variant.fileVariant.
- scannedFileSize < fileSize) {
- /* This covers the case where the file size is greater
- * than where the data is
- * This will happen if the file is resized to be larger
- * than its current data extents.
- */
- in->variant.fileVariant.fileSize = fileSize;
- in->variant.fileVariant.scannedFileSize =
- in->variant.fileVariant.fileSize;
- }
-
- if (isShrink &&
- in->variant.fileVariant.shrinkSize > fileSize) {
- in->variant.fileVariant.shrinkSize = fileSize;
- }
-
- break;
- case YAFFS_OBJECT_TYPE_HARDLINK:
- if(!itsUnlinked) {
- in->variant.hardLinkVariant.equivalentObjectId =
- equivalentObjectId;
- in->hardLinks.next =
- (struct ylist_head *) hardList;
- hardList = in;
- }
- break;
- case YAFFS_OBJECT_TYPE_DIRECTORY:
- /* Do nothing */
- break;
- case YAFFS_OBJECT_TYPE_SPECIAL:
- /* Do nothing */
- break;
- case YAFFS_OBJECT_TYPE_SYMLINK:
- if(oh){
- in->variant.symLinkVariant.alias =
- yaffs_CloneString(oh->
- alias);
- if(!in->variant.symLinkVariant.alias)
- alloc_failed = 1;
- }
- break;
- }