From: charles Date: Wed, 1 Mar 2006 08:14:32 +0000 (+0000) Subject: Add lazy loading X-Git-Tag: pre-name-change~367 X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=commitdiff_plain;h=da27a11ac14cc0db3e7a8dbce75ec0ff18fb4334;hp=538f08e54c0d397762caaf029c7c289b8aec76a0 Add lazy loading --- diff --git a/yaffs_guts.c b/yaffs_guts.c index e949e31..ca1dd6a 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.29 2006-02-08 22:29:14 charles Exp $"; + "$Id: yaffs_guts.c,v 1.30 2006-03-01 08:14:32 charles Exp $"; #include "yportenv.h" @@ -4418,6 +4418,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; @@ -4441,6 +4481,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; @@ -4665,7 +4710,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 @@ -4700,21 +4753,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. @@ -4762,68 +4805,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 */ @@ -4852,7 +4923,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; } @@ -4871,31 +4942,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; @@ -4908,8 +4975,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; @@ -5087,6 +5154,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) { @@ -5164,6 +5233,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); diff --git a/yaffs_guts.h b/yaffs_guts.h index 7bf46c1..b1e9374 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -14,7 +14,7 @@ * * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. * - * $Id: yaffs_guts.h,v 1.18 2006-01-27 00:44:10 charles Exp $ + * $Id: yaffs_guts.h,v 1.19 2006-03-01 08:15:45 charles Exp $ */ #ifndef __YAFFS_GUTS_H__ @@ -386,13 +386,14 @@ struct yaffs_ObjectStruct { * object might be created before the data * is available (ie. file data records appear before the header). */ - __u8 serial; /* serial number of chunk in NAND. Cached here */ + __u8 lazyLoaded:1; /* This object has been lazy loaded and is missing some detail */ __u8 deferedFree:1; /* For Linux kernel. Object is removed from NAND, but is * still in the inode cache. Free of object is defered. * until the inode is released. */ + __u8 serial; /* serial number of chunk in NAND. Cached here */ __u16 sum; /* sum of the name to speed searching */ struct yaffs_DeviceStruct *myDev; /* The device I'm on */