X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=e8873e1debfd176641816a23490676e9eafddbec;hp=0ab8d8a051dcf81706e0f6ffce91e167ba144fe8;hb=751cba724040d777d1768dd5d4997039962d2608;hpb=6eceb5b64c0f77ca1cde968025e50a4f3f69f311 diff --git a/yaffs_guts.c b/yaffs_guts.c index 0ab8d8a..e8873e1 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -13,7 +13,7 @@ */ const char *yaffs_guts_c_version = - "$Id: yaffs_guts.c,v 1.28 2006-02-02 22:14:44 charles Exp $"; + "$Id: yaffs_guts.c,v 1.31 2006-03-08 07:59:20 charles Exp $"; #include "yportenv.h" @@ -2347,6 +2347,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block) ("yaffs: About to finally delete object %d" TENDSTR), object->objectId)); yaffs_DoGenericObjectDeletion(object); + object->myDev->nDeletedFiles--; } } @@ -3036,6 +3037,36 @@ static void yaffs_FlushFilesChunkCache(yaffs_Object * obj) } +/*yaffs_FlushEntireDeviceCache(dev) + * + * + */ + +void yaffs_FlushEntireDeviceCache(yaffs_Device *dev) +{ + yaffs_Object *obj; + int nCaches = dev->nShortOpCaches; + int i; + + /* Find a dirty object in the cache and flush it... + * until there are no further dirty objects. + */ + do { + obj = NULL; + for( i = 0; i < nCaches && !obj; i++) { + if (dev->srCache[i].object && + dev->srCache[i].dirty) + obj = dev->srCache[i].object; + + } + if(obj) + yaffs_FlushFilesChunkCache(obj); + + } while(obj); + +} + + /* Grab us a cache chunk for use. * First look for an empty one. * Then look for the least recently used non-dirty one. @@ -4417,6 +4448,46 @@ static int yaffs_Scan(yaffs_Device * dev) return YAFFS_OK; } +static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in) +{ + __u8 *chunkData; + yaffs_ObjectHeader *oh; + yaffs_Device *dev = in->myDev; + + if(in->lazyLoaded){ + in->lazyLoaded = 0; + chunkData = yaffs_GetTempBuffer(dev, __LINE__); + + yaffs_ReadChunkWithTagsFromNAND(dev,in->chunkId,chunkData,NULL); + 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); + + yaffs_ReleaseTempBuffer(dev,chunkData, __LINE__); + } +} + static int yaffs_ScanBackwards(yaffs_Device * dev) { yaffs_ExtendedTags tags; @@ -4440,6 +4511,11 @@ static int yaffs_ScanBackwards(yaffs_Device * dev) int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1; int itsUnlinked; __u8 *chunkData; + + int fileSize; + int isShrink; + int equivalentObjectId; + yaffs_BlockIndex *blockIndex = NULL; @@ -4664,7 +4740,15 @@ static int yaffs_ScanBackwards(yaffs_Device * dev) tags.extraObjectType); } - if (!in || !in->valid) { + 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 @@ -4699,21 +4783,11 @@ static int yaffs_ScanBackwards(yaffs_Device * dev) * 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)) + 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. @@ -4761,68 +4835,96 @@ static int yaffs_ScanBackwards(yaffs_Device * dev) YAFFS_OBJECTID_LOSTNFOUND)) { /* We only load some info, don't fiddle with directory structure */ in->valid = 1; - in->variantType = oh->type; + + if(oh) { + in->variantType = oh->type; - in->yst_mode = oh->yst_mode; + 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]; + 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; + 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->chunkId = chunk; } else if (!in->valid) { /* we need to load this info */ in->valid = 1; - in->variantType = oh->type; + in->chunkId = chunk; + + if(oh) { + in->variantType = oh->type; - in->yst_mode = oh->yst_mode; + 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]; + 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; + 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->chunkId = chunk; - if (oh->shadowsObject > 0) { - yaffs_HandleShadowedObject(dev, + 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; - 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 */ @@ -4851,7 +4953,7 @@ static int yaffs_ScanBackwards(yaffs_Device * dev) itsUnlinked = (parent == dev->deletedDir) || (parent == dev->unlinkedDir); - if (oh->isShrink) { + if (isShrink) { /* Mark the block as having a shrinkHeader */ bi->hasShrinkHeader = 1; } @@ -4870,31 +4972,27 @@ static int yaffs_ScanBackwards(yaffs_Device * dev) case YAFFS_OBJECT_TYPE_FILE: if (in->variant.fileVariant. - scannedFileSize < - oh->fileSize) { + 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 = - oh->fileSize; + in->variant.fileVariant.fileSize = fileSize; in->variant.fileVariant.scannedFileSize = in->variant.fileVariant.fileSize; } - if (oh->isShrink && - in->variant.fileVariant.shrinkSize > - oh->fileSize) { - in->variant.fileVariant.shrinkSize = - oh->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 = - oh->equivalentObjectId; + equivalentObjectId; in->hardLinks.next = (struct list_head *) hardList; hardList = in; @@ -4907,8 +5005,8 @@ static int yaffs_ScanBackwards(yaffs_Device * dev) /* Do nothing */ break; case YAFFS_OBJECT_TYPE_SYMLINK: - in->variant.symLinkVariant. - alias = + if(oh) + in->variant.symLinkVariant.alias = yaffs_CloneString(oh-> alias); break; @@ -5086,6 +5184,8 @@ yaffs_Object *yaffs_FindObjectByName(yaffs_Object * directory, list_for_each(i, &directory->variant.directoryVariant.children) { if (i) { l = list_entry(i, yaffs_Object, siblings); + + yaffs_CheckObjectDetailsLoaded(l); /* Special case for lost-n-found */ if (l->objectId == YAFFS_OBJECTID_LOSTNFOUND) { @@ -5163,6 +5263,8 @@ yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object * obj) int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize) { memset(name, 0, buffSize * sizeof(YCHAR)); + + yaffs_CheckObjectDetailsLoaded(obj); if (obj->objectId == YAFFS_OBJECTID_LOSTNFOUND) { yaffs_strncpy(name, YAFFS_LOSTNFOUND_NAME, buffSize - 1); @@ -5691,6 +5793,8 @@ int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev) nFree = yaffs_CountFreeChunks(dev); #endif + nFree += dev->nDeletedFiles; + /* Now count the number of dirty chunks in the cache and subtract those */ {