projects
/
yaffs
/
.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
*** empty log message ***
[yaffs/.git]
/
yaffs_guts.c
diff --git
a/yaffs_guts.c
b/yaffs_guts.c
index 5cbd371a938ecafc39814e049f7ca0381eac1e78..4757ff6802ceed1571b8fad2c556522010a454b7 100644
(file)
--- a/
yaffs_guts.c
+++ b/
yaffs_guts.c
@@
-14,7
+14,7
@@
*/
//yaffs_guts.c
*/
//yaffs_guts.c
-const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.
27 2003-08-16 08:17:3
2 charles Exp $";
+const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.
35 2004-09-21 03:03:1
2 charles Exp $";
#include "yportenv.h"
#include "yportenv.h"
@@
-782,11
+782,16
@@
static void yaffs_FreeTnode(yaffs_Device*dev, yaffs_Tnode *tn)
static void yaffs_DeinitialiseTnodes(yaffs_Device*dev)
{
// Free the list of allocated tnodes
static void yaffs_DeinitialiseTnodes(yaffs_Device*dev)
{
// Free the list of allocated tnodes
-
+ yaffs_TnodeList *tmp;
+
while(dev->allocatedTnodeList)
{
while(dev->allocatedTnodeList)
{
+ tmp = dev->allocatedTnodeList->next;
+
YFREE(dev->allocatedTnodeList->tnodes);
YFREE(dev->allocatedTnodeList->tnodes);
- dev->allocatedTnodeList = dev->allocatedTnodeList->next;
+ YFREE(dev->allocatedTnodeList);
+ dev->allocatedTnodeList = tmp;
+
}
dev->freeTnodes = NULL;
}
dev->freeTnodes = NULL;
@@
-1080,7
+1085,7
@@
static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, in
if(limit)
{
*limit = *limit-1;
if(limit)
{
*limit = *limit-1;
- if(limit <= 0)
+ if(
*
limit <= 0)
{
hitLimit = 1;
}
{
hitLimit = 1;
}
@@
-1151,6
+1156,8
@@
static int yaffs_SoftDeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level
{
if(tn->level0[i])
{
{
if(tn->level0[i])
{
+ // Note this does not find the real chunk, only the chunk group.
+ // We make an assumption that a chunk group is niot larger than a block.
theChunk = (tn->level0[i] << in->myDev->chunkGroupBits);
T(YAFFS_TRACE_SCAN,(TSTR("soft delete tch %d cgb %d chunk %d" TENDSTR),
tn->level0[i],in->myDev->chunkGroupBits,theChunk));
theChunk = (tn->level0[i] << in->myDev->chunkGroupBits);
T(YAFFS_TRACE_SCAN,(TSTR("soft delete tch %d cgb %d chunk %d" TENDSTR),
tn->level0[i],in->myDev->chunkGroupBits,theChunk));
@@
-1452,10
+1459,15
@@
static void yaffs_DeinitialiseObjects(yaffs_Device *dev)
{
// Free the list of allocated Objects
{
// Free the list of allocated Objects
+ yaffs_ObjectList *tmp;
+
while( dev->allocatedObjectList)
{
while( dev->allocatedObjectList)
{
+ tmp = dev->allocatedObjectList->next;
YFREE(dev->allocatedObjectList->objects);
YFREE(dev->allocatedObjectList->objects);
- dev->allocatedObjectList = dev->allocatedObjectList->next;
+ YFREE(dev->allocatedObjectList);
+
+ dev->allocatedObjectList = tmp;
}
dev->freeObjects = NULL;
}
dev->freeObjects = NULL;
@@
-1626,7
+1638,8
@@
yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev,int number,yaffs_ObjectTyp
#else
#else
-#if defined(CONFIG_KERNEL_2_5)
+//#if defined(CONFIG_KERNEL_2_5)
+#if defined(__KERNEL__) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
theObject->st_atime = theObject->st_mtime = theObject->st_ctime = CURRENT_TIME.tv_sec;
#else
theObject->st_atime = theObject->st_mtime = theObject->st_ctime = CURRENT_TIME;
theObject->st_atime = theObject->st_mtime = theObject->st_ctime = CURRENT_TIME.tv_sec;
#else
theObject->st_atime = theObject->st_mtime = theObject->st_ctime = CURRENT_TIME;
@@
-1731,10
+1744,11
@@
yaffs_Object *yaffs_MknodObject( yaffs_ObjectType type,
#ifdef CONFIG_YAFFS_WINCE
yfsd_WinFileTimeNow(in->win_atime);
in->win_ctime[0] = in->win_mtime[0] = in->win_atime[0];
#ifdef CONFIG_YAFFS_WINCE
yfsd_WinFileTimeNow(in->win_atime);
in->win_ctime[0] = in->win_mtime[0] = in->win_atime[0];
- in->win_ctime[1] = in->win_mtime[1] = in->win_atime[
0
];
+ in->win_ctime[1] = in->win_mtime[1] = in->win_atime[
1
];
#else
#else
-#if defined(CONFIG_KERNEL_2_5)
+//#if defined(CONFIG_KERNEL_2_5)
+#if defined(__KERNEL__) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
in->st_atime = in->st_mtime = in->st_ctime = CURRENT_TIME.tv_sec;
#else
in->st_atime = in->st_mtime = in->st_ctime = CURRENT_TIME;
in->st_atime = in->st_mtime = in->st_ctime = CURRENT_TIME.tv_sec;
#else
in->st_atime = in->st_mtime = in->st_ctime = CURRENT_TIME;
@@
-2290,6
+2304,7
@@
static int yaffs_GarbageCollectBlock(yaffs_Device *dev,int block)
{
// It's a header
object->chunkId = newChunk;
{
// It's a header
object->chunkId = newChunk;
+ object->serial = tags.serialNumber;
}
else
{
}
else
{
@@
-2831,6
+2846,7
@@
int yaffs_ReadChunkDataFromObject(yaffs_Object *in,int chunkInInode, __u8 *buffe
}
else
{
}
else
{
+ memset(buffer,0,YAFFS_BYTES_PER_CHUNK);
return 0;
}
return 0;
}
@@
-2853,7
+2869,14
@@
static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId,int markNAND)
if(markNAND)
{
yaffs_SpareInitialise(&spare);
if(markNAND)
{
yaffs_SpareInitialise(&spare);
-
+
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+
+ //read data before write, to ensure correct ecc
+ //if we're using MTD verification under Linux
+ yaffs_ReadChunkFromNAND(dev,chunkId,NULL,&spare,0);
+#endif
+
spare.pageStatus = 0; // To mark it as deleted.
spare.pageStatus = 0; // To mark it as deleted.
@@
-3649,8
+3672,10
@@
int yaffs_ResizeFile(yaffs_Object *in, int newSize)
int lastChunk = 1+ newSize/YAFFS_BYTES_PER_CHUNK;
// Got to read and rewrite the last chunk with its new size.
int lastChunk = 1+ newSize/YAFFS_BYTES_PER_CHUNK;
// Got to read and rewrite the last chunk with its new size.
+ // NB Got to zero pad to nuke old data
yaffs_ReadChunkDataFromObject(in,lastChunk,dev->localBuffer);
yaffs_ReadChunkDataFromObject(in,lastChunk,dev->localBuffer);
-
+ memset(dev->localBuffer + sizeOfPartialChunk,0, YAFFS_BYTES_PER_CHUNK - sizeOfPartialChunk);
+
yaffs_WriteChunkDataToObject(in,lastChunk,dev->localBuffer,sizeOfPartialChunk,1);
}
yaffs_WriteChunkDataToObject(in,lastChunk,dev->localBuffer,sizeOfPartialChunk,1);
}
@@
-3702,7
+3727,8
@@
int yaffs_FlushFile(yaffs_Object *in, int updateTime)
#ifdef CONFIG_YAFFS_WINCE
yfsd_WinFileTimeNow(in->win_mtime);
#else
#ifdef CONFIG_YAFFS_WINCE
yfsd_WinFileTimeNow(in->win_mtime);
#else
-#if defined(CONFIG_KERNEL_2_5)
+//#if defined(CONFIG_KERNEL_2_5)
+#if defined(__KERNEL__) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
in->st_mtime = CURRENT_TIME.tv_sec;
#else
in->st_mtime = CURRENT_TIME;
in->st_mtime = CURRENT_TIME.tv_sec;
#else
in->st_mtime = CURRENT_TIME;
@@
-4205,8
+4231,9
@@
static int yaffs_Scan(yaffs_Device *dev)
{
// Hoosterman, another problem....
// We're trying to use a non-directory as a directory
{
// Hoosterman, another problem....
// We're trying to use a non-directory as a directory
- // Todo ... handle
- T(YAFFS_TRACE_ERROR, (TSTR("yaffs tragedy: attempting to use non-directory as a directory in scan" TENDSTR)));
+
+ 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;
}
}
@@
-4559,7
+4586,9
@@
int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr)
if(valid & ATTR_UID) obj->st_uid = attr->ia_uid;
if(valid & ATTR_GID) obj->st_gid = attr->ia_gid;
if(valid & ATTR_UID) obj->st_uid = attr->ia_uid;
if(valid & ATTR_GID) obj->st_gid = attr->ia_gid;
-#if defined(CONFIG_KERNEL_2_5)
+//#if defined(CONFIG_KERNEL_2_5)
+#if defined(__KERNEL__) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+
if(valid & ATTR_ATIME) obj->st_atime = attr->ia_atime.tv_sec;
if(valid & ATTR_CTIME) obj->st_ctime = attr->ia_ctime.tv_sec;
if(valid & ATTR_MTIME) obj->st_mtime = attr->ia_mtime.tv_sec;
if(valid & ATTR_ATIME) obj->st_atime = attr->ia_atime.tv_sec;
if(valid & ATTR_CTIME) obj->st_ctime = attr->ia_ctime.tv_sec;
if(valid & ATTR_MTIME) obj->st_mtime = attr->ia_mtime.tv_sec;
@@
-4584,7
+4613,8
@@
int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr)
attr->ia_uid = obj->st_uid; valid |= ATTR_UID;
attr->ia_gid = obj->st_gid; valid |= ATTR_GID;
attr->ia_uid = obj->st_uid; valid |= ATTR_UID;
attr->ia_gid = obj->st_gid; valid |= ATTR_GID;
-#if defined(CONFIG_KERNEL_2_5)
+//#if defined(CONFIG_KERNEL_2_5)
+#if defined(__KERNEL__) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
attr->ia_atime.tv_sec = obj->st_atime; valid |= ATTR_ATIME;
attr->ia_ctime.tv_sec = obj->st_ctime; valid |= ATTR_CTIME;
attr->ia_mtime.tv_sec = obj->st_mtime; valid |= ATTR_MTIME;
attr->ia_atime.tv_sec = obj->st_atime; valid |= ATTR_ATIME;
attr->ia_ctime.tv_sec = obj->st_ctime; valid |= ATTR_CTIME;
attr->ia_mtime.tv_sec = obj->st_mtime; valid |= ATTR_MTIME;
@@
-4656,8
+4686,7
@@
int yaffs_GutsInitialise(yaffs_Device *dev)
int extraBits;
int nBlocks;
int extraBits;
int nBlocks;
- if( dev->nBytesPerChunk != YAFFS_BYTES_PER_CHUNK ||
-
+ if( dev->nBytesPerChunk != YAFFS_BYTES_PER_CHUNK ||
dev->nChunksPerBlock < 2 ||
dev->nReservedBlocks < 2 ||
dev->startBlock <= 0 ||
dev->nChunksPerBlock < 2 ||
dev->nReservedBlocks < 2 ||
dev->startBlock <= 0 ||
@@
-4724,7
+4753,18
@@
int yaffs_GutsInitialise(yaffs_Device *dev)
{
dev->chunkGroupBits = bits - 16;
}
{
dev->chunkGroupBits = bits - 16;
}
+
dev->chunkGroupSize = 1 << dev->chunkGroupBits;
dev->chunkGroupSize = 1 << dev->chunkGroupBits;
+
+ if(dev->nChunksPerBlock < dev->chunkGroupSize)
+ {
+ // We have a problem because the soft delete won't work if
+ // the chunk group size > chunks per block.
+ // This can be remedied by using larger "virtual blocks".
+
+ return YAFFS_FAIL;
+ }
+
@@
-4810,6
+4850,8
@@
void yaffs_Deinitialise(yaffs_Device *dev)
yaffs_DeinitialiseBlocks(dev);
yaffs_DeinitialiseTnodes(dev);
yaffs_DeinitialiseObjects(dev);
yaffs_DeinitialiseBlocks(dev);
yaffs_DeinitialiseTnodes(dev);
yaffs_DeinitialiseObjects(dev);
+ if(dev->nShortOpCaches > 0)
+ YFREE(dev->srCache);
YFREE(dev->localBuffer);
}
YFREE(dev->localBuffer);
}
@@
-4963,3
+5005,4
@@
void yaffs_GutsTest(yaffs_Device *dev)
+