/*
* YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
*
* Copyright (C) 2002-2007 Aleph One Ltd.
* for Toby Churchill Ltd and Brightstar Engineering
*
* Created by Charles Manning <charles@aleph1.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/* XXX U-BOOT XXX */
#include <common.h>
const char *yaffs_guts_c_version =
"$Id: yaffs_guts.c,v 1.52 2007/10/16 00:45:05 charles Exp $";
#include "yportenv.h"
#include "linux/stat.h"
#include "yaffsinterface.h"
#include "yaffsfs.h"
#include "yaffs_guts.h"
#include "yaffs_tagsvalidity.h"
#include "yaffs_tagscompat.h"
#ifndef CONFIG_YAFFS_USE_OWN_SORT
#include "yaffs_qsort.h"
#endif
#include "yaffs_nand.h"
#include "yaffs_checkptrw.h"
#include "yaffs_nand.h"
#include "yaffs_packedtags2.h"
#include "malloc.h"
#ifdef CONFIG_YAFFS_WINCE
void yfsd_LockYAFFS(BOOL fsLockOnly);
void yfsd_UnlockYAFFS(BOOL fsLockOnly);
#endif
#define YAFFS_PASSIVE_GC_CHUNKS 2
#include "yaffs_ecc.h"
/* Robustification (if it ever comes about...) */
static void yaffs_RetireBlock(yaffs_Device * dev, int blockInNAND);
static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND, int erasedOk);
static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND,
const __u8 * data,
const yaffs_ExtendedTags * tags);
static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND,
const yaffs_ExtendedTags * tags);
/* Other local prototypes */
static int yaffs_UnlinkObject( yaffs_Object *obj);
static int yaffs_ObjectHasCachedWriteData(yaffs_Object *obj);
static void yaffs_HardlinkFixup(yaffs_Device *dev, yaffs_Object *hardList);
static int yaffs_WriteNewChunkWithTagsToNAND(yaffs_Device * dev,
const __u8 * buffer,
yaffs_ExtendedTags * tags,
int useReserve);
static int yaffs_PutChunkIntoFile(yaffs_Object * in, int chunkInInode,
int chunkInNAND, int inScan);
static yaffs_Object *yaffs_CreateNewObject(yaffs_Device * dev, int number,
yaffs_ObjectType type);
static void yaffs_AddObjectToDirectory(yaffs_Object * directory,
yaffs_Object * obj);
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);
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 __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo);
static void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer,
int lineNo);
static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
int chunkInNAND);
static int yaffs_UnlinkWorker(yaffs_Object * obj);
static void yaffs_DestroyObject(yaffs_Object * obj);
static int yaffs_TagsMatch(const yaffs_ExtendedTags * tags, int objectId,
int chunkInObject);
loff_t yaffs_GetFileSize(yaffs_Object * obj);
static int yaffs_AllocateChunk(yaffs_Device * dev, int useReserve, yaffs_BlockInfo **blockUsedPtr);
static void yaffs_VerifyFreeChunks(yaffs_Device * dev);
static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in);
#ifdef YAFFS_PARANOID
static int yaffs_CheckFileSanity(yaffs_Object * in);
#else
#define yaffs_CheckFileSanity(in)
#endif
static void yaffs_InvalidateWholeChunkCache(yaffs_Object * in);
static void yaffs_InvalidateChunkCache(yaffs_Object * object, int chunkId);
static void yaffs_InvalidateCheckpoint(yaffs_Device *dev);
static int yaffs_FindChunkInFile(yaffs_Object * in, int chunkInInode,
yaffs_ExtendedTags * tags);
static __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos);
static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device * dev,
yaffs_FileStructure * fStruct,
__u32 chunkId);
/* Function to calculate chunk and offset */
static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, __u32 *chunk, __u32 *offset)
{
if(dev->chunkShift){
/* Easy-peasy power of 2 case */
*chunk = (__u32)(addr >> dev->chunkShift);
*offset = (__u32)(addr & dev->chunkMask);
}
else if(dev->crumbsPerChunk)
{
/* Case where we're using "crumbs" */
*offset = (__u32)(addr & dev->crumbMask);
addr >>= dev->crumbShift;
*chunk = ((__u32)addr)/dev->crumbsPerChunk;
*offset += ((addr - (*chunk * dev->crumbsPerChunk)) << dev->crumbShift);
}
else
YBUG();
}
/* Function to return the number of shifts for a power of 2 greater than or equal
* to the given number
* Note we don't try to cater for all possible numbers and this does not have to
* be hellishly efficient.
*/
static __u32 ShiftsGE(__u32 x)
{
int extraBits;
int nShifts;
nShifts = extraBits = 0;
while(x>1){
if(x & 1) extraBits++;
x>>=1;
nShifts++;
}
if(extraBits)
nShifts++;
return nShifts;
}
/* Function to return the number of shifts to get a 1 in bit 0
*/
static __u32 ShiftDiv(__u32 x)
{
int nShifts;
nShifts = 0;
if(!x) return 0;
while( !(x&1)){
x>>=1;
nShifts++;
}
return nShifts;
}
/*
* Temporary buffer manipulations.
*/
static int yaffs_InitialiseTempBuffers(yaffs_Device *dev)
{
int i;
__u8 *buf = (__u8 *)1;
memset(dev->tempBuffer,0,sizeof(dev->tempBuffer));
for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) {
dev->tempBuffer[i].line = 0; /* not in use */
dev->tempBuffer[i].buffer = buf =
YMALLOC_DMA(dev->nDataBytesPerChunk);
}
return buf ? YAFFS_OK : YAFFS_FAIL;
}
static __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo)
{
int i, j;
for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
if (dev->tempBuffer[i].line == 0) {
dev->tempBuffer[i].line = lineNo;
if ((i + 1) > dev->maxTemp) {
dev->maxTemp = i + 1;
for (j = 0; j <= i; j++)
dev->tempBuffer[j].maxLine =
dev->tempBuffer[j].line;
}
return dev->tempBuffer[i].buffer;
}
}
T(YAFFS_TRACE_BUFFERS,
(TSTR("Out of temp buffers at line %d, other held by lines:"),
lineNo));
for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
T(YAFFS_TRACE_BUFFERS, (TSTR(" %d "), dev->tempBuffer[i].line));
}
T(YAFFS_TRACE_BUFFERS, (TSTR(" " TENDSTR)));
/*
* If we got here then we have to allocate an unmanaged one
* This is not good.
*/
dev->unmanagedTempAllocations++;
return YMALLOC(dev->nDataBytesPerChunk);
}
static void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer,
int lineNo)
{
int i;
for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
if (dev->tempBuffer[i].buffer == buffer) {
dev->tempBuffer[i].line = 0;
return;
}
}
if (buffer) {
/* assume it is an unmanaged one. */
T(YAFFS_TRACE_BUFFERS,
(TSTR("Releasing unmanaged temp buffer in line %d" TENDSTR),
lineNo));
YFREE(buffer);
dev->unmanagedTempDeallocations++;
}
}
/*
* Determine if we have a managed buffer.
*/
int yaffs_IsManagedTempBuffer(yaffs_Device * dev, const __u8 * buffer)
{
int i;
for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
if (dev->tempBuffer[i].buffer == buffer)
return 1;
}
for (i = 0; i < dev->nShortOpCaches; i++) {
if( dev->srCache[i].data == buffer )
return 1;
}
if (buffer == dev->checkpointBuffer)
return 1;
T(YAFFS_TRACE_ALWAYS,
(TSTR("yaffs: unmaged buffer detected.\n" TENDSTR)));
return 0;
}
/*
* Chunk bitmap manipulations
*/
static Y_INLINE __u8 *yaffs_BlockBits(yaffs_Device * dev, int blk)
{
if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
T(YAFFS_TRACE_ERROR,
(TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR),
blk));
YBUG();
}
return dev->chunkBits +
(dev->chunkBitmapStride * (blk - dev->internalStartBlock));
}
static Y_INLINE void yaffs_Veri
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
qq2440-uboot-qq2440使用的uboot (2000个子文件)
esd.bmp 34KB
atmel.bmp 26KB
linux_logo_ttcontrol_palfin.bmp 20KB
denx.bmp 15KB
linux_logo_ttcontrol.bmp 12KB
syteco.bmp 11KB
ronetix.bmp 6KB
yaffs_guts.c 178KB
tigon3.c 173KB
e1000.c 153KB
ops.c 140KB
dlmalloc.c 101KB
hush.c 92KB
image.c 83KB
zlib.c 81KB
nand_base.c 80KB
tnc.c 72KB
onenand_base.c 71KB
4xx_enet.c 62KB
prim_ops.c 62KB
cfi_flash.c 55KB
ohci-hcd.c 52KB
cmd_ide.c 50KB
tsec.c 50KB
diskonchip.c 49KB
ops2.c 48KB
jffs2_1pass.c 47KB
sata_dwc.c 47KB
cmd_mtdparts.c 47KB
cfb_console.c 45KB
usb_ohci.c 45KB
bcm570x.c 45KB
net.c 44KB
wl.c 44KB
omap1510_udc.c 43KB
bzlib.c 43KB
ct69000.c 40KB
usb_storage.c 39KB
usb.c 38KB
io.c 37KB
cmd_bootm.c 37KB
cmd_i2c.c 37KB
isp116x-hcd.c 36KB
MCD_tasks.c 36KB
MCD_dmaApi.c 35KB
smc91111.c 34KB
mxc_nand.c 34KB
scan.c 34KB
eba.c 33KB
uec.c 33KB
build.c 33KB
nand_bbt.c 33KB
mpc8xx_udc.c 33KB
tsi108_eth.c 32KB
super.c 32KB
recovery.c 31KB
decode.c 31KB
main.c 31KB
musb_hcd.c 30KB
pata_bfin.c 30KB
bedbug.c 30KB
lpt.c 29KB
cmd_mem.c 29KB
fw_env.c 29KB
fdt_support.c 29KB
sym53c8xx.c 29KB
reiserfs.c 28KB
replay.c 27KB
LzmaDec.c 27KB
usbtty.c 26KB
yaffsfs.c 26KB
spr_udc.c 26KB
cmd_load.c 26KB
uli526x.c 26KB
altera_tse.c 25KB
jffs2_nand_1pass.c 25KB
fat.c 25KB
i82365.c 25KB
fsl_sata.c 25KB
mpc5xxx_fec.c 24KB
eepro100.c 24KB
remote.c 24KB
ati_radeon_fb.c 24KB
lprops.c 24KB
ns7520_eth.c 24KB
smiLynxEM.c 24KB
ns9750_eth.c 24KB
enc28j60.c 24KB
uec_phy.c 23KB
r8a66597-hcd.c 23KB
ns8382x.c 23KB
i8042.c 23KB
cmd_fdc.c 23KB
vtbl.c 23KB
rtl8169.c 23KB
natsemi.c 23KB
mx3fb.c 23KB
vmt.c 23KB
bootp.c 22KB
fsl_elbc_nand.c 22KB
共 2000 条
- 1
- 2
- 3
- 4
- 5
- 6
- 20
资源评论
Java程序员-张凯
- 粉丝: 1w+
- 资源: 6804
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功