Lines Matching defs:dev

47 static void yaffs_RetireBlock(yaffs_Device * dev, int blockInNAND);
48 static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND, int erasedOk);
49 static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND,
52 static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND,
59 static void yaffs_HardlinkFixup(yaffs_Device *dev, yaffs_Object *hardList);
61 static int yaffs_WriteNewChunkWithTagsToNAND(yaffs_Device * dev,
68 static yaffs_Object *yaffs_CreateNewObject(yaffs_Device * dev, int number,
80 static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blockNo);
82 static __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo);
83 static void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer,
86 static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
97 static int yaffs_AllocateChunk(yaffs_Device * dev, int useReserve, yaffs_BlockInfo **blockUsedPtr);
99 static void yaffs_VerifyFreeChunks(yaffs_Device * dev);
110 static void yaffs_InvalidateCheckpoint(yaffs_Device *dev);
116 static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, __u32 *chunk, __u32 *offset)
118 if(dev->chunkShift){
120 *chunk = (__u32)(addr >> dev->chunkShift);
121 *offset = (__u32)(addr & dev->chunkMask);
123 else if(dev->crumbsPerChunk)
126 *offset = (__u32)(addr & dev->crumbMask);
127 addr >>= dev->crumbShift;
128 *chunk = ((__u32)addr)/dev->crumbsPerChunk;
129 *offset += ((addr - (*chunk * dev->crumbsPerChunk)) << dev->crumbShift);
185 static __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo)
189 if (dev->tempBuffer[i].line == 0) {
190 dev->tempBuffer[i].line = lineNo;
191 if ((i + 1) > dev->maxTemp) {
192 dev->maxTemp = i + 1;
194 dev->tempBuffer[j].maxLine =
195 dev->tempBuffer[j].line;
198 return dev->tempBuffer[i].buffer;
206 T(YAFFS_TRACE_BUFFERS, (TSTR(" %d "), dev->tempBuffer[i].line));
215 dev->unmanagedTempAllocations++;
216 return YMALLOC(dev->nDataBytesPerChunk);
220 static void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer,
225 if (dev->tempBuffer[i].buffer == buffer) {
226 dev->tempBuffer[i].line = 0;
237 dev->unmanagedTempDeallocations++;
245 int yaffs_IsManagedTempBuffer(yaffs_Device * dev, const __u8 * buffer)
249 if (dev->tempBuffer[i].buffer == buffer)
254 for (i = 0; i < dev->nShortOpCaches; i++) {
255 if( dev->srCache[i].data == buffer )
260 if (buffer == dev->checkpointBuffer)
272 static Y_INLINE __u8 *yaffs_BlockBits(yaffs_Device * dev, int blk)
274 if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
280 return dev->chunkBits +
281 (dev->chunkBitmapStride * (blk - dev->internalStartBlock));
284 static Y_INLINE void yaffs_ClearChunkBits(yaffs_Device * dev, int blk)
286 __u8 *blkBits = yaffs_BlockBits(dev, blk);
288 memset(blkBits, 0, dev->chunkBitmapStride);
291 static Y_INLINE void yaffs_ClearChunkBit(yaffs_Device * dev, int blk, int chunk)
293 __u8 *blkBits = yaffs_BlockBits(dev, blk);
298 static Y_INLINE void yaffs_SetChunkBit(yaffs_Device * dev, int blk, int chunk)
300 __u8 *blkBits = yaffs_BlockBits(dev, blk);
305 static Y_INLINE int yaffs_CheckChunkBit(yaffs_Device * dev, int blk, int chunk)
307 __u8 *blkBits = yaffs_BlockBits(dev, blk);
311 static Y_INLINE int yaffs_StillSomeChunkBits(yaffs_Device * dev, int blk)
313 __u8 *blkBits = yaffs_BlockBits(dev, blk);
315 for (i = 0; i < dev->chunkBitmapStride; i++) {
337 yaffs_Object *yaffs_Root(yaffs_Device * dev)
339 return dev->rootDir;
342 yaffs_Object *yaffs_LostNFound(yaffs_Device * dev)
344 return dev->lostNFoundDir;
363 static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
368 __u8 *data = yaffs_GetTempBuffer(dev, __LINE__);
372 result = yaffs_ReadChunkWithTagsFromNAND(dev, chunkInNAND, data, &tags);
378 if (!yaffs_CheckFF(data, dev->nDataBytesPerChunk) || tags.chunkUsed) {
384 yaffs_ReleaseTempBuffer(dev, data, __LINE__);
390 static int yaffs_WriteNewChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
402 yaffs_InvalidateCheckpoint(dev);
405 chunk = yaffs_AllocateChunk(dev, useReserve,&bi);
428 yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
436 erasedOk = yaffs_CheckChunkErased(dev, chunk);
448 yaffs_WriteChunkWithTagsToNAND(dev, chunk,
460 yaffs_HandleWriteChunkOk(dev, chunk, data, tags);
464 yaffs_HandleWriteChunkError(dev, chunk, erasedOk);
475 dev->nRetriedWrites += (attempts - 1);
485 static void yaffs_RetireBlock(yaffs_Device * dev, int blockInNAND)
488 yaffs_InvalidateCheckpoint(dev);
490 yaffs_MarkBlockBad(dev, blockInNAND);
492 yaffs_GetBlockInfo(dev, blockInNAND)->blockState =
495 dev->nRetiredBlocks++;
503 static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND,
509 static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND,
514 void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi)
518 dev->hasPendingPrioritisedGCs = 1;
530 static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND, int erasedOk)
533 int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
534 yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND);
536 yaffs_HandleChunkError(dev,bi);
546 yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__);
597 static int yaffs_CreateTnodes(yaffs_Device * dev, int nTnodes)
612 tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
634 newTnodes[nTnodes - 1].internal[0] = dev->freeTnodes;
638 dev->freeTnodes = newTnodes;
648 curr->internal[0] = dev->freeTnodes;
649 dev->freeTnodes = (yaffs_Tnode *)mem;
654 dev->nFreeTnodes += nTnodes;
655 dev->nTnodesCreated += nTnodes;
670 tnl->next = dev->allocatedTnodeList;
671 dev->allocatedTnodeList = tnl;
681 static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device * dev)
686 if (!dev->freeTnodes) {
687 yaffs_CreateTnodes(dev, YAFFS_ALLOCATION_NTNODES);
690 if (dev->freeTnodes) {
691 tn = dev->freeTnodes;
699 dev->freeTnodes = dev->freeTnodes->internal[0];
700 dev->nFreeTnodes--;
706 static yaffs_Tnode *yaffs_GetTnode(yaffs_Device * dev)
708 yaffs_Tnode *tn = yaffs_GetTnodeRaw(dev);
711 memset(tn, 0, (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);
717 static void yaffs_FreeTnode(yaffs_Device * dev, yaffs_Tnode * tn)
728 tn->internal[0] = dev->freeTnodes;
729 dev->freeTnodes = tn;
730 dev->nFreeTnodes++;
734 static void yaffs_DeinitialiseTnodes(yaffs_Device * dev)
739 while (dev->allocatedTnodeList) {
740 tmp = dev->allocatedTnodeList->next;
742 YFREE(dev->allocatedTnodeList->tnodes);
743 YFREE(dev->allocatedTnodeList);
744 dev->allocatedTnodeList = tmp;
748 dev->freeTnodes = NULL;
749 dev->nFreeTnodes = 0;
752 static void yaffs_InitialiseTnodes(yaffs_Device * dev)
754 dev->allocatedTnodeList = NULL;
755 dev->freeTnodes = NULL;
756 dev->nFreeTnodes = 0;
757 dev->nTnodesCreated = 0;
762 void yaffs_PutLevel0Tnode(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos, unsigned val)
771 val >>= dev->chunkGroupBits;
773 bitInMap = pos * dev->tnodeWidth;
777 mask = dev->tnodeMask << bitInWord;
782 if(dev->tnodeWidth > (32-bitInWord)) {
785 mask = dev->tnodeMask >> (/*dev->tnodeWidth -*/ bitInWord);
791 __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos)
801 bitInMap = pos * dev->tnodeWidth;
807 if(dev->tnodeWidth > (32-bitInWord)) {
813 val &= dev->tnodeMask;
814 val <<= dev->chunkGroupBits;
827 static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device * dev,
887 static yaffs_Tnode *yaffs_AddOrFindLevel0Tnode(yaffs_Device * dev,
924 tn = yaffs_GetTnode(dev);
953 tn->internal[x] = yaffs_GetTnode(dev);
960 yaffs_FreeTnode(dev,tn->internal[x]);
965 tn->internal[x] = yaffs_GetTnode(dev);
975 memcpy(tn,passedTn,(dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);
976 yaffs_FreeTnode(dev,passedTn);
983 static int yaffs_FindChunkInGroup(yaffs_Device * dev, int theChunk,
989 for (j = 0; theChunk && j < dev->chunkGroupSize; j++) {
991 (dev, theChunk / dev->nChunksPerBlock,
992 theChunk % dev->nChunksPerBlock)) {
993 yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL,
1021 yaffs_Device *dev = in->myDev;
1048 yaffs_FreeTnode(dev,
1062 theChunk = yaffs_GetChunkGroupBase(dev,tn,i);
1070 yaffs_FindChunkInGroup(dev,
1077 yaffs_DeleteChunk(dev,
1090 yaffs_PutLevel0Tnode(dev,tn,i,0);
1104 static void yaffs_SoftDeleteChunk(yaffs_Device * dev, int chunk)
1111 theBlock = yaffs_GetBlockInfo(dev, chunk / dev->nChunksPerBlock);
1114 dev->nFreeChunks++;
1130 yaffs_Device *dev = in->myDev;
1148 yaffs_FreeTnode(dev,
1161 theChunk = yaffs_GetChunkGroupBase(dev,tn,i);
1167 yaffs_SoftDeleteChunk(dev, theChunk);
1168 yaffs_PutLevel0Tnode(dev,tn,i,0);
1216 static yaffs_Tnode *yaffs_PruneWorker(yaffs_Device * dev, yaffs_Tnode * tn,
1228 yaffs_PruneWorker(dev, tn->internal[i],
1241 yaffs_FreeTnode(dev, tn);
1251 static int yaffs_PruneFileStructure(yaffs_Device * dev,
1261 yaffs_PruneWorker(dev, fStruct->top, fStruct->topLevel, 0);
1283 yaffs_FreeTnode(dev, tn);
1298 static int yaffs_CreateFreeObjects(yaffs_Device * dev, int nObjects)
1322 newObjects[nObjects - 1].siblings.next = (void *)dev->freeObjects;
1323 dev->freeObjects = newObjects;
1324 dev->nFreeObjects += nObjects;
1325 dev->nObjectsCreated += nObjects;
1335 list->next = dev->allocatedObjectList;
1336 dev->allocatedObjectList = list;
1344 static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device * dev)
1349 if (!dev->freeObjects) {
1350 yaffs_CreateFreeObjects(dev, YAFFS_ALLOCATION_NOBJECTS);
1353 if (dev->freeObjects) {
1354 tn = dev->freeObjects;
1355 dev->freeObjects =
1356 (yaffs_Object *) (dev->freeObjects->siblings.next);
1357 dev->nFreeObjects--;
1362 tn->myDev = dev;
1373 if (dev->lostNFoundDir) {
1374 yaffs_AddObjectToDirectory(dev->lostNFoundDir, tn);
1381 static yaffs_Object *yaffs_CreateFakeDirectory(yaffs_Device * dev, int number,
1386 yaffs_CreateNewObject(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY);
1394 obj->myDev = dev;
1405 yaffs_Device *dev = tn->myDev;
1411 dev->objectBucket[bucket].count--;
1420 yaffs_Device *dev = tn->myDev;
1435 tn->siblings.next = (struct list_head *)(dev->freeObjects);
1436 dev->freeObjects = tn;
1437 dev->nFreeObjects++;
1451 static void yaffs_DeinitialiseObjects(yaffs_Device * dev)
1457 while (dev->allocatedObjectList) {
1458 tmp = dev->allocatedObjectList->next;
1459 YFREE(dev->allocatedObjectList->objects);
1460 YFREE(dev->allocatedObjectList);
1462 dev->allocatedObjectList = tmp;
1465 dev->freeObjects = NULL;
1466 dev->nFreeObjects = 0;
1469 static void yaffs_InitialiseObjects(yaffs_Device * dev)
1473 dev->allocatedObjectList = NULL;
1474 dev->freeObjects = NULL;
1475 dev->nFreeObjects = 0;
1478 INIT_LIST_HEAD(&dev->objectBucket[i].list);
1479 dev->objectBucket[i].count = 0;
1484 static int yaffs_FindNiceObjectBucket(yaffs_Device * dev)
1496 if (dev->objectBucket[x].count < lowest) {
1497 lowest = dev->objectBucket[x].count;
1510 if (dev->objectBucket[x].count < lowest) {
1511 lowest = dev->objectBucket[x].count;
1520 static int yaffs_CreateNewObjectNumber(yaffs_Device * dev)
1522 int bucket = yaffs_FindNiceObjectBucket(dev);
1538 if (1 || dev->objectBucket[bucket].count > 0) {
1539 list_for_each(i, &dev->objectBucket[bucket].list) {
1557 yaffs_Device *dev = in->myDev;
1559 list_add(&in->hashLink, &dev->objectBucket[bucket].list);
1560 dev->objectBucket[bucket].count++;
1564 yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number)
1570 list_for_each(i, &dev->objectBucket[bucket].list) {
1589 yaffs_Object *yaffs_CreateNewObject(yaffs_Device * dev, int number,
1596 number = yaffs_CreateNewObjectNumber(dev);
1599 theObject = yaffs_AllocateEmptyObject(dev);
1627 yaffs_GetTnode(dev);
1647 static yaffs_Object *yaffs_FindOrCreateObjectByNumber(yaffs_Device * dev,
1654 theObject = yaffs_FindObjectByNumber(dev, number);
1658 theObject = yaffs_CreateNewObject(dev, number, type);
1697 yaffs_Device *dev = parent->myDev;
1704 in = yaffs_CreateNewObject(dev, -1, type);
1924 static int yaffs_InitialiseBlocks(yaffs_Device * dev)
1926 int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1;
1928 dev->allocationBlock = -1; /* force it to get a new one */
1931 dev->blockInfo = YMALLOC(nBlocks * sizeof(yaffs_BlockInfo));
1932 if(!dev->blockInfo){
1933 dev->blockInfo = YMALLOC_ALT(nBlocks * sizeof(yaffs_BlockInfo));
1934 dev->blockInfoAlt = 1;
1937 dev->blockInfoAlt = 0;
1940 dev->chunkBitmapStride = (dev->nChunksPerBlock + 7) / 8; // round up bytes
1941 dev->chunkBits = YMALLOC(dev->chunkBitmapStride * nBlocks);
1942 if(!dev->chunkBits){
1943 dev->chunkBits = YMALLOC_ALT(dev->chunkBitmapStride * nBlocks);
1944 dev->chunkBitsAlt = 1;
1947 dev->chunkBitsAlt = 0;
1949 if (dev->blockInfo && dev->chunkBits) {
1950 memset(dev->blockInfo, 0, nBlocks * sizeof(yaffs_BlockInfo));
1951 memset(dev->chunkBits, 0, dev->chunkBitmapStride * nBlocks);
1959 static void yaffs_DeinitialiseBlocks(yaffs_Device * dev)
1961 if(dev->blockInfoAlt)
1962 YFREE_ALT(dev->blockInfo);
1964 YFREE(dev->blockInfo);
1965 dev->blockInfoAlt = 0;
1967 dev->blockInfo = NULL;
1969 if(dev->chunkBitsAlt)
1970 YFREE_ALT(dev->chunkBits);
1972 YFREE(dev->chunkBits);
1973 dev->chunkBitsAlt = 0;
1974 dev->chunkBits = NULL;
1977 static int yaffs_BlockNotDisqualifiedFromGC(yaffs_Device * dev,
1984 if (!dev->isYaffs2)
1993 if (!dev->oldestDirtySequence) {
1994 seq = dev->sequenceNumber;
1996 for (i = dev->internalStartBlock; i <= dev->internalEndBlock;
1998 b = yaffs_GetBlockInfo(dev, i);
2001 dev->nChunksPerBlock && b->sequenceNumber < seq) {
2005 dev->oldestDirtySequence = seq;
2011 return (bi->sequenceNumber <= dev->oldestDirtySequence);
2021 static int yaffs_FindBlockForGarbageCollection(yaffs_Device * dev,
2025 int b = dev->currentDirtyChecker;
2037 if(dev->hasPendingPrioritisedGCs){
2038 for(i = dev->internalStartBlock; i < dev->internalEndBlock && !prioritised; i++){
2040 bi = yaffs_GetBlockInfo(dev, i);
2045 yaffs_BlockNotDisqualifiedFromGC(dev, bi)){
2054 dev->hasPendingPrioritisedGCs = 0;
2071 (aggressive) ? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1;
2075 dev->internalEndBlock - dev->internalStartBlock + 1;
2078 dev->internalEndBlock - dev->internalStartBlock + 1;
2087 if (b < dev->internalStartBlock || b > dev->internalEndBlock) {
2088 b = dev->internalStartBlock;
2091 if (b < dev->internalStartBlock || b > dev->internalEndBlock) {
2097 bi = yaffs_GetBlockInfo(dev, b);
2109 yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
2115 dev->currentDirtyChecker = b;
2120 dev->nChunksPerBlock - pagesInUse,prioritised));
2123 dev->oldestDirtySequence = 0;
2132 static void yaffs_BlockBecameDirty(yaffs_Device * dev, int blockNo)
2134 yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockNo);
2144 yaffs_InvalidateCheckpoint(dev);
2145 erasedOk = yaffs_EraseBlockInNAND(dev, blockNo);
2147 dev->nErasureFailures++;
2155 for (i = 0; i < dev->nChunksPerBlock; i++) {
2157 (dev, blockNo * dev->nChunksPerBlock + i)) {
2169 dev->nErasedBlocks++;
2175 yaffs_ClearChunkBits(dev, blockNo);
2180 dev->nFreeChunks -= dev->nChunksPerBlock; /* We lost a block of free space */
2182 yaffs_RetireBlock(dev, blockNo);
2188 static int yaffs_FindBlockForAllocation(yaffs_Device * dev)
2194 if (dev->nErasedBlocks < 1) {
2206 for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
2207 dev->allocationBlockFinder++;
2208 if (dev->allocationBlockFinder < dev->internalStartBlock
2209 || dev->allocationBlockFinder > dev->internalEndBlock) {
2210 dev->allocationBlockFinder = dev->internalStartBlock;
2213 bi = yaffs_GetBlockInfo(dev, dev->allocationBlockFinder);
2217 dev->sequenceNumber++;
2218 bi->sequenceNumber = dev->sequenceNumber;
2219 dev->nErasedBlocks--;
2222 dev->allocationBlockFinder, dev->sequenceNumber,
2223 dev->nErasedBlocks));
2224 return dev->allocationBlockFinder;
2231 TENDSTR), dev->nErasedBlocks));
2239 static int yaffs_CheckSpaceForAllocation(yaffs_Device * dev)
2242 int reservedBlocks = dev->nReservedBlocks;
2245 checkpointBlocks = dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint;
2249 reservedChunks = ((reservedBlocks + checkpointBlocks) * dev->nChunksPerBlock);
2251 return (dev->nFreeChunks > reservedChunks);
2254 static int yaffs_AllocateChunk(yaffs_Device * dev, int useReserve, yaffs_BlockInfo **blockUsedPtr)
2259 if (dev->allocationBlock < 0) {
2261 dev->allocationBlock = yaffs_FindBlockForAllocation(dev);
2262 dev->allocationPage = 0;
2265 if (!useReserve && !yaffs_CheckSpaceForAllocation(dev)) {
2270 if (dev->nErasedBlocks < dev->nReservedBlocks
2271 && dev->allocationPage == 0) {
2276 if (dev->allocationBlock >= 0) {
2277 bi = yaffs_GetBlockInfo(dev, dev->allocationBlock);
2279 retVal = (dev->allocationBlock * dev->nChunksPerBlock) +
2280 dev->allocationPage;
2282 yaffs_SetChunkBit(dev, dev->allocationBlock,
2283 dev->allocationPage);
2285 dev->allocationPage++;
2287 dev->nFreeChunks--;
2290 if (dev->allocationPage >= dev->nChunksPerBlock) {
2292 dev->allocationBlock = -1;
2307 static int yaffs_GetErasedChunks(yaffs_Device * dev)
2311 n = dev->nErasedBlocks * dev->nChunksPerBlock;
2313 if (dev->allocationBlock > 0) {
2314 n += (dev->nChunksPerBlock - dev->allocationPage);
2321 static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block)
2332 int chunksBefore = yaffs_GetErasedChunks(dev);
2337 yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, block);
2349 /*yaffs_VerifyFreeChunks(dev); */
2356 dev->nFreeChunks -= bi->softDeletions;
2358 dev->isDoingGC = 1;
2361 !yaffs_StillSomeChunkBits(dev, block)) {
2366 yaffs_BlockBecameDirty(dev, block);
2369 __u8 *buffer = yaffs_GetTempBuffer(dev, __LINE__);
2371 for (chunkInBlock = 0, oldChunk = block * dev->nChunksPerBlock;
2372 chunkInBlock < dev->nChunksPerBlock
2373 && yaffs_StillSomeChunkBits(dev, block);
2375 if (yaffs_CheckChunkBit(dev, block, chunkInBlock)) {
2383 yaffs_ReadChunkWithTagsFromNAND(dev, oldChunk,
2387 yaffs_FindObjectByNumber(dev,
2415 dev->gcCleanupList[cleanups] =
2441 dev->nGCCopies++;
2460 yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &tags, 1);
2482 yaffs_DeleteChunk(dev, oldChunk, markNAND, __LINE__);
2487 yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
2494 yaffs_FindObjectByNumber(dev,
2495 dev->gcCleanupList[i]);
2497 yaffs_FreeTnode(dev,
2513 if (chunksBefore >= (chunksAfter = yaffs_GetErasedChunks(dev))) {
2520 dev->isDoingGC = 0;
2534 static int yaffs_CheckGarbageCollection(yaffs_Device * dev)
2543 if (dev->isDoingGC) {
2555 checkpointBlockAdjust = (dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint);
2559 if (dev->nErasedBlocks < (dev->nReservedBlocks + checkpointBlockAdjust)) {
2567 block = yaffs_FindBlockForGarbageCollection(dev, aggressive);
2570 dev->garbageCollections++;
2572 dev->passiveGarbageCollections++;
2578 dev->nErasedBlocks, aggressive));
2580 gcOk = yaffs_GarbageCollectBlock(dev, block);
2583 if (dev->nErasedBlocks < (dev->nReservedBlocks) && block > 0) {
2587 TENDSTR), dev->nErasedBlocks, maxTries, block));
2589 } while ((dev->nErasedBlocks < dev->nReservedBlocks) && (block > 0)
2617 yaffs_Device *dev = in->myDev;
2624 tn = yaffs_FindLevel0Tnode(dev, &in->variant.fileVariant, chunkInInode);
2627 theChunk = yaffs_GetChunkGroupBase(dev,tn,chunkInInode);
2630 yaffs_FindChunkInGroup(dev, theChunk, tags, in->objectId,
2644 yaffs_Device *dev = in->myDev;
2652 tn = yaffs_FindLevel0Tnode(dev, &in->variant.fileVariant, chunkInInode);
2656 theChunk = yaffs_GetChunkGroupBase(dev,tn,chunkInInode);
2659 yaffs_FindChunkInGroup(dev, theChunk, tags, in->objectId,
2664 yaffs_PutLevel0Tnode(dev,tn,chunkInInode,0);
2707 theChunk = yaffs_GetChunkGroupBase(dev,tn,chunk);
2710 (dev, theChunk / dev->nChunksPerBlock,
2711 theChunk % dev->nChunksPerBlock)) {
2745 yaffs_Device *dev = in->myDev;
2763 yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__);
2767 tn = yaffs_AddOrFindLevel0Tnode(dev,
2775 existingChunk = yaffs_GetChunkGroupBase(dev,tn,chunkInInode);
2800 yaffs_ReadChunkWithTagsFromNAND(dev,
2835 yaffs_DeleteChunk(dev, existingChunk, 1,
2842 yaffs_DeleteChunk(dev, chunkInNAND, 1,
2854 yaffs_PutLevel0Tnode(dev,tn,chunkInInode,chunkInNAND);
2878 void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn)
2888 dev->nDeletions++;
2889 block = chunkId / dev->nChunksPerBlock;
2890 page = chunkId % dev->nChunksPerBlock;
2892 bi = yaffs_GetBlockInfo(dev, block);
2898 bi->blockState != YAFFS_BLOCK_STATE_COLLECTING && !dev->isYaffs2) {
2904 yaffs_WriteChunkWithTagsToNAND(dev, chunkId, NULL, &tags);
2905 yaffs_HandleUpdateChunk(dev, chunkId, &tags);
2907 dev->nUnmarkedDeletions++;
2917 dev->nFreeChunks++;
2919 yaffs_ClearChunkBit(dev, block, page);
2927 yaffs_BlockBecameDirty(dev, block);
2951 yaffs_Device *dev = in->myDev;
2953 yaffs_CheckGarbageCollection(dev);
2968 yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &newTags,
2975 yaffs_DeleteChunk(dev, prevChunkId, 1, __LINE__);
2994 yaffs_Device *dev = in->myDev;
3010 yaffs_CheckGarbageCollection(dev);
3018 result = yaffs_ReadChunkWithTagsFromNAND(dev, prevChunkId,
3023 memset(buffer, 0xFF, dev->nDataBytesPerChunk);
3109 yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &newTags,
3117 yaffs_DeleteChunk(dev, prevChunkId, 1,
3138 yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
3158 yaffs_Device *dev = obj->myDev;
3164 cache = &dev->srCache[i];
3176 yaffs_Device *dev = obj->myDev;
3189 if (dev->srCache[i].object == obj &&
3190 dev->srCache[i].dirty) {
3192 || dev->srCache[i].chunkId <
3194 cache = &dev->srCache[i];
3225 /*yaffs_FlushEntireDeviceCache(dev)
3230 void yaffs_FlushEntireDeviceCache(yaffs_Device *dev)
3233 int nCaches = dev->nShortOpCaches;
3242 if (dev->srCache[i].object &&
3243 dev->srCache[i].dirty)
3244 obj = dev->srCache[i].object;
3260 static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device * dev)
3266 if (dev->nShortOpCaches > 0) {
3267 for (i = 0; i < dev->nShortOpCaches; i++) {
3268 if (!dev->srCache[i].object)
3269 return &dev->srCache[i];
3277 for (i = 0; i < dev->nShortOpCaches; i++) {
3278 if (!dev->srCache[i].dirty &&
3279 ((dev->srCache[i].lastUse < usage && theOne >= 0) ||
3281 usage = dev->srCache[i].lastUse;
3287 return theOne >= 0 ? &dev->srCache[theOne] : NULL;
3294 static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device * dev)
3302 if (dev->nShortOpCaches > 0) {
3305 cache = yaffs_GrabChunkCacheWorker(dev);
3321 for (i = 0; i < dev->nShortOpCaches; i++) {
3322 if (dev->srCache[i].object &&
3323 !dev->srCache[i].locked &&
3324 (dev->srCache[i].lastUse < usage || !cache))
3326 usage = dev->srCache[i].lastUse;
3327 theObj = dev->srCache[i].object;
3328 cache = &dev->srCache[i];
3336 cache = yaffs_GrabChunkCacheWorker(dev);
3350 yaffs_Device *dev = obj->myDev;
3352 if (dev->nShortOpCaches > 0) {
3353 for (i = 0; i < dev->nShortOpCaches; i++) {
3354 if (dev->srCache[i].object == obj &&
3355 dev->srCache[i].chunkId == chunkId) {
3356 dev->cacheHits++;
3358 return &dev->srCache[i];
3366 static void yaffs_UseChunkCache(yaffs_Device * dev, yaffs_ChunkCache * cache,
3370 if (dev->nShortOpCaches > 0) {
3371 if (dev->srLastUse < 0 || dev->srLastUse > 100000000) {
3374 for (i = 1; i < dev->nShortOpCaches; i++) {
3375 dev->srCache[i].lastUse = 0;
3377 dev->srLastUse = 0;
3380 dev->srLastUse++;
3382 cache->lastUse = dev->srLastUse;
3411 yaffs_Device *dev = in->myDev;
3413 if (dev->nShortOpCaches > 0) {
3415 for (i = 0; i < dev->nShortOpCaches; i++) {
3416 if (dev->srCache[i].object == in) {
3417 dev->srCache[i].object = NULL;
3426 static int yaffs_WriteCheckpointValidityMarker(yaffs_Device *dev,int head)
3434 return (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp))?
3438 static int yaffs_ReadCheckpointValidityMarker(yaffs_Device *dev, int head)
3443 ok = (yaffs_CheckpointRead(dev,&cp,sizeof(cp)) == sizeof(cp));
3454 yaffs_Device *dev)
3456 cp->nErasedBlocks = dev->nErasedBlocks;
3457 cp->allocationBlock = dev->allocationBlock;
3458 cp->allocationPage = dev->allocationPage;
3459 cp->nFreeChunks = dev->nFreeChunks;
3461 cp->nDeletedFiles = dev->nDeletedFiles;
3462 cp->nUnlinkedFiles = dev->nUnlinkedFiles;
3463 cp->nBackgroundDeletions = dev->nBackgroundDeletions;
3464 cp->sequenceNumber = dev->sequenceNumber;
3465 cp->oldestDirtySequence = dev->oldestDirtySequence;
3469 static void yaffs_CheckpointDeviceToDevice(yaffs_Device *dev,
3472 dev->nErasedBlocks = cp->nErasedBlocks;
3473 dev->allocationBlock = cp->allocationBlock;
3474 dev->allocationPage = cp->allocationPage;
3475 dev->nFreeChunks = cp->nFreeChunks;
3477 dev->nDeletedFiles = cp->nDeletedFiles;
3478 dev->nUnlinkedFiles = cp->nUnlinkedFiles;
3479 dev->nBackgroundDeletions = cp->nBackgroundDeletions;
3480 dev->sequenceNumber = cp->sequenceNumber;
3481 dev->oldestDirtySequence = cp->oldestDirtySequence;
3485 static int yaffs_WriteCheckpointDevice(yaffs_Device *dev)
3489 __u32 nBlocks = (dev->internalEndBlock - dev->internalStartBlock + 1);
3494 yaffs_DeviceToCheckpointDevice(&cp,dev);
3497 ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp));
3502 ok = (yaffs_CheckpointWrite(dev,dev->blockInfo,nBytes) == nBytes);
3507 nBytes = nBlocks * dev->chunkBitmapStride;
3508 ok = (yaffs_CheckpointWrite(dev,dev->chunkBits,nBytes) == nBytes);
3514 static int yaffs_ReadCheckpointDevice(yaffs_Device *dev)
3518 __u32 nBlocks = (dev->internalEndBlock - dev->internalStartBlock + 1);
3522 ok = (yaffs_CheckpointRead(dev,&cp,sizeof(cp)) == sizeof(cp));
3530 yaffs_CheckpointDeviceToDevice(dev,&cp);
3534 ok = (yaffs_CheckpointRead(dev,dev->blockInfo,nBytes) == nBytes);
3538 nBytes = nBlocks * dev->chunkBitmapStride;
3540 ok = (yaffs_CheckpointRead(dev,dev->chunkBits,nBytes) == nBytes);
3612 yaffs_Device *dev = in->myDev;
3614 int nTnodeBytes = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
3630 ok = (yaffs_CheckpointWrite(dev,&baseOffset,sizeof(baseOffset)) == sizeof(baseOffset));
3632 ok = (yaffs_CheckpointWrite(dev,tn,nTnodeBytes) == nTnodeBytes);
3662 yaffs_Device *dev = obj->myDev;
3666 ok = (yaffs_CheckpointRead(dev,&baseChunk,sizeof(baseChunk)) == sizeof(baseChunk));
3672 tn = yaffs_GetTnodeRaw(dev);
3674 ok = (yaffs_CheckpointRead(dev,tn,(dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8) ==
3675 (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);
3680 ok = yaffs_AddOrFindLevel0Tnode(dev,
3687 ok = (yaffs_CheckpointRead(dev,&baseChunk,sizeof(baseChunk)) == sizeof(baseChunk));
3695 static int yaffs_WriteCheckpointObjects(yaffs_Device *dev)
3709 list_for_each(lh, &dev->objectBucket[i].list) {
3716 ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp));
3731 ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp));
3736 static int yaffs_ReadCheckpointObjects(yaffs_Device *dev)
3745 ok = (yaffs_CheckpointRead(dev,&cp,sizeof(cp)) == sizeof(cp));
3756 obj = yaffs_FindOrCreateObjectByNumber(dev,cp.objectId, cp.variantType);
3773 yaffs_HardlinkFixup(dev,hardList);
3778 static int yaffs_WriteCheckpointData(yaffs_Device *dev)
3783 ok = yaffs_CheckpointOpen(dev,1);
3786 ok = yaffs_WriteCheckpointValidityMarker(dev,1);
3788 ok = yaffs_WriteCheckpointDevice(dev);
3790 ok = yaffs_WriteCheckpointObjects(dev);
3792 ok = yaffs_WriteCheckpointValidityMarker(dev,0);
3794 if(!yaffs_CheckpointClose(dev))
3798 dev->isCheckpointed = 1;
3800 dev->isCheckpointed = 0;
3802 return dev->isCheckpointed;
3805 static int yaffs_ReadCheckpointData(yaffs_Device *dev)
3809 ok = yaffs_CheckpointOpen(dev,0); /* open for read */
3812 ok = yaffs_ReadCheckpointValidityMarker(dev,1);
3814 ok = yaffs_ReadCheckpointDevice(dev);
3816 ok = yaffs_ReadCheckpointObjects(dev);
3818 ok = yaffs_ReadCheckpointValidityMarker(dev,0);
3822 if(!yaffs_CheckpointClose(dev))
3826 dev->isCheckpointed = 1;
3828 dev->isCheckpointed = 0;
3834 static void yaffs_InvalidateCheckpoint(yaffs_Device *dev)
3836 if(dev->isCheckpointed ||
3837 dev->blocksInCheckpoint > 0){
3838 dev->isCheckpointed = 0;
3839 yaffs_CheckpointInvalidateStream(dev);
3840 if(dev->superBlock && dev->markSuperBlockDirty)
3841 dev->markSuperBlockDirty(dev->superBlock);
3846 int yaffs_CheckpointSave(yaffs_Device *dev)
3848 T(YAFFS_TRACE_CHECKPOINT,(TSTR("save entry: isCheckpointed %d"TENDSTR),dev->isCheckpointed));
3850 if(!dev->isCheckpointed)
3851 yaffs_WriteCheckpointData(dev);
3853 T(YAFFS_TRACE_CHECKPOINT,(TSTR("save exit: isCheckpointed %d"TENDSTR),dev->isCheckpointed));
3855 return dev->isCheckpointed;
3858 int yaffs_CheckpointRestore(yaffs_Device *dev)
3861 T(YAFFS_TRACE_CHECKPOINT,(TSTR("restore entry: isCheckpointed %d"TENDSTR),dev->isCheckpointed));
3863 retval = yaffs_ReadCheckpointData(dev);
3865 T(YAFFS_TRACE_CHECKPOINT,(TSTR("restore exit: isCheckpointed %d"TENDSTR),dev->isCheckpointed));
3891 yaffs_Device *dev;
3893 dev = in->myDev;
3896 //chunk = offset / dev->nDataBytesPerChunk + 1;
3897 //start = offset % dev->nDataBytesPerChunk;
3898 yaffs_AddrToChunk(dev,offset,&chunk,&start);
3904 if ((start + n) < dev->nDataBytesPerChunk) {
3907 nToCopy = dev->nDataBytesPerChunk - start;
3916 if (cache || nToCopy != dev->nDataBytesPerChunk) {
3917 if (dev->nShortOpCaches > 0) {
3933 yaffs_UseChunkCache(dev, cache, 0);
3950 yaffs_GetTempBuffer(dev, __LINE__);
3961 yaffs_ReleaseTempBuffer(dev, localBuffer,
3967 __u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__);
3977 memcpy(buffer, localBuffer, dev->nDataBytesPerChunk);
3981 yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__);
4014 yaffs_Device *dev;
4016 dev = in->myDev;
4019 //chunk = offset / dev->nDataBytesPerChunk + 1;
4020 //start = offset % dev->nDataBytesPerChunk;
4021 yaffs_AddrToChunk(dev,offset,&chunk,&start);
4028 if ((start + n) < dev->nDataBytesPerChunk) {
4038 ((chunk - 1) * dev->nDataBytesPerChunk);
4040 if (nBytesRead > dev->nDataBytesPerChunk) {
4041 nBytesRead = dev->nDataBytesPerChunk;
4049 nToCopy = dev->nDataBytesPerChunk - start;
4050 nToWriteBack = dev->nDataBytesPerChunk;
4053 if (nToCopy != dev->nDataBytesPerChunk) {
4055 if (dev->nShortOpCaches > 0) {
4082 yaffs_UseChunkCache(dev, cache, 1);
4116 yaffs_GetTempBuffer(dev, __LINE__);
4136 yaffs_ReleaseTempBuffer(dev, localBuffer,
4147 __u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__);
4151 memcpy(localBuffer, buffer, dev->nDataBytesPerChunk);
4157 dev->nDataBytesPerChunk,
4159 yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__);
4164 dev->nDataBytesPerChunk,
4197 yaffs_Device *dev = in->myDev;
4200 int lastDel = 1 + (oldFileSize - 1) / dev->nDataBytesPerChunk;
4202 int startDel = 1 + (newSize + dev->nDataBytesPerChunk - 1) /
4203 dev->nDataBytesPerChunk;
4219 (dev->internalStartBlock * dev->nChunksPerBlock)
4221 ((dev->internalEndBlock +
4222 1) * dev->nChunksPerBlock)) {
4228 yaffs_DeleteChunk(dev, chunkId, 1, __LINE__);
4242 yaffs_Device *dev = in->myDev;
4244 yaffs_AddrToChunk(dev, newSize, &newFullChunks, &newSizeOfPartialChunk);
4249 yaffs_CheckGarbageCollection(dev);
4266 __u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__);
4273 dev->nDataBytesPerChunk - newSizeOfPartialChunk);
4278 yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__);
4283 yaffs_PruneFileStructure(dev, &in->variant.fileVariant);
4562 static void yaffs_HandleShadowedObject(yaffs_Device * dev, int objId,
4576 if (yaffs_FindObjectByNumber(dev, objId)) {
4585 yaffs_FindOrCreateObjectByNumber(dev, objId,
4587 yaffs_AddObjectToDirectory(dev->unlinkedDir, obj);
4599 static void yaffs_HardlinkFixup(yaffs_Device *dev, yaffs_Object *hardList)
4608 in = yaffs_FindObjectByNumber(dev,
4645 static int yaffs_Scan(yaffs_Device * dev)
4666 int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1;
4672 if (dev->isYaffs2) {
4682 dev->internalStartBlock, dev->internalEndBlock));
4684 chunkData = yaffs_GetTempBuffer(dev, __LINE__);
4686 dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;
4688 if (dev->isYaffs2) {
4693 for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) {
4694 bi = yaffs_GetBlockInfo(dev, blk);
4695 yaffs_ClearChunkBits(dev, blk);
4699 yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber);
4714 dev->nErasedBlocks++;
4715 dev->nFreeChunks += dev->nChunksPerBlock;
4719 if (dev->isYaffs2 &&
4728 if (sequenceNumber >= dev->sequenceNumber) {
4729 dev->sequenceNumber = sequenceNumber;
4731 } else if (dev->isYaffs2) {
4745 if (dev->isYaffs2) {
4760 if (dev->isYaffs2) {
4766 startIterator = dev->internalStartBlock;
4767 endIterator = dev->internalEndBlock;
4774 if (dev->isYaffs2) {
4781 bi = yaffs_GetBlockInfo(dev, blk);
4787 for (c = 0; c < dev->nChunksPerBlock &&
4790 chunk = blk * dev->nChunksPerBlock + c;
4792 result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL,
4797 if (!dev->isYaffs2 && tags.chunkDeleted) {
4802 dev->nFreeChunks++;
4813 dev->nErasedBlocks++;
4821 dev->allocationBlock = blk;
4822 dev->allocationPage = c;
4823 dev->allocationBlockFinder = blk;
4829 if (dev->isYaffs2
4830 && (dev->sequenceNumber !=
4835 " block seq = %d, dev seq = %d"
4836 TENDSTR), blk,bi->sequenceNumber,dev->sequenceNumber));
4840 dev->nFreeChunks += (dev->nChunksPerBlock - c);
4845 yaffs_SetChunkBit(dev, blk, c);
4848 in = yaffs_FindOrCreateObjectByNumber(dev,
4858 (tags.chunkId - 1) * dev->nDataBytesPerChunk +
4865 if (!dev->useHeaderFileSize) {
4878 yaffs_SetChunkBit(dev, blk, c);
4881 result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk,
4887 in = yaffs_FindObjectByNumber(dev,
4900 in = yaffs_FindOrCreateObjectByNumber(dev,
4906 yaffs_HandleShadowedObject(dev,
4918 if (dev->isYaffs2 ||
4922 yaffs_DeleteChunk(dev,
4928 yaffs_DeleteChunk(dev, chunk, 1,
4991 (dev, oh->parentObjectId,
5013 parent = dev->lostNFoundDir;
5018 if (0 && (parent == dev->deletedDir ||
5019 parent == dev->unlinkedDir)) {
5021 dev->nDeletedFiles++;
5035 if (dev->isYaffs2
5044 if (dev->useHeaderFileSize)
5073 if (parent == dev->deletedDir) {
5092 yaffs_BlockBecameDirty(dev, blk);
5108 yaffs_HardlinkFixup(dev,hardList);
5120 &dev->unlinkedDir->variant.directoryVariant.
5129 yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
5140 yaffs_Device *dev = in->myDev;
5146 chunkData = yaffs_GetTempBuffer(dev, __LINE__);
5148 result = yaffs_ReadChunkWithTagsFromNAND(dev,in->chunkId,chunkData,&tags);
5174 yaffs_ReleaseTempBuffer(dev,chunkData, __LINE__);
5178 static int yaffs_ScanBackwards(yaffs_Device * dev)
5198 int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1;
5211 if (!dev->isYaffs2) {
5220 TENDSTR), dev->internalStartBlock, dev->internalEndBlock));
5223 dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;
5238 chunkData = yaffs_GetTempBuffer(dev, __LINE__);
5241 for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) {
5242 bi = yaffs_GetBlockInfo(dev, blk);
5243 yaffs_ClearChunkBits(dev, blk);
5247 yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber);
5269 dev->nErasedBlocks++;
5270 dev->nFreeChunks += dev->nChunksPerBlock;
5274 if (dev->isYaffs2 &&
5283 if (sequenceNumber >= dev->sequenceNumber) {
5284 dev->sequenceNumber = sequenceNumber;
5286 } else if (dev->isYaffs2) {
5348 bi = yaffs_GetBlockInfo(dev, blk);
5355 for (c = dev->nChunksPerBlock - 1; c >= 0 &&
5361 chunk = blk * dev->nChunksPerBlock + c;
5363 result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL,
5385 dev->nErasedBlocks++;
5396 dev->allocationBlock = blk;
5397 dev->allocationPage = c;
5398 dev->allocationBlockFinder = blk;
5406 if (dev->isYaffs2
5407 && (dev->sequenceNumber !=
5412 "id: block seq = %d, dev seq = %d"
5415 dev->sequenceNumber));
5419 dev->nFreeChunks++;
5424 (tags.chunkId - 1) * dev->nDataBytesPerChunk;
5429 yaffs_SetChunkBit(dev, blk, c);
5432 in = yaffs_FindOrCreateObjectByNumber(dev,
5448 1) * dev->nDataBytesPerChunk +
5464 yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
5473 yaffs_SetChunkBit(dev, blk, c);
5481 (dev, tags.objectId,
5500 result = yaffs_ReadChunkWithTagsFromNAND(dev,
5508 in = yaffs_FindOrCreateObjectByNumber(dev, tags.objectId, oh->type);
5570 yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
5635 yaffs_HandleShadowedObject(dev,
5644 (dev, oh->parentObjectId,
5656 (dev, tags.extraParentObjectId,
5690 parent = dev->lostNFoundDir;
5695 itsUnlinked = (parent == dev->deletedDir) ||
5696 (parent == dev->unlinkedDir);
5772 yaffs_BlockBecameDirty(dev, blk);
5787 yaffs_HardlinkFixup(dev,hardList);
5801 &dev->unlinkedDir->variant.directoryVariant.
5811 &dev->deletedDir->variant.directoryVariant.
5821 yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
5832 yaffs_Device *dev = obj->myDev;
5834 if(dev && dev->removeObjectCallback)
5835 dev->removeObjectCallback(obj);
6191 static int yaffs_CheckDevFunctions(const yaffs_Device * dev)
6195 if (!dev->eraseBlockInNAND || !dev->initialiseNAND)
6201 if (dev->writeChunkWithTagsToNAND &&
6202 dev->readChunkWithTagsFromNAND &&
6203 !dev->writeChunkToNAND &&
6204 !dev->readChunkFromNAND &&
6205 dev->markNANDBlockBad && dev->queryNANDBlock)
6210 if (!dev->isYaffs2 &&
6211 !dev->writeChunkWithTagsToNAND &&
6212 !dev->readChunkWithTagsFromNAND &&
6213 dev->writeChunkToNAND &&
6214 dev->readChunkFromNAND &&
6215 !dev->markNANDBlockBad && !dev->queryNANDBlock)
6222 static void yaffs_CreateInitialDirectories(yaffs_Device *dev)
6226 dev->lostNFoundDir = dev->rootDir = NULL;
6227 dev->unlinkedDir = dev->deletedDir = NULL;
6229 dev->unlinkedDir =
6230 yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_UNLINKED, S_IFDIR);
6231 dev->deletedDir =
6232 yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_DELETED, S_IFDIR);
6234 dev->rootDir =
6235 yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_ROOT,
6237 dev->lostNFoundDir =
6238 yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_LOSTNFOUND,
6240 yaffs_AddObjectToDirectory(dev->rootDir, dev->lostNFoundDir);
6243 int yaffs_GutsInitialise(yaffs_Device * dev)
6252 if (!dev) {
6257 dev->internalStartBlock = dev->startBlock;
6258 dev->internalEndBlock = dev->endBlock;
6259 dev->blockOffset = 0;
6260 dev->chunkOffset = 0;
6261 dev->nFreeChunks = 0;
6263 if (dev->startBlock == 0) {
6264 dev->internalStartBlock = dev->startBlock + 1;
6265 dev->internalEndBlock = dev->endBlock + 1;
6266 dev->blockOffset = 1;
6267 dev->chunkOffset = dev->nChunksPerBlock;
6272 if ((dev->isYaffs2 && dev->nDataBytesPerChunk < 1024) ||
6273 (!dev->isYaffs2 && dev->nDataBytesPerChunk != 512) ||
6274 dev->nChunksPerBlock < 2 ||
6275 dev->nReservedBlocks < 2 ||
6276 dev->internalStartBlock <= 0 ||
6277 dev->internalEndBlock <= 0 ||
6278 dev->internalEndBlock <= (dev->internalStartBlock + dev->nReservedBlocks + 2) // otherwise it is too small
6283 TENDSTR), dev->nDataBytesPerChunk, dev->isYaffs2 ? "2" : ""));
6287 if (yaffs_InitialiseNAND(dev) != YAFFS_OK) {
6294 if (!yaffs_CheckDevFunctions(dev)) {
6310 if (dev->isMounted) {
6318 dev->isMounted = 1;
6328 dev->chunkShift = ShiftDiv(dev->nDataBytesPerChunk);
6329 dev->chunkMask = (1<<dev->chunkShift) - 1;
6331 if(dev->nDataBytesPerChunk == (dev->chunkMask + 1)){
6333 dev->crumbMask = 0;
6334 dev->crumbShift = 0;
6335 dev->crumbsPerChunk = 0;
6338 dev->crumbShift = ShiftDiv(sizeof(yaffs_PackedTags2TagsPart));
6339 dev->crumbMask = (1<<dev->crumbShift)-1;
6340 dev->crumbsPerChunk = dev->nDataBytesPerChunk/(1 << dev->crumbShift);
6341 dev->chunkShift = 0;
6342 dev->chunkMask = 0;
6351 x = dev->nChunksPerBlock * (dev->internalEndBlock + 1);
6356 if(!dev->wideTnodesDisabled){
6361 dev->tnodeWidth = 16;
6363 dev->tnodeWidth = bits;
6366 dev->tnodeWidth = 16;
6368 dev->tnodeMask = (1<<dev->tnodeWidth)-1;
6376 if (bits <= dev->tnodeWidth)
6377 dev->chunkGroupBits = 0;
6379 dev->chunkGroupBits = bits - dev->tnodeWidth;
6382 dev->chunkGroupSize = 1 << dev->chunkGroupBits;
6384 if (dev->nChunksPerBlock < dev->chunkGroupSize) {
6398 dev->garbageCollections = 0;
6399 dev->passiveGarbageCollections = 0;
6400 dev->currentDirtyChecker = 0;
6401 dev->bufferedBlock = -1;
6402 dev->doingBufferedBlockRewrite = 0;
6403 dev->nDeletedFiles = 0;
6404 dev->nBackgroundDeletions = 0;
6405 dev->nUnlinkedFiles = 0;
6406 dev->eccFixed = 0;
6407 dev->eccUnfixed = 0;
6408 dev->tagsEccFixed = 0;
6409 dev->tagsEccUnfixed = 0;
6410 dev->nErasureFailures = 0;
6411 dev->nErasedBlocks = 0;
6412 dev->isDoingGC = 0;
6413 dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
6419 dev->tempBuffer[i].line = 0; /* not in use */
6420 dev->tempBuffer[i].buffer =
6421 YMALLOC_DMA(dev->nDataBytesPerChunk);
6425 if (dev->nShortOpCaches > 0) {
6428 if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES) {
6429 dev->nShortOpCaches = YAFFS_MAX_SHORT_OP_CACHES;
6432 dev->srCache =
6433 YMALLOC(dev->nShortOpCaches * sizeof(yaffs_ChunkCache));
6435 for (i = 0; i < dev->nShortOpCaches; i++) {
6436 dev->srCache[i].object = NULL;
6437 dev->srCache[i].lastUse = 0;
6438 dev->srCache[i].dirty = 0;
6439 dev->srCache[i].data = YMALLOC_DMA(dev->nDataBytesPerChunk);
6441 dev->srLastUse = 0;
6444 dev->cacheHits = 0;
6446 dev->gcCleanupList = YMALLOC(dev->nChunksPerBlock * sizeof(__u32));
6448 if (dev->isYaffs2) {
6449 dev->useHeaderFileSize = 1;
6452 yaffs_InitialiseBlocks(dev);
6453 yaffs_InitialiseTnodes(dev);
6454 yaffs_InitialiseObjects(dev);
6456 yaffs_CreateInitialDirectories(dev);
6460 if (dev->isYaffs2) {
6461 if(yaffs_CheckpointRestore(dev)) {
6469 yaffs_DeinitialiseBlocks(dev);
6470 yaffs_DeinitialiseTnodes(dev);
6471 yaffs_DeinitialiseObjects(dev);
6472 yaffs_InitialiseBlocks(dev);
6473 yaffs_InitialiseTnodes(dev);
6474 yaffs_InitialiseObjects(dev);
6475 yaffs_CreateInitialDirectories(dev);
6477 yaffs_ScanBackwards(dev);
6480 yaffs_Scan(dev);
6483 dev->nPageReads = 0;
6484 dev->nPageWrites = 0;
6485 dev->nBlockErasures = 0;
6486 dev->nGCCopies = 0;
6487 dev->nRetriedWrites = 0;
6489 dev->nRetiredBlocks = 0;
6491 yaffs_VerifyFreeChunks(dev);
6499 void yaffs_Deinitialise(yaffs_Device * dev)
6501 if (dev->isMounted) {
6504 yaffs_DeinitialiseBlocks(dev);
6505 yaffs_DeinitialiseTnodes(dev);
6506 yaffs_DeinitialiseObjects(dev);
6507 if (dev->nShortOpCaches > 0) {
6509 for (i = 0; i < dev->nShortOpCaches; i++) {
6510 YFREE(dev->srCache[i].data);
6513 YFREE(dev->srCache);
6516 YFREE(dev->gcCleanupList);
6519 YFREE(dev->tempBuffer[i].buffer);
6522 dev->isMounted = 0;
6527 static int yaffs_CountFreeChunks(yaffs_Device * dev)
6534 for (nFree = 0, b = dev->internalStartBlock; b <= dev->internalEndBlock;
6536 blk = yaffs_GetBlockInfo(dev, b);
6544 (dev->nChunksPerBlock - blk->pagesInUse +
6556 int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev)
6565 nFree = dev->nFreeChunks;
6567 nFree = yaffs_CountFreeChunks(dev);
6570 nFree += dev->nDeletedFiles;
6576 for (nDirtyCacheChunks = 0, i = 0; i < dev->nShortOpCaches; i++) {
6577 if (dev->srCache[i].dirty)
6584 nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock);
6587 blocksForCheckpoint = dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint;
6591 nFree -= (blocksForCheckpoint * dev->nChunksPerBlock);
6602 static void yaffs_VerifyFreeChunks(yaffs_Device * dev)
6604 int counted = yaffs_CountFreeChunks(dev);
6606 int difference = dev->nFreeChunks - counted;
6611 dev->nFreeChunks, counted, difference));