projects
/
yaffs2.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
yaffs: Clean up yaffs direct configuration
[yaffs2.git]
/
yaffs_guts.c
diff --git
a/yaffs_guts.c
b/yaffs_guts.c
index 42e234a73f56852b4d5760733c3f9ec59e3ae076..9509dd401a33e5e9eb0a6989f74f733b1cc33d61 100644
(file)
--- a/
yaffs_guts.c
+++ b/
yaffs_guts.c
@@
-1,7
+1,7
@@
/*
* YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
*
/*
* YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
*
- * Copyright (C) 2002-20
07
Aleph One Ltd.
+ * Copyright (C) 2002-20
10
Aleph One Ltd.
* for Toby Churchill Ltd and Brightstar Engineering
*
* Created by Charles Manning <charles@aleph1.co.uk>
* for Toby Churchill Ltd and Brightstar Engineering
*
* Created by Charles Manning <charles@aleph1.co.uk>
@@
-10,10
+10,6
@@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
-const char *yaffs_guts_c_version =
- "$Id: yaffs_guts.c,v 1.120 2010-03-15 23:10:34 charles Exp $";
-
#include "yportenv.h"
#include "yaffs_trace.h"
#include "yportenv.h"
#include "yaffs_trace.h"
@@
-37,8
+33,17
@@
const char *yaffs_guts_c_version =
/* Note YAFFS_GC_GOOD_ENOUGH must be <= YAFFS_GC_PASSIVE_THRESHOLD */
#define YAFFS_GC_GOOD_ENOUGH 2
#define YAFFS_GC_PASSIVE_THRESHOLD 4
/* Note YAFFS_GC_GOOD_ENOUGH must be <= YAFFS_GC_PASSIVE_THRESHOLD */
#define YAFFS_GC_GOOD_ENOUGH 2
#define YAFFS_GC_PASSIVE_THRESHOLD 4
+
#define YAFFS_SMALL_HOLE_THRESHOLD 3
#define YAFFS_SMALL_HOLE_THRESHOLD 3
+/*
+ * Checkpoints are really no benefit on very small partitions.
+ *
+ * To save space on small partitions don't bother with checkpoints unless
+ * the partition is at least this big.
+ */
+#define YAFFS_CHECKPOINT_MIN_BLOCKS 60
+
#include "yaffs_ecc.h"
#include "yaffs_ecc.h"
@@
-74,8
+79,6
@@
static int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name,
int force, int isShrink, int shadows);
static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj);
static int yaffs_CheckStructures(void);
int force, int isShrink, int shadows);
static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj);
static int yaffs_CheckStructures(void);
-static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level,
- int chunkOffset, int *limit);
static int yaffs_DoGenericObjectDeletion(yaffs_Object *in);
static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device *dev, int blockNo);
static int yaffs_DoGenericObjectDeletion(yaffs_Object *in);
static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device *dev, int blockNo);
@@
-183,7
+186,7
@@
static __u32 ShiftsGE(__u32 x)
static __u32 Shifts(__u32 x)
{
static __u32 Shifts(__u32 x)
{
-
int
nShifts;
+
__u32
nShifts;
nShifts = 0;
nShifts = 0;
@@
-610,7
+613,8
@@
static void yaffs_VerifyObjectHeader(yaffs_Object *obj, yaffs_ObjectHeader *oh,
}
}
-
+#if 0
+/* Not being used, but don't want to throw away yet */
static int yaffs_VerifyTnodeWorker(yaffs_Object *obj, yaffs_Tnode *tn,
__u32 level, int chunkOffset)
{
static int yaffs_VerifyTnodeWorker(yaffs_Object *obj, yaffs_Tnode *tn,
__u32 level, int chunkOffset)
{
@@
-656,6
+660,7
@@
static int yaffs_VerifyTnodeWorker(yaffs_Object *obj, yaffs_Tnode *tn,
}
}
+#endif
static void yaffs_VerifyFile(yaffs_Object *obj)
{
static void yaffs_VerifyFile(yaffs_Object *obj)
{
@@
-1708,9
+1713,10
@@
static int yaffs_FindChunkInGroup(yaffs_Device *dev, int theChunk,
return -1;
}
return -1;
}
-
+#if 0
+/* Experimental code not being used yet. Might speed up file deletion */
/* DeleteWorker scans backwards through the tnode tree and deletes all the
/* DeleteWorker scans backwards through the tnode tree and deletes all the
- * chunks and tnodes in the file
+ * chunks and tnodes in the file
.
* Returns 1 if the tree was deleted.
* Returns 0 if it stopped early due to hitting the limit and the delete is incomplete.
*/
* Returns 1 if the tree was deleted.
* Returns 0 if it stopped early due to hitting the limit and the delete is incomplete.
*/
@@
-1802,6
+1808,8
@@
static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level,
}
}
+#endif
+
static void yaffs_SoftDeleteChunk(yaffs_Device *dev, int chunk)
{
yaffs_BlockInfo *theBlock;
static void yaffs_SoftDeleteChunk(yaffs_Device *dev, int chunk)
{
yaffs_BlockInfo *theBlock;
@@
-2956,10
+2964,17
@@
static int yaffs_FindBlockForAllocation(yaffs_Device *dev)
+static int yaffs_CheckpointRequired(yaffs_Device *dev)
+{
+ int nblocks = dev->internalEndBlock - dev->internalStartBlock + 1 ;
+ return dev->param.isYaffs2 &&
+ !dev->param.skipCheckpointWrite &&
+ (nblocks >= YAFFS_CHECKPOINT_MIN_BLOCKS);
+}
static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev)
{
if (!dev->nCheckpointBlocksRequired &&
static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev)
{
if (!dev->nCheckpointBlocksRequired &&
-
dev->param.isYaffs2)
{
+
yaffs_CheckpointRequired(dev))
{
/* Not a valid value so recalculate */
int nBytes = 0;
int nBlocks;
/* Not a valid value so recalculate */
int nBytes = 0;
int nBlocks;
@@
-3465,11
+3480,18
@@
static unsigned yaffs_FindBlockForGarbageCollection(yaffs_Device *dev,
selected = dev->gcDirtiest;
}
selected = dev->gcDirtiest;
}
- if(!selected && dev->param.isYaffs2 && dev->gcNotDone >= ( background ? 10 : 20)){
+ /*
+ * If nothing has been selected for a while, try selecting the oldest dirty
+ * because that's gumming up the works.
+ */
+
+ if(!selected && dev->param.isYaffs2 &&
+ dev->gcNotDone >= ( background ? 10 : 20)){
yaffs_FindOldestDirtySequence(dev);
if(dev->oldestDirtyBlock > 0) {
selected = dev->oldestDirtyBlock;
dev->gcDirtiest = selected;
yaffs_FindOldestDirtySequence(dev);
if(dev->oldestDirtyBlock > 0) {
selected = dev->oldestDirtyBlock;
dev->gcDirtiest = selected;
+ dev->oldestDirtyGCs++;
bi = yaffs_GetBlockInfo(dev, selected);
dev->gcPagesInUse = bi->pagesInUse - bi->softDeletions;
} else
bi = yaffs_GetBlockInfo(dev, selected);
dev->gcPagesInUse = bi->pagesInUse - bi->softDeletions;
} else
@@
-3483,6
+3505,8
@@
static unsigned yaffs_FindBlockForGarbageCollection(yaffs_Device *dev,
dev->param.nChunksPerBlock - dev->gcPagesInUse,
prioritised));
dev->param.nChunksPerBlock - dev->gcPagesInUse,
prioritised));
+ if(background)
+ dev->backgroundGCs++;
dev->gcDirtiest = 0;
dev->gcPagesInUse = 0;
dev->gcNotDone = 0;
dev->gcDirtiest = 0;
dev->gcPagesInUse = 0;
dev->gcNotDone = 0;
@@
-3575,9
+3599,9
@@
static int yaffs_CheckGarbageCollection(yaffs_Device *dev, int background)
}
if (dev->gcBlock > 0) {
}
if (dev->gcBlock > 0) {
- dev->
garbageCollection
s++;
+ dev->
allGC
s++;
if (!aggressive)
if (!aggressive)
- dev->passiveG
arbageCollection
s++;
+ dev->passiveG
C
s++;
T(YAFFS_TRACE_GC,
(TSTR
T(YAFFS_TRACE_GC,
(TSTR
@@
-3605,11
+3629,11
@@
static int yaffs_CheckGarbageCollection(yaffs_Device *dev, int background)
* Garbage collects. Intended to be called from a background thread.
* Returns non-zero if at least half the free chunks are erased.
*/
* Garbage collects. Intended to be called from a background thread.
* Returns non-zero if at least half the free chunks are erased.
*/
-int yaffs_BackgroundGarbageCollect(yaffs_Device *dev)
+int yaffs_BackgroundGarbageCollect(yaffs_Device *dev
, unsigned urgency
)
{
int erasedChunks = dev->nErasedBlocks * dev->param.nChunksPerBlock;
{
int erasedChunks = dev->nErasedBlocks * dev->param.nChunksPerBlock;
- T(YAFFS_TRACE_BACKGROUND, (TSTR("Background gc
" TENDSTR)
));
+ T(YAFFS_TRACE_BACKGROUND, (TSTR("Background gc
%u" TENDSTR),urgency
));
yaffs_CheckGarbageCollection(dev, 1);
return erasedChunks > dev->nFreeChunks/2;
yaffs_CheckGarbageCollection(dev, 1);
return erasedChunks > dev->nFreeChunks/2;
@@
-4871,7
+4895,7
@@
static int yaffs_WriteCheckpointData(yaffs_Device *dev)
{
int ok = 1;
{
int ok = 1;
- if (
dev->param.skipCheckpointWrite || !dev->param.isYaffs2
) {
+ if (
!yaffs_CheckpointRequired(dev)
) {
T(YAFFS_TRACE_CHECKPOINT, (TSTR("skipping checkpoint write" TENDSTR)));
ok = 0;
}
T(YAFFS_TRACE_CHECKPOINT, (TSTR("skipping checkpoint write" TENDSTR)));
ok = 0;
}
@@
-5127,8
+5151,6
@@
int yaffs_DoWriteDataToFile(yaffs_Object *in, const __u8 *buffer, loff_t offset,
dev = in->myDev;
while (n > 0 && chunkWritten >= 0) {
dev = in->myDev;
while (n > 0 && chunkWritten >= 0) {
- /* chunk = offset / dev->nDataBytesPerChunk + 1; */
- /* start = offset % dev->nDataBytesPerChunk; */
yaffs_AddrToChunk(dev, offset, &chunk, &start);
if (chunk * dev->nDataBytesPerChunk + start != offset ||
yaffs_AddrToChunk(dev, offset, &chunk, &start);
if (chunk * dev->nDataBytesPerChunk + start != offset ||
@@
-5138,7
+5160,7
@@
int yaffs_DoWriteDataToFile(yaffs_Object *in, const __u8 *buffer, loff_t offset,
TENDSTR),
(int)offset, chunk, start));
}
TENDSTR),
(int)offset, chunk, start));
}
- chunk++;
+ chunk++;
/* File pos to chunk in file offset */
/* OK now check for the curveball where the start and end are in
* the same chunk.
/* OK now check for the curveball where the start and end are in
* the same chunk.
@@
-5602,7
+5624,7
@@
static int yaffs_UnlinkFileIfNeeded(yaffs_Object *in)
int yaffs_DeleteFile(yaffs_Object *in)
{
int retVal = YAFFS_OK;
int yaffs_DeleteFile(yaffs_Object *in)
{
int retVal = YAFFS_OK;
- int deleted
= in->deleted;
+ int deleted
; /* Need to cache value on stack if in is freed */
yaffs_Device *dev = in->myDev;
if (dev->param.disableSoftDelete || dev->param.isYaffs2)
yaffs_Device *dev = in->myDev;
if (dev->param.disableSoftDelete || dev->param.isYaffs2)
@@
-5615,6
+5637,8
@@
int yaffs_DeleteFile(yaffs_Object *in)
if (!in->unlinked)
retVal = yaffs_UnlinkFileIfNeeded(in);
if (!in->unlinked)
retVal = yaffs_UnlinkFileIfNeeded(in);
+ deleted = in->deleted;
+
if (retVal == YAFFS_OK && in->unlinked && !in->deleted) {
in->deleted = 1;
deleted = 1;
if (retVal == YAFFS_OK && in->unlinked && !in->deleted) {
in->deleted = 1;
deleted = 1;
@@
-6762,7
+6786,7
@@
static int yaffs_ScanBackwards(yaffs_Device *dev)
* the current allocation block.
*/
* the current allocation block.
*/
- T(YAFFS_TRACE_
ALWAYS
,
+ T(YAFFS_TRACE_
SCAN
,
(TSTR("Partially written block %d detected" TENDSTR),
blk));
}
(TSTR("Partially written block %d detected" TENDSTR),
blk));
}
@@
-7907,8
+7931,10
@@
int yaffs_GutsInitialise(yaffs_Device *dev)
/* OK, we've finished verifying the device, lets continue with initialisation */
/* More device initialisation */
/* OK, we've finished verifying the device, lets continue with initialisation */
/* More device initialisation */
- dev->garbageCollections = 0;
- dev->passiveGarbageCollections = 0;
+ dev->allGCs = 0;
+ dev->passiveGCs = 0;
+ dev->oldestDirtyGCs = 0;
+ dev->backgroundGCs = 0;
dev->gcBlockFinder = 0;
dev->bufferedBlock = -1;
dev->doingBufferedBlockRewrite = 0;
dev->gcBlockFinder = 0;
dev->bufferedBlock = -1;
dev->doingBufferedBlockRewrite = 0;