* published by the Free Software Foundation.
*/
+
const char *yaffs_guts_c_version =
- "$Id: yaffs_guts.c,v 1.68 2008-11-27 20:32:52 charles Exp $";
+ "$Id: yaffs_guts.c,v 1.72 2009-01-16 00:44:45 charles Exp $";
#include "yportenv.h"
yaffs_VerifyBlock(dev,bi,n);
/* After collection the block should be in the erased state */
- /* TODO: This will need to change if we do partial gc */
+ /* This will need to change if we do partial gc */
- if(bi->blockState != YAFFS_BLOCK_STATE_EMPTY){
+ if(bi->blockState != YAFFS_BLOCK_STATE_COLLECTING &&
+ bi->blockState != YAFFS_BLOCK_STATE_EMPTY){
T(YAFFS_TRACE_ERROR,(TSTR("Block %d is in state %d after gc, should be erased"TENDSTR),
n,bi->blockState));
}
}
} else if (level == 0) {
__u32 baseOffset = chunkOffset << YAFFS_TNODES_LEVEL0_BITS;
- /* printf("write tnode at %d\n",baseOffset); */
ok = (yaffs_CheckpointWrite(dev,&baseOffset,sizeof(baseOffset)) == sizeof(baseOffset));
if(ok)
ok = (yaffs_CheckpointWrite(dev,tn,tnodeSize) == tnodeSize);
/* Read level 0 tnode */
- /* printf("read tnode at %d\n",baseChunk); */
tn = yaffs_GetTnodeRaw(dev);
if(tn)
ok = (yaffs_CheckpointRead(dev,tn,tnodeSize) == tnodeSize);
int nToWriteBack;
int startOfWrite = offset;
int chunkWritten = 0;
- int nBytesRead;
+ __u32 nBytesRead;
+ __u32 chunkStart;
yaffs_Device *dev;
* we need to write back as much as was there before.
*/
- nBytesRead =
- in->variant.fileVariant.fileSize -
- ((chunk - 1) * dev->nDataBytesPerChunk);
+ chunkStart = ((chunk - 1) * dev->nDataBytesPerChunk);
+
+ if(chunkStart > in->variant.fileVariant.fileSize)
+ nBytesRead = 0; /* Past end of file */
+ else
+ nBytesRead = in->variant.fileVariant.fileSize - chunkStart;
if (nBytesRead > dev->nDataBytesPerChunk) {
nBytesRead = dev->nDataBytesPerChunk;
nToWriteBack =
(nBytesRead >
- ((int)start + n)) ? nBytesRead : (start + n);
+ (start + n)) ? nBytesRead : (start + n);
+
+ if(nToWriteBack < 0 || nToWriteBack > dev->nDataBytesPerChunk)
+ YBUG();
} else {
nToCopy = dev->nDataBytesPerChunk - start;
struct yaffs_ShadowFixerStruct *next;
};
+
+static void yaffs_StripDeletedObjects(yaffs_Device *dev)
+{
+ /*
+ * Sort out state of unlinked and deleted objects after scanning.
+ */
+ 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);
+ }
+ }
+
+ ylist_for_each_safe(i, n,
+ &dev->deletedDir->variant.directoryVariant.children) {
+ if (i) {
+ l = ylist_entry(i, yaffs_Object, siblings);
+ yaffs_DestroyObject(l);
+ }
+ }
+
+}
+
static int yaffs_Scan(yaffs_Device * dev)
{
yaffs_ExtendedTags tags;
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;
dev->nFreeChunks++;
- } else if (tags.chunkId > 0) {
+ } else if (tags.eccResult == YAFFS_ECC_RESULT_UNFIXED){
+ printf("Error in ECC\n");
+ /* Don't actually delete because the chunk is not yet set up as being in use */
+ /* yaffs_DeleteChunk(dev, chunk, 1, __LINE__); */
+ }else if (tags.chunkId > 0) {
/* chunkId > 0 so it is a data chunk... */
unsigned int endpos;
__u32 chunkBase =
*/
yaffs_HardlinkFixup(dev,hardList);
-
- /*
- * Sort out state of unlinked and deleted objects.
- */
- {
- 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);
- }
- }
-
- /* Soft delete all the deletedDir files */
- ylist_for_each_safe(i, n,
- &dev->deletedDir->variant.directoryVariant.
- children) {
- if (i) {
- l = ylist_entry(i, yaffs_Object, siblings);
- yaffs_DestroyObject(l);
-
- }
- }
- }
yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
if (lh) {
listObj = ylist_entry(lh, yaffs_Object, siblings);
if(listObj->parent != directory){
- T(YAFFS_TRACE_ALWAYS, (TSTR("Object in directory list has wrong parent" TENDSTR),listObj->parent));
+ T(YAFFS_TRACE_ALWAYS, (TSTR("Object in directory list has wrong parent %p" TENDSTR),listObj->parent));
YBUG();
}
yaffs_VerifyObjectInDirectory(listObj);
}else
if(!yaffs_Scan(dev))
init_failed = 1;
+
+ yaffs_StripDeletedObjects(dev);
}
if(init_failed){