yaffs: moved to newest official xyaffs driver

This commit is contained in:
Markinus 2011-01-29 12:02:03 +01:00 committed by tytung
parent fc0148dc57
commit 1130964c5c
30 changed files with 4705 additions and 5478 deletions

View File

@ -102,22 +102,6 @@ config YAFFS_DISABLE_TAGS_ECC
If unsure, say N.
config YAFFS_DISABLE_WIDE_TNODES
bool "Turn off wide tnodes"
depends on YAFFS_FS
default n
help
Wide tnodes are only used for NAND arrays >=32MB for 512-byte
page devices and >=128MB for 2k page devices. They use slightly
more RAM but are faster since they eliminate chunk group
searching.
Setting this to 'y' will force tnode width to 16 bits and save
memory but make large arrays slower.
If unsure, say N.
config YAFFS_ALWAYS_CHECK_CHUNK_ERASED
bool "Force chunk erase check"
depends on YAFFS_FS
@ -136,17 +120,6 @@ config YAFFS_ALWAYS_CHECK_CHUNK_ERASED
If unsure, say Y.
config YAFFS_SHORT_NAMES_IN_RAM
bool "Cache short names in RAM"
depends on YAFFS_FS
default y
help
If this config is set, then short names are stored with the
yaffs_Object. This costs an extra 16 bytes of RAM per object,
but makes look-ups faster.
If unsure, say Y.
config YAFFS_EMPTY_LOST_AND_FOUND
bool "Empty lost and found on boot"
depends on YAFFS_FS
@ -177,7 +150,7 @@ config YAFFS_DISABLE_BACKGROUND
If this is set, then background processing is disabled.
Background processing makes many foreground activities faster.
If unsure, say N.
If unsure, say N.
config YAFFS_XATTR
bool "Enable yaffs2 xattr support"
@ -186,5 +159,3 @@ config YAFFS_XATTR
help
If this is set then yaffs2 will provide xattr support.
If unsure, say Y.

View File

@ -16,7 +16,8 @@
#include "yaffs_trace.h"
#include "yportenv.h"
#ifdef CONFIG_YAFFS_YMALLOC_ALLOCATOR
#ifdef CONFIG_YAFFS_KMALLOC_ALLOCATOR
/* This is an alternative debug allocator. Don't use for production code. */
void yaffs_deinit_raw_tnodes_and_objs(struct yaffs_dev *dev)
{
@ -30,13 +31,13 @@ void yaffs_init_raw_tnodes_and_objs(struct yaffs_dev *dev)
struct yaffs_tnode *yaffs_alloc_raw_tnode(struct yaffs_dev *dev)
{
return (struct yaffs_tnode *)YMALLOC(dev->tnode_size);
return kmalloc(dev->tnode_size, GFP_NOFS);
}
void yaffs_free_raw_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn)
{
dev = dev;
YFREE(tn);
kfree(tn);
}
void yaffs_init_raw_objs(struct yaffs_dev *dev)
@ -52,14 +53,14 @@ void yaffs_deinit_raw_objs(struct yaffs_dev *dev)
struct yaffs_obj *yaffs_alloc_raw_obj(struct yaffs_dev *dev)
{
dev = dev;
return (struct yaffs_obj *)YMALLOC(sizeof(struct yaffs_obj));
return kmalloc(sizeof(struct yaffs_obj));
}
void yaffs_free_raw_obj(struct yaffs_dev *dev, struct yaffs_obj *obj)
{
dev = dev;
YFREE(obj);
kfree(obj);
}
#else
@ -89,10 +90,8 @@ struct yaffs_allocator {
static void yaffs_deinit_raw_tnodes(struct yaffs_dev *dev)
{
struct yaffs_allocator *allocator =
(struct yaffs_allocator *)dev->allocator;
struct yaffs_tnode_list *tmp;
if (!allocator) {
@ -103,10 +102,9 @@ static void yaffs_deinit_raw_tnodes(struct yaffs_dev *dev)
while (allocator->alloc_tnode_list) {
tmp = allocator->alloc_tnode_list->next;
YFREE(allocator->alloc_tnode_list->tnodes);
YFREE(allocator->alloc_tnode_list);
kfree(allocator->alloc_tnode_list->tnodes);
kfree(allocator->alloc_tnode_list);
allocator->alloc_tnode_list = tmp;
}
allocator->free_tnodes = NULL;
@ -123,8 +121,9 @@ static void yaffs_init_raw_tnodes(struct yaffs_dev *dev)
allocator->free_tnodes = NULL;
allocator->n_free_tnodes = 0;
allocator->n_tnodes_created = 0;
} else
} else {
YBUG();
}
}
static int yaffs_create_tnodes(struct yaffs_dev *dev, int n_tnodes)
@ -147,13 +146,12 @@ static int yaffs_create_tnodes(struct yaffs_dev *dev, int n_tnodes)
return YAFFS_OK;
/* make these things */
new_tnodes = YMALLOC(n_tnodes * dev->tnode_size);
new_tnodes = kmalloc(n_tnodes * dev->tnode_size, GFP_NOFS);
mem = (u8 *) new_tnodes;
if (!new_tnodes) {
T(YAFFS_TRACE_ERROR,
(TSTR("yaffs: Could not allocate Tnodes" TENDSTR)));
yaffs_trace(YAFFS_TRACE_ERROR,
"yaffs: Could not allocate Tnodes");
return YAFFS_FAIL;
}
@ -175,12 +173,10 @@ static int yaffs_create_tnodes(struct yaffs_dev *dev, int n_tnodes)
* NB If we can't add this to the management list it isn't fatal
* but it just means we can't free this bunch of tnodes later.
*/
tnl = YMALLOC(sizeof(struct yaffs_tnode_list));
tnl = kmalloc(sizeof(struct yaffs_tnode_list), GFP_NOFS);
if (!tnl) {
T(YAFFS_TRACE_ERROR,
(TSTR
("yaffs: Could not add tnodes to management list" TENDSTR)));
yaffs_trace(YAFFS_TRACE_ERROR,
"Could not add tnodes to management list");
return YAFFS_FAIL;
} else {
tnl->tnodes = new_tnodes;
@ -188,7 +184,7 @@ static int yaffs_create_tnodes(struct yaffs_dev *dev, int n_tnodes)
allocator->alloc_tnode_list = tnl;
}
T(YAFFS_TRACE_ALLOCATE, (TSTR("yaffs: Tnodes added" TENDSTR)));
yaffs_trace(YAFFS_TRACE_ALLOCATE, "Tnodes added");
return YAFFS_OK;
}
@ -243,8 +239,9 @@ static void yaffs_init_raw_objs(struct yaffs_dev *dev)
allocator->allocated_obj_list = NULL;
allocator->free_objs = NULL;
allocator->n_free_objects = 0;
} else
} else {
YBUG();
}
}
static void yaffs_deinit_raw_objs(struct yaffs_dev *dev)
@ -259,8 +256,8 @@ static void yaffs_deinit_raw_objs(struct yaffs_dev *dev)
while (allocator->allocated_obj_list) {
tmp = allocator->allocated_obj_list->next;
YFREE(allocator->allocated_obj_list->objects);
YFREE(allocator->allocated_obj_list);
kfree(allocator->allocated_obj_list->objects);
kfree(allocator->allocated_obj_list);
allocator->allocated_obj_list = tmp;
}
@ -273,7 +270,6 @@ static void yaffs_deinit_raw_objs(struct yaffs_dev *dev)
static int yaffs_create_free_objs(struct yaffs_dev *dev, int n_obj)
{
struct yaffs_allocator *allocator = dev->allocator;
int i;
struct yaffs_obj *new_objs;
struct yaffs_obj_list *list;
@ -287,20 +283,16 @@ static int yaffs_create_free_objs(struct yaffs_dev *dev, int n_obj)
return YAFFS_OK;
/* make these things */
new_objs = YMALLOC(n_obj * sizeof(struct yaffs_obj));
list = YMALLOC(sizeof(struct yaffs_obj_list));
new_objs = kmalloc(n_obj * sizeof(struct yaffs_obj), GFP_NOFS);
list = kmalloc(sizeof(struct yaffs_obj_list), GFP_NOFS);
if (!new_objs || !list) {
if (new_objs) {
YFREE(new_objs);
new_objs = NULL;
}
if (list) {
YFREE(list);
list = NULL;
}
T(YAFFS_TRACE_ALLOCATE,
(TSTR("yaffs: Could not allocate more objects" TENDSTR)));
kfree(new_objs);
new_objs = NULL;
kfree(list);
list = NULL;
yaffs_trace(YAFFS_TRACE_ALLOCATE,
"Could not allocate more objects");
return YAFFS_FAIL;
}
@ -369,10 +361,11 @@ void yaffs_deinit_raw_tnodes_and_objs(struct yaffs_dev *dev)
yaffs_deinit_raw_tnodes(dev);
yaffs_deinit_raw_objs(dev);
YFREE(dev->allocator);
kfree(dev->allocator);
dev->allocator = NULL;
} else
} else {
YBUG();
}
}
void yaffs_init_raw_tnodes_and_objs(struct yaffs_dev *dev)
@ -380,14 +373,15 @@ void yaffs_init_raw_tnodes_and_objs(struct yaffs_dev *dev)
struct yaffs_allocator *allocator;
if (!dev->allocator) {
allocator = YMALLOC(sizeof(struct yaffs_allocator));
allocator = kmalloc(sizeof(struct yaffs_allocator), GFP_NOFS);
if (allocator) {
dev->allocator = allocator;
yaffs_init_raw_tnodes(dev);
yaffs_init_raw_objs(dev);
}
} else
} else {
YBUG();
}
}
#endif

View File

@ -39,9 +39,9 @@ void yaffs_load_current_time(struct yaffs_obj *obj, int do_a, int do_c)
{
obj->yst_mtime = Y_CURRENT_TIME;
if (do_a)
obj->yst_atime = obj->yst_atime;
obj->yst_atime = obj->yst_mtime;
if (do_c)
obj->yst_ctime = obj->yst_atime;
obj->yst_ctime = obj->yst_mtime;
}
void yaffs_attribs_init(struct yaffs_obj *obj, u32 gid, u32 uid, u32 rdev)
@ -64,7 +64,7 @@ loff_t yaffs_get_file_size(struct yaffs_obj *obj)
alias = obj->variant.symlink_variant.alias;
if (!alias)
return 0;
return yaffs_strnlen(alias, YAFFS_MAX_ALIAS_LENGTH);
return strnlen(alias, YAFFS_MAX_ALIAS_LENGTH);
default:
return 0;
}

View File

@ -17,12 +17,12 @@
* Chunk bitmap manipulations
*/
static Y_INLINE u8 *yaffs_block_bits(struct yaffs_dev *dev, int blk)
static inline u8 *yaffs_block_bits(struct yaffs_dev *dev, int blk)
{
if (blk < dev->internal_start_block || blk > dev->internal_end_block) {
T(YAFFS_TRACE_ERROR,
(TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR),
blk));
yaffs_trace(YAFFS_TRACE_ERROR,
"BlockBits block %d is not valid",
blk);
YBUG();
}
return dev->chunk_bits +
@ -33,9 +33,9 @@ void yaffs_verify_chunk_bit_id(struct yaffs_dev *dev, int blk, int chunk)
{
if (blk < dev->internal_start_block || blk > dev->internal_end_block ||
chunk < 0 || chunk >= dev->param.chunks_per_block) {
T(YAFFS_TRACE_ERROR,
(TSTR("**>> yaffs: Chunk Id (%d:%d) invalid" TENDSTR),
blk, chunk));
yaffs_trace(YAFFS_TRACE_ERROR,
"Chunk Id (%d:%d) invalid",
blk, chunk);
YBUG();
}
}
@ -52,7 +52,6 @@ void yaffs_clear_chunk_bit(struct yaffs_dev *dev, int blk, int chunk)
u8 *blk_bits = yaffs_block_bits(dev, blk);
yaffs_verify_chunk_bit_id(dev, blk, chunk);
blk_bits[chunk / 8] &= ~(1 << (chunk & 7));
}
@ -61,15 +60,14 @@ void yaffs_set_chunk_bit(struct yaffs_dev *dev, int blk, int chunk)
u8 *blk_bits = yaffs_block_bits(dev, blk);
yaffs_verify_chunk_bit_id(dev, blk, chunk);
blk_bits[chunk / 8] |= (1 << (chunk & 7));
}
int yaffs_check_chunk_bit(struct yaffs_dev *dev, int blk, int chunk)
{
u8 *blk_bits = yaffs_block_bits(dev, blk);
yaffs_verify_chunk_bit_id(dev, blk, chunk);
yaffs_verify_chunk_bit_id(dev, blk, chunk);
return (blk_bits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0;
}
@ -77,6 +75,7 @@ int yaffs_still_some_chunks(struct yaffs_dev *dev, int blk)
{
u8 *blk_bits = yaffs_block_bits(dev, blk);
int i;
for (i = 0; i < dev->chunk_bit_stride; i++) {
if (*blk_bits)
return 1;
@ -90,15 +89,9 @@ int yaffs_count_chunk_bits(struct yaffs_dev *dev, int blk)
u8 *blk_bits = yaffs_block_bits(dev, blk);
int i;
int n = 0;
for (i = 0; i < dev->chunk_bit_stride; i++) {
u8 x = *blk_bits;
while (x) {
if (x & 1)
n++;
x >>= 1;
}
blk_bits++;
}
for (i = 0; i < dev->chunk_bit_stride; i++, blk_bits++)
n += hweight8(*blk_bits);
return n;
}

View File

@ -18,8 +18,8 @@ static int yaffs2_checkpt_space_ok(struct yaffs_dev *dev)
{
int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks;
T(YAFFS_TRACE_CHECKPOINT,
(TSTR("checkpt blocks available = %d" TENDSTR), blocks_avail));
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"checkpt blocks_avail = %d", blocks_avail);
return (blocks_avail <= 0) ? 0 : 1;
}
@ -30,21 +30,21 @@ static int yaffs_checkpt_erase(struct yaffs_dev *dev)
if (!dev->param.erase_fn)
return 0;
T(YAFFS_TRACE_CHECKPOINT, (TSTR("checking blocks %d to %d" TENDSTR),
dev->internal_start_block,
dev->internal_end_block));
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"checking blocks %d to %d",
dev->internal_start_block, dev->internal_end_block);
for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
struct yaffs_block_info *bi = yaffs_get_block_info(dev, i);
if (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT) {
T(YAFFS_TRACE_CHECKPOINT,
(TSTR("erasing checkpt block %d" TENDSTR), i));
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"erasing checkpt block %d", i);
dev->n_erasures++;
if (dev->param.
erase_fn(dev,
i - dev->block_offset /* realign */ )) {
i - dev->block_offset /* realign */)) {
bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
dev->n_erased_blocks++;
dev->n_free_chunks +=
@ -65,11 +65,11 @@ static void yaffs2_checkpt_find_erased_block(struct yaffs_dev *dev)
{
int i;
int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks;
T(YAFFS_TRACE_CHECKPOINT,
(TSTR
("allocating checkpt block: erased %d reserved %d avail %d next %d "
TENDSTR), dev->n_erased_blocks, dev->param.n_reserved_blocks,
blocks_avail, dev->checkpt_next_block));
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"allocating checkpt block: erased %d reserved %d avail %d next %d ",
dev->n_erased_blocks, dev->param.n_reserved_blocks,
blocks_avail, dev->checkpt_next_block);
if (dev->checkpt_next_block >= 0 &&
dev->checkpt_next_block <= dev->internal_end_block &&
@ -82,14 +82,13 @@ static void yaffs2_checkpt_find_erased_block(struct yaffs_dev *dev)
if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) {
dev->checkpt_next_block = i + 1;
dev->checkpt_cur_block = i;
T(YAFFS_TRACE_CHECKPOINT,
(TSTR("allocating checkpt block %d" TENDSTR),
i));
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"allocating checkpt block %d", i);
return;
}
}
}
T(YAFFS_TRACE_CHECKPOINT, (TSTR("out of checkpt blocks" TENDSTR)));
yaffs_trace(YAFFS_TRACE_CHECKPOINT, "out of checkpt blocks");
dev->checkpt_next_block = -1;
dev->checkpt_cur_block = -1;
@ -100,9 +99,9 @@ static void yaffs2_checkpt_find_block(struct yaffs_dev *dev)
int i;
struct yaffs_ext_tags tags;
T(YAFFS_TRACE_CHECKPOINT,
(TSTR("find next checkpt block: start: blocks %d next %d" TENDSTR),
dev->blocks_in_checkpt, dev->checkpt_next_block));
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"find next checkpt block: start: blocks %d next %d",
dev->blocks_in_checkpt, dev->checkpt_next_block);
if (dev->blocks_in_checkpt < dev->checkpt_max_blocks)
for (i = dev->checkpt_next_block; i <= dev->internal_end_block;
@ -112,11 +111,10 @@ static void yaffs2_checkpt_find_block(struct yaffs_dev *dev)
dev->param.read_chunk_tags_fn(dev, realigned_chunk,
NULL, &tags);
T(YAFFS_TRACE_CHECKPOINT,
(TSTR
("find next checkpt block: search: block %d oid %d seq %d eccr %d"
TENDSTR), i, tags.obj_id, tags.seq_number,
tags.ecc_result));
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"find next checkpt block: search: block %d oid %d seq %d eccr %d",
i, tags.obj_id, tags.seq_number,
tags.ecc_result);
if (tags.seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA) {
/* Right kind of block */
@ -125,14 +123,13 @@ static void yaffs2_checkpt_find_block(struct yaffs_dev *dev)
dev->checkpt_block_list[dev->
blocks_in_checkpt] = i;
dev->blocks_in_checkpt++;
T(YAFFS_TRACE_CHECKPOINT,
(TSTR("found checkpt block %d" TENDSTR), i));
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"found checkpt block %d", i);
return;
}
}
T(YAFFS_TRACE_CHECKPOINT,
(TSTR("found no more checkpt blocks" TENDSTR)));
yaffs_trace(YAFFS_TRACE_CHECKPOINT, "found no more checkpt blocks");
dev->checkpt_next_block = -1;
dev->checkpt_cur_block = -1;
@ -140,7 +137,6 @@ static void yaffs2_checkpt_find_block(struct yaffs_dev *dev)
int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing)
{
dev->checkpt_open_write = writing;
/* Got the functions we need? */
@ -154,7 +150,7 @@ int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing)
if (!dev->checkpt_buffer)
dev->checkpt_buffer =
YMALLOC_DMA(dev->param.total_bytes_per_chunk);
kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS);
if (!dev->checkpt_buffer)
return 0;
@ -175,14 +171,14 @@ int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing)
int i;
/* Set to a value that will kick off a read */
dev->checkpt_byte_offs = dev->data_bytes_per_chunk;
/* A checkpoint block list of 1 checkpoint block per 16 block is (hopefully)
* going to be way more than we need */
/* A checkpoint block list of 1 checkpoint block per 16 block is
* (hopefully) going to be way more than we need */
dev->blocks_in_checkpt = 0;
dev->checkpt_max_blocks =
(dev->internal_end_block - dev->internal_start_block) / 16 +
2;
dev->checkpt_block_list =
YMALLOC(sizeof(int) * dev->checkpt_max_blocks);
kmalloc(sizeof(int) * dev->checkpt_max_blocks, GFP_NOFS);
if (!dev->checkpt_block_list)
return 0;
@ -196,6 +192,7 @@ int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing)
int yaffs2_get_checkpt_sum(struct yaffs_dev *dev, u32 * sum)
{
u32 composite_sum;
composite_sum = (dev->checkpt_sum << 8) | (dev->checkpt_xor & 0xFF);
*sum = composite_sum;
return 1;
@ -205,7 +202,6 @@ static int yaffs2_checkpt_flush_buffer(struct yaffs_dev *dev)
{
int chunk;
int realigned_chunk;
struct yaffs_ext_tags tags;
if (dev->checkpt_cur_block < 0) {
@ -234,11 +230,10 @@ static int yaffs2_checkpt_flush_buffer(struct yaffs_dev *dev)
dev->checkpt_cur_block * dev->param.chunks_per_block +
dev->checkpt_cur_chunk;
T(YAFFS_TRACE_CHECKPOINT,
(TSTR
("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR),
chunk, dev->checkpt_cur_block, dev->checkpt_cur_chunk, tags.obj_id,
tags.chunk_id));
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"checkpoint wite buffer nand %d(%d:%d) objid %d chId %d",
chunk, dev->checkpt_cur_block, dev->checkpt_cur_chunk,
tags.obj_id, tags.chunk_id);
realigned_chunk = chunk - dev->chunk_offset;
@ -262,7 +257,6 @@ int yaffs2_checkpt_wr(struct yaffs_dev *dev, const void *data, int n_bytes)
{
int i = 0;
int ok = 1;
u8 *data_bytes = (u8 *) data;
if (!dev->checkpt_buffer)
@ -294,10 +288,8 @@ int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes)
int i = 0;
int ok = 1;
struct yaffs_ext_tags tags;
int chunk;
int realigned_chunk;
u8 *data_bytes = (u8 *) data;
if (!dev->checkpt_buffer)
@ -329,10 +321,9 @@ int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes)
/* read in the next chunk */
dev->param.read_chunk_tags_fn(dev,
realigned_chunk,
dev->
checkpt_buffer,
&tags);
realigned_chunk,
dev->checkpt_buffer,
&tags);
if (tags.chunk_id != (dev->checkpt_page_seq + 1)
|| tags.ecc_result > YAFFS_ECC_RESULT_FIXED
@ -367,7 +358,6 @@ int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes)
int yaffs_checkpt_close(struct yaffs_dev *dev)
{
if (dev->checkpt_open_write) {
if (dev->checkpt_byte_offs != 0)
yaffs2_checkpt_flush_buffer(dev);
@ -383,11 +373,8 @@ int yaffs_checkpt_close(struct yaffs_dev *dev)
bi = yaffs_get_block_info(dev, blk);
if (bi && bi->block_state == YAFFS_BLOCK_STATE_EMPTY)
bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT;
else {
/* Todo this looks odd... */
}
}
YFREE(dev->checkpt_block_list);
kfree(dev->checkpt_block_list);
dev->checkpt_block_list = NULL;
}
@ -395,25 +382,26 @@ int yaffs_checkpt_close(struct yaffs_dev *dev)
dev->blocks_in_checkpt * dev->param.chunks_per_block;
dev->n_erased_blocks -= dev->blocks_in_checkpt;
T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint byte count %d" TENDSTR),
dev->checkpt_byte_count));
yaffs_trace(YAFFS_TRACE_CHECKPOINT, "checkpoint byte count %d",
dev->checkpt_byte_count);
if (dev->checkpt_buffer) {
/* free the buffer */
YFREE(dev->checkpt_buffer);
kfree(dev->checkpt_buffer);
dev->checkpt_buffer = NULL;
return 1;
} else
} else {
return 0;
}
}
int yaffs2_checkpt_invalidate_stream(struct yaffs_dev *dev)
{
/* Erase the checkpoint data */
T(YAFFS_TRACE_CHECKPOINT,
(TSTR("checkpoint invalidate of %d blocks" TENDSTR),
dev->blocks_in_checkpt));
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"checkpoint invalidate of %d blocks",
dev->blocks_in_checkpt);
return yaffs_checkpt_erase(dev);
}

View File

@ -16,16 +16,16 @@
*
* The ECC comprises 22 bits of parity information and is stuffed into 3 bytes.
* The two unused bit are set to 1.
* The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC
* blocks are used on a 512-byte NAND page.
* The ECC can correct single bit errors in a 256-byte page of data. Thus, two
* such ECC blocks are used on a 512-byte NAND page.
*
*/
/* Table generated by gen-ecc.c
* Using a table means we do not have to calculate p1..p4 and p1'..p4'
* for each byte of data. These are instead provided in a table in bits7..2.
* Bit 0 of each entry indicates whether the entry has an odd or even parity, and therefore
* this bytes influence on the line parity.
* Bit 0 of each entry indicates whether the entry has an odd or even parity,
* and therefore this bytes influence on the line parity.
*/
#include "yportenv.h"
@ -67,35 +67,11 @@ static const unsigned char column_parity_table[] = {
0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
};
/* Count the bits in an unsigned char or a U32 */
static int yaffs_count_bits(unsigned char x)
{
int r = 0;
while (x) {
if (x & 1)
r++;
x >>= 1;
}
return r;
}
static int yaffs_count_bits32(unsigned x)
{
int r = 0;
while (x) {
if (x & 1)
r++;
x >>= 1;
}
return r;
}
/* Calculate the ECC for a 256-byte block of data */
void yaffs_ecc_cacl(const unsigned char *data, unsigned char *ecc)
{
unsigned int i;
unsigned char col_parity = 0;
unsigned char line_parity = 0;
unsigned char line_parity_prime = 0;
@ -222,8 +198,7 @@ int yaffs_ecc_correct(unsigned char *data, unsigned char *read_ecc,
return 1; /* Corrected the error */
}
if ((yaffs_count_bits(d0) +
yaffs_count_bits(d1) + yaffs_count_bits(d2)) == 1) {
if ((hweight8(d0) + hweight8(d1) + hweight8(d2)) == 1) {
/* Reccoverable error in ecc */
read_ecc[0] = test_ecc[0];
@ -246,7 +221,6 @@ void yaffs_ecc_calc_other(const unsigned char *data, unsigned n_bytes,
struct yaffs_ecc_other *ecc_other)
{
unsigned int i;
unsigned char col_parity = 0;
unsigned line_parity = 0;
unsigned line_parity_prime = 0;
@ -307,9 +281,9 @@ int yaffs_ecc_correct_other(unsigned char *data, unsigned n_bytes,
return 1; /* corrected */
}
if ((yaffs_count_bits32(delta_line) +
yaffs_count_bits32(delta_line_prime) +
yaffs_count_bits(delta_col)) == 1) {
if ((hweight32(delta_line) +
hweight32(delta_line_prime) +
hweight8(delta_col)) == 1) {
/* Reccoverable error in ecc */
*read_ecc = *test_ecc;

View File

@ -18,8 +18,8 @@
*
* The ECC comprises 22 bits of parity information and is stuffed into 3 bytes.
* The two unused bit are set to 1.
* The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC
* blocks are used on a 512-byte NAND page.
* The ECC can correct single bit errors in a 256-byte page of data.
* Thus, two such ECC blocks are used on a 512-byte NAND page.
*
*/

View File

@ -20,14 +20,13 @@
#include "yaffs_trace.h"
/* Function to manipulate block info */
static Y_INLINE struct yaffs_block_info *yaffs_get_block_info(struct yaffs_dev
static inline struct yaffs_block_info *yaffs_get_block_info(struct yaffs_dev
*dev, int blk)
{
if (blk < dev->internal_start_block || blk > dev->internal_end_block) {
T(YAFFS_TRACE_ERROR,
(TSTR
("**>> yaffs: get_block_info block %d is not valid" TENDSTR),
blk));
yaffs_trace(YAFFS_TRACE_ERROR,
"**>> yaffs: get_block_info block %d is not valid",
blk);
YBUG();
}
return &dev->block_info[blk - dev->internal_start_block];

File diff suppressed because it is too large Load Diff

View File

@ -29,12 +29,12 @@
*/
#define YAFFS_MAGIC 0x5941FF53
#define YAFFS_NTNODES_LEVEL0 16
#define YAFFS_NTNODES_LEVEL0 16
#define YAFFS_TNODES_LEVEL0_BITS 4
#define YAFFS_TNODES_LEVEL0_MASK 0xf
#define YAFFS_NTNODES_INTERNAL (YAFFS_NTNODES_LEVEL0 / 2)
#define YAFFS_TNODES_INTERNAL_BITS (YAFFS_TNODES_LEVEL0_BITS - 1)
#define YAFFS_NTNODES_INTERNAL (YAFFS_NTNODES_LEVEL0 / 2)
#define YAFFS_TNODES_INTERNAL_BITS (YAFFS_TNODES_LEVEL0_BITS - 1)
#define YAFFS_TNODES_INTERNAL_MASK 0x7
#define YAFFS_TNODES_MAX_LEVEL 6
@ -43,10 +43,10 @@
#define YAFFS_BYTES_PER_CHUNK 512
#define YAFFS_CHUNK_SIZE_SHIFT 9
#define YAFFS_CHUNKS_PER_BLOCK 32
#define YAFFS_BYTES_PER_BLOCK (YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK)
#define YAFFS_BYTES_PER_BLOCK (YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK)
#endif
#define YAFFS_MIN_YAFFS2_CHUNK_SIZE 1024
#define YAFFS_MIN_YAFFS2_CHUNK_SIZE 1024
#define YAFFS_MIN_YAFFS2_SPARE_SIZE 32
#define YAFFS_MAX_CHUNK_ID 0x000FFFFF
@ -58,9 +58,9 @@
#define YAFFS_NOBJECT_BUCKETS 256
#define YAFFS_OBJECT_SPACE 0x40000
#define YAFFS_MAX_OBJECT_ID (YAFFS_OBJECT_SPACE -1)
#define YAFFS_MAX_OBJECT_ID (YAFFS_OBJECT_SPACE - 1)
#define YAFFS_CHECKPOINT_VERSION 4
#define YAFFS_CHECKPOINT_VERSION 4
#ifdef CONFIG_YAFFS_UNICODE
#define YAFFS_MAX_NAME_LENGTH 127
@ -97,7 +97,7 @@
* The range is limited slightly to help distinguish bad numbers from good.
* This also allows us to perhaps in the future use special numbers for
* special purposes.
* EFFFFF00 allows the allocation of 8 blocks per second (~1Mbytes) for 15 years,
* EFFFFF00 allows the allocation of 8 blocks/second (~1Mbytes) for 15 years,
* and is a larger number than the lifetime of a 2GB device.
*/
#define YAFFS_LOWEST_SEQUENCE_NUMBER 0x00001000
@ -118,8 +118,8 @@ struct yaffs_cache {
};
/* Tags structures in RAM
* NB This uses bitfield. Bitfields should not straddle a u32 boundary otherwise
* the structure size will get blown out.
* NB This uses bitfield. Bitfields should not straddle a u32 boundary
* otherwise the structure size will get blown out.
*/
#ifndef CONFIG_YAFFS_NO_YAFFS1
@ -163,8 +163,8 @@ struct yaffs_ext_tags {
unsigned validity0;
unsigned chunk_used; /* Status of the chunk: used or unused */
unsigned obj_id; /* If 0 then this is not part of an object (unused) */
unsigned chunk_id; /* If 0 then this is a header, else a data chunk */
unsigned obj_id; /* If 0 this is not used */
unsigned chunk_id; /* If 0 this is a header, else a data chunk */
unsigned n_bytes; /* Only valid for data chunks */
/* The following stuff only has meaning when we read */
@ -180,7 +180,7 @@ struct yaffs_ext_tags {
/* Extra info if this is an object header (YAFFS2 only) */
unsigned extra_available; /* There is extra info available if this is not zero */
unsigned extra_available; /* Extra info available if not zero */
unsigned extra_parent_id; /* The parent object */
unsigned extra_is_shrink; /* Is it a shrink header? */
unsigned extra_shadows; /* Does this shadow another object? */
@ -188,7 +188,7 @@ struct yaffs_ext_tags {
enum yaffs_obj_type extra_obj_type; /* What object type? */
unsigned extra_length; /* Length if it is a file */
unsigned extra_equiv_id; /* Equivalent object Id if it is a hard link */
unsigned extra_equiv_id; /* Equivalent object for a hard link */
unsigned validity1;
@ -226,11 +226,14 @@ enum yaffs_block_state {
/* Being scanned */
YAFFS_BLOCK_STATE_NEEDS_SCANNING,
/* The block might have something on it (ie it is allocating or full, perhaps empty)
* but it needs to be scanned to determine its true state.
/* The block might have something on it (ie it is allocating or full,
* perhaps empty) but it needs to be scanned to determine its true
* state.
* This state is only valid during scanning.
* NB We tolerate empty because the pre-scanner might be incapable of deciding
* However, if this state is returned on a YAFFS2 device, then we expect a sequence number
* NB We tolerate empty because the pre-scanner might be incapable of
* deciding
* However, if this state is returned on a YAFFS2 device,
* then we expect a sequence number
*/
YAFFS_BLOCK_STATE_EMPTY,
@ -241,7 +244,8 @@ enum yaffs_block_state {
* At least one page holds valid data.
* This is the one currently being used for page
* allocation. Should never be more than one of these.
* If a block is only partially allocated at mount it is treated as full.
* If a block is only partially allocated at mount it is treated as
* full.
*/
YAFFS_BLOCK_STATE_FULL,
@ -271,16 +275,19 @@ struct yaffs_block_info {
int soft_del_pages:10; /* number of soft deleted pages */
int pages_in_use:10; /* number of pages in use */
unsigned block_state:4; /* One of the above block states. NB use unsigned because enum is sometimes an int */
u32 needs_retiring:1; /* Data has failed on this block, need to get valid data off */
/* and retire the block. */
u32 skip_erased_check:1; /* If this is set we can skip the erased check on this block */
u32 gc_prioritise:1; /* An ECC check or blank check has failed on this block.
It should be prioritised for GC */
u32 chunk_error_strikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */
unsigned block_state:4; /* One of the above block states. */
/* NB use unsigned because enum is sometimes
* an int */
u32 needs_retiring:1; /* Data has failed on this block, */
/*need to get valid data off and retire*/
u32 skip_erased_check:1;/* Skip the erased check on this block */
u32 gc_prioritise:1; /* An ECC check or blank check has failed.
Block should be prioritised for GC */
u32 chunk_error_strikes:3; /* How many times we've had ecc etc
failures on this block and tried to reuse it */
#ifdef CONFIG_YAFFS_YAFFS2
u32 has_shrink_hdr:1; /* This block has at least one shrink object header */
u32 has_shrink_hdr:1; /* This block has at least one shrink header */
u32 seq_number; /* block sequence number for yaffs2 */
#endif
@ -297,7 +304,7 @@ struct yaffs_obj_hdr {
u16 sum_no_longer_used; /* checksum of name. No longer used */
YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
/* The following apply to directories, files, symlinks - not hard links */
/* The following apply to all object types except for hard links */
u32 yst_mode; /* protection */
u32 yst_uid;
@ -315,7 +322,7 @@ struct yaffs_obj_hdr {
/* Alias is for symlinks only. */
YCHAR alias[YAFFS_MAX_ALIAS_LENGTH + 1];
u32 yst_rdev; /* device stuff for block and char devices (major/min) */
u32 yst_rdev; /* stuff for block and char devices (major/min) */
u32 win_ctime[2];
u32 win_atime[2];
@ -325,9 +332,10 @@ struct yaffs_obj_hdr {
u32 inband_is_shrink;
u32 reserved[2];
int shadows_obj; /* This object header shadows the specified object if > 0 */
int shadows_obj; /* This object header shadows the
specified object if > 0 */
/* is_shrink applies to object headers written when we shrink the file (ie resize) */
/* is_shrink applies to object headers written when wemake a hole. */
u32 is_shrink;
};
@ -378,35 +386,43 @@ union yaffs_obj_var {
struct yaffs_obj {
u8 deleted:1; /* This should only apply to unlinked files. */
u8 soft_del:1; /* it has also been soft deleted */
u8 unlinked:1; /* An unlinked file. The file should be in the unlinked directory. */
u8 unlinked:1; /* An unlinked file.*/
u8 fake:1; /* A fake object has no presence on NAND. */
u8 rename_allowed:1; /* Some objects are not allowed to be renamed. */
u8 rename_allowed:1; /* Some objects cannot be renamed. */
u8 unlink_allowed:1;
u8 dirty:1; /* the object needs to be written to flash */
u8 valid:1; /* When the file system is being loaded up, this
* object might be created before the data
* is available (ie. file data records appear before the header).
* is available
* ie. file data chunks encountered before
* the header.
*/
u8 lazy_loaded:1; /* This object has been lazy loaded and is missing some detail */
u8 lazy_loaded:1; /* This object has been lazy loaded and
* is missing some detail */
u8 defered_free:1; /* For Linux kernel. Object is removed from NAND, but is
* still in the inode cache. Free of object is defered.
u8 defered_free:1; /* Object is removed from NAND, but is
* still in the inode cache.
* Free of object is defered.
* until the inode is released.
*/
u8 being_created:1; /* This object is still being created so skip some checks. */
u8 is_shadowed:1; /* This object is shadowed on the way to being renamed. */
u8 being_created:1; /* This object is still being created
* so skip some verification checks. */
u8 is_shadowed:1; /* This object is shadowed on the way
* to being renamed. */
u8 xattr_known:1; /* We know if this has object has xattribs or not. */
u8 has_xattr:1; /* This object has xattribs. Valid if xattr_known. */
u8 xattr_known:1; /* We know if this has object has xattribs
* or not. */
u8 has_xattr:1; /* This object has xattribs.
* Only valid if xattr_known. */
u8 serial; /* serial number of chunk in NAND. Cached here */
u8 serial; /* serial number of chunk in NAND.*/
u16 sum; /* sum of the name to speed searching */
struct yaffs_dev *my_dev; /* The device I'm on */
struct list_head hash_link; /* list of objects in this hash bucket */
struct list_head hash_link; /* list of objects in hash bucket */
struct list_head hard_links; /* all the equivalent hard linked objects */
struct list_head hard_links; /* hard linked object chain*/
/* directory structure stuff */
/* also used for linking up the free list */
@ -416,13 +432,13 @@ struct yaffs_obj {
/* Where's my object header in NAND? */
int hdr_chunk;
int n_data_chunks; /* Number of data chunks attached to the file. */
int n_data_chunks; /* Number of data chunks for this file. */
u32 obj_id; /* the object id value */
u32 yst_mode;
#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
#ifndef CONFIG_YAFFS_NO_SHORT_NAMES
YCHAR short_name[YAFFS_SHORT_NAME_LENGTH + 1];
#endif
@ -481,7 +497,7 @@ struct yaffs_checkpt_obj {
struct yaffs_buffer {
u8 *buffer;
int line; /* track from whence this buffer was allocated */
int line; /* track from whence this buffer was allocated */
int max_line;
};
@ -497,26 +513,28 @@ struct yaffs_param {
*/
int inband_tags; /* Use unband tags */
u32 total_bytes_per_chunk; /* Should be >= 512, does not need to be a power of 2 */
u32 total_bytes_per_chunk; /* Should be >= 512, does not need to
be a power of 2 */
int chunks_per_block; /* does not need to be a power of 2 */
int spare_bytes_per_chunk; /* spare area size */
int start_block; /* Start block we're allowed to use */
int end_block; /* End block we're allowed to use */
int n_reserved_blocks; /* We want this tuneable so that we can reduce */
/* reserved blocks on NOR and RAM. */
int n_reserved_blocks; /* Tuneable so that we can reduce
* reserved blocks on NOR and RAM. */
int n_caches; /* If <= 0, then short op caching is disabled, else
* the number of short op caches (don't use too many).
* 10 to 20 is a good bet.
int n_caches; /* If <= 0, then short op caching is disabled,
* else the number of short op caches.
*/
int use_nand_ecc; /* Flag to decide whether or not to use NANDECC on data (yaffs1) */
int no_tags_ecc; /* Flag to decide whether or not to do ECC on packed tags (yaffs2) */
int use_nand_ecc; /* Flag to decide whether or not to use
* NAND driver ECC on data (yaffs1) */
int no_tags_ecc; /* Flag to decide whether or not to do ECC
* on packed tags (yaffs2) */
int is_yaffs2; /* Use yaffs2 mode on this device */
int empty_lost_n_found; /* Auto-empty lost+found directory on mount */
int refresh_period; /* How often we should check to do a block refresh */
int refresh_period; /* How often to check for a block refresh */
/* Checkpoint control. Can be set before or after initialisation */
u8 skip_checkpt_rd;
@ -526,27 +544,27 @@ struct yaffs_param {
/* NAND access functions (Must be set before calling YAFFS) */
int (*write_chunk_fn) (struct yaffs_dev * dev,
int nand_chunk, const u8 * data,
const struct yaffs_spare * spare);
int (*read_chunk_fn) (struct yaffs_dev * dev,
int nand_chunk, u8 * data,
struct yaffs_spare * spare);
int (*erase_fn) (struct yaffs_dev * dev, int flash_block);
int (*initialise_flash_fn) (struct yaffs_dev * dev);
int (*deinitialise_flash_fn) (struct yaffs_dev * dev);
int (*write_chunk_fn) (struct yaffs_dev *dev,
int nand_chunk, const u8 *data,
const struct yaffs_spare *spare);
int (*read_chunk_fn) (struct yaffs_dev *dev,
int nand_chunk, u8 *data,
struct yaffs_spare *spare);
int (*erase_fn) (struct yaffs_dev *dev, int flash_block);
int (*initialise_flash_fn) (struct yaffs_dev *dev);
int (*deinitialise_flash_fn) (struct yaffs_dev *dev);
#ifdef CONFIG_YAFFS_YAFFS2
int (*write_chunk_tags_fn) (struct yaffs_dev * dev,
int nand_chunk, const u8 * data,
const struct yaffs_ext_tags * tags);
int (*read_chunk_tags_fn) (struct yaffs_dev * dev,
int nand_chunk, u8 * data,
struct yaffs_ext_tags * tags);
int (*bad_block_fn) (struct yaffs_dev * dev, int block_no);
int (*query_block_fn) (struct yaffs_dev * dev, int block_no,
enum yaffs_block_state * state,
u32 * seq_number);
int (*write_chunk_tags_fn) (struct yaffs_dev *dev,
int nand_chunk, const u8 *data,
const struct yaffs_ext_tags *tags);
int (*read_chunk_tags_fn) (struct yaffs_dev *dev,
int nand_chunk, u8 *data,
struct yaffs_ext_tags *tags);
int (*bad_block_fn) (struct yaffs_dev *dev, int block_no);
int (*query_block_fn) (struct yaffs_dev *dev, int block_no,
enum yaffs_block_state *state,
u32 *seq_number);
#endif
/* The remove_obj_fn function must be supplied by OS flavours that
@ -554,19 +572,21 @@ struct yaffs_param {
* yaffs direct uses it to implement the faster readdir.
* Linux uses it to protect the directory during unlocking.
*/
void (*remove_obj_fn) (struct yaffs_obj * obj);
void (*remove_obj_fn) (struct yaffs_obj *obj);
/* Callback to mark the superblock dirty */
void (*sb_dirty_fn) (struct yaffs_dev * dev);
void (*sb_dirty_fn) (struct yaffs_dev *dev);
/* Callback to control garbage collection. */
unsigned (*gc_control) (struct yaffs_dev * dev);
unsigned (*gc_control) (struct yaffs_dev *dev);
/* Debug control flags. Don't use unless you know what you're doing */
int use_header_file_size; /* Flag to determine if we should use file sizes from the header */
int use_header_file_size; /* Flag to determine if we should use
* file sizes from the header */
int disable_lazy_load; /* Disable lazy loading on this device */
int wide_tnodes_disabled; /* Set to disable wide tnodes */
int disable_soft_del; /* yaffs 1 only: Set to disable the use of softdeletion. */
int disable_soft_del; /* yaffs 1 only: Set to disable the use of
* softdeletion. */
int defered_dir_update; /* Set to defer directory updates */
@ -602,7 +622,7 @@ struct yaffs_dev {
/* Stuff for figuring out file offset to chunk conversions */
u32 chunk_shift; /* Shift value */
u32 chunk_div; /* Divisor after shifting: 1 for power-of-2 sizes */
u32 chunk_div; /* Divisor after shifting: 1 for 2^n sizes */
u32 chunk_mask; /* Mask to use for power-of-2 case */
int is_mounted;
@ -616,7 +636,7 @@ struct yaffs_dev {
int chunk_offset;
/* Runtime checkpointing stuff */
int checkpt_page_seq; /* running sequence number of checkpoint pages */
int checkpt_page_seq; /* running sequence number of checkpt pages */
int checkpt_byte_count;
int checkpt_byte_offs;
u8 *checkpt_buffer;
@ -630,13 +650,14 @@ struct yaffs_dev {
u32 checkpt_sum;
u32 checkpt_xor;
int checkpoint_blocks_required; /* Number of blocks needed to store current checkpoint set */
int checkpoint_blocks_required; /* Number of blocks needed to store
* current checkpoint set */
/* Block Info */
struct yaffs_block_info *block_info;
u8 *chunk_bits; /* bitmap of chunks in use */
unsigned block_info_alt:1; /* was allocated using alternative strategy */
unsigned chunk_bits_alt:1; /* was allocated using alternative strategy */
unsigned block_info_alt:1; /* allocated using alternative alloc */
unsigned chunk_bits_alt:1; /* allocated using alternative alloc */
int chunk_bit_stride; /* Number of bytes of chunk_bits per block.
* Must be consistent with chunks_per_block.
*/
@ -662,7 +683,8 @@ struct yaffs_dev {
u32 *gc_cleanup_list; /* objects to delete at the end of a GC. */
u32 n_clean_ups;
unsigned has_pending_prioritised_gc; /* We think this device might have pending prioritised gcs */
unsigned has_pending_prioritised_gc; /* We think this device might
have pending prioritised gcs */
unsigned gc_disable;
unsigned gc_block_finder;
unsigned gc_dirtiest;
@ -676,11 +698,6 @@ struct yaffs_dev {
struct yaffs_obj *root_dir;
struct yaffs_obj *lost_n_found;
/* Buffer areas for storing data to recover from write failures TODO
* u8 buffered_data[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK];
* struct yaffs_spare buffered_spare[YAFFS_CHUNKS_PER_BLOCK];
*/
int buffered_block; /* Which block is buffered here? */
int doing_buffered_block_rewrite;
@ -688,9 +705,12 @@ struct yaffs_dev {
int cache_last_use;
/* Stuff for background deletion and unlinked files. */
struct yaffs_obj *unlinked_dir; /* Directory where unlinked and deleted files live. */
struct yaffs_obj *del_dir; /* Directory where deleted objects are sent to disappear. */
struct yaffs_obj *unlinked_deletion; /* Current file being background deleted. */
struct yaffs_obj *unlinked_dir; /* Directory where unlinked and deleted
files live. */
struct yaffs_obj *del_dir; /* Directory where deleted objects are
sent to disappear. */
struct yaffs_obj *unlinked_deletion; /* Current file being
background deleted. */
int n_deleted_files; /* Count of files awaiting deletion; */
int n_unlinked_files; /* Count of unlinked files. */
int n_bg_deletions; /* Count of background deletions. */
@ -703,12 +723,14 @@ struct yaffs_dev {
int unmanaged_buffer_deallocs;
/* yaffs2 runtime stuff */
unsigned seq_number; /* Sequence number of currently allocating block */
unsigned seq_number; /* Sequence number of currently
allocating block */
unsigned oldest_dirty_seq;
unsigned oldest_dirty_block;
/* Block refreshing */
int refresh_skip; /* A skip down counter. Refresh happens when this gets to zero. */
int refresh_skip; /* A skip down counter.
* Refresh happens when this gets to zero. */
/* Dirty directory handling */
struct list_head dirty_dirs; /* List of dirty directories */
@ -737,8 +759,8 @@ struct yaffs_dev {
};
/* The CheckpointDevice structure holds the device information that changes at runtime and
* must be preserved over unmount/mount cycles.
/* The CheckpointDevice structure holds the device information that changes
*at runtime and must be preserved over unmount/mount cycles.
*/
struct yaffs_checkpt_dev {
int struct_type;
@ -752,7 +774,8 @@ struct yaffs_checkpt_dev {
int n_bg_deletions; /* Count of background deletions. */
/* yaffs2 runtime stuff */
unsigned seq_number; /* Sequence number of currently allocating block */
unsigned seq_number; /* Sequence number of currently
* allocating block */
};
@ -806,7 +829,7 @@ int yaffs_wr_file(struct yaffs_obj *obj, const u8 * buffer, loff_t offset,
int yaffs_resize_file(struct yaffs_obj *obj, loff_t new_size);
struct yaffs_obj *yaffs_create_file(struct yaffs_obj *parent,
const YCHAR * name, u32 mode, u32 uid,
const YCHAR *name, u32 mode, u32 uid,
u32 gid);
int yaffs_flush_file(struct yaffs_obj *obj, int update_time, int data_sync);
@ -818,35 +841,35 @@ int yaffs_checkpoint_save(struct yaffs_dev *dev);
int yaffs_checkpoint_restore(struct yaffs_dev *dev);
/* Directory operations */
struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR * name,
struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR *name,
u32 mode, u32 uid, u32 gid);
struct yaffs_obj *yaffs_find_by_name(struct yaffs_obj *the_dir,
const YCHAR * name);
const YCHAR *name);
struct yaffs_obj *yaffs_find_by_number(struct yaffs_dev *dev, u32 number);
/* Link operations */
struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR * name,
struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR *name,
struct yaffs_obj *equiv_obj);
struct yaffs_obj *yaffs_get_equivalent_obj(struct yaffs_obj *obj);
/* Symlink operations */
struct yaffs_obj *yaffs_create_symlink(struct yaffs_obj *parent,
const YCHAR * name, u32 mode, u32 uid,
u32 gid, const YCHAR * alias);
const YCHAR *name, u32 mode, u32 uid,
u32 gid, const YCHAR *alias);
YCHAR *yaffs_get_symlink_alias(struct yaffs_obj *obj);
/* Special inodes (fifos, sockets and devices) */
struct yaffs_obj *yaffs_create_special(struct yaffs_obj *parent,
const YCHAR * name, u32 mode, u32 uid,
const YCHAR *name, u32 mode, u32 uid,
u32 gid, u32 rdev);
int yaffs_set_xattrib(struct yaffs_obj *obj, const YCHAR * name,
int yaffs_set_xattrib(struct yaffs_obj *obj, const YCHAR *name,
const void *value, int size, int flags);
int yaffs_get_xattrib(struct yaffs_obj *obj, const YCHAR * name, void *value,
int yaffs_get_xattrib(struct yaffs_obj *obj, const YCHAR *name, void *value,
int size);
int yaffs_list_xattrib(struct yaffs_obj *obj, char *buffer, int size);
int yaffs_remove_xattrib(struct yaffs_obj *obj, const YCHAR * name);
int yaffs_remove_xattrib(struct yaffs_obj *obj, const YCHAR *name);
/* Special directories */
struct yaffs_obj *yaffs_root(struct yaffs_dev *dev);
@ -866,26 +889,26 @@ void yaffs_guts_test(struct yaffs_dev *dev);
/* A few useful functions to be used within the core files*/
void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash,
int lyn);
int yaffs_check_ff(u8 * buffer, int n_bytes);
int yaffs_check_ff(u8 *buffer, int n_bytes);
void yaffs_handle_chunk_error(struct yaffs_dev *dev,
struct yaffs_block_info *bi);
u8 *yaffs_get_temp_buffer(struct yaffs_dev *dev, int line_no);
void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 * buffer, int line_no);
void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer, int line_no);
struct yaffs_obj *yaffs_find_or_create_by_number(struct yaffs_dev *dev,
int number,
enum yaffs_obj_type type);
int yaffs_put_chunk_in_file(struct yaffs_obj *in, int inode_chunk,
int nand_chunk, int in_scan);
void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR * name);
void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR *name);
void yaffs_set_obj_name_from_oh(struct yaffs_obj *obj,
const struct yaffs_obj_hdr *oh);
void yaffs_add_obj_to_dir(struct yaffs_obj *directory, struct yaffs_obj *obj);
YCHAR *yaffs_clone_str(const YCHAR * str);
YCHAR *yaffs_clone_str(const YCHAR *str);
void yaffs_link_fixup(struct yaffs_dev *dev, struct yaffs_obj *hard_list);
void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no);
int yaffs_update_oh(struct yaffs_obj *in, const YCHAR * name,
int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name,
int force, int is_shrink, int shadows,
struct yaffs_xattr_mod *xop);
void yaffs_handle_shadowed_obj(struct yaffs_dev *dev, int obj_id,
@ -897,7 +920,7 @@ struct yaffs_tnode *yaffs_add_find_tnode_0(struct yaffs_dev *dev,
u32 chunk_id,
struct yaffs_tnode *passed_tn);
int yaffs_do_file_wr(struct yaffs_obj *in, const u8 * buffer, loff_t offset,
int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
int n_bytes, int write_trhrough);
void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size);
void yaffs_skip_rest_of_block(struct yaffs_dev *dev);
@ -911,4 +934,5 @@ struct yaffs_tnode *yaffs_find_tnode_0(struct yaffs_dev *dev,
u32 yaffs_get_group_base(struct yaffs_dev *dev, struct yaffs_tnode *tn,
unsigned pos);
int yaffs_is_non_empty_dir(struct yaffs_obj *obj);
#endif

View File

@ -25,11 +25,11 @@ struct yaffs_linux_context {
struct task_struct *bg_thread; /* Background thread for this device */
int bg_running;
struct mutex gross_lock; /* Gross locking mutex*/
u8 *spare_buffer; /* For mtdif2 use. Don't know the size of the buffer
u8 *spare_buffer; /* For mtdif2 use. Don't know the buffer size
* at compile time so we have to allocate it.
*/
struct list_head search_contexts;
void (*put_super_fn) (struct super_block * sb);
void (*put_super_fn) (struct super_block *sb);
struct task_struct *readdir_process;
unsigned mount_id;

View File

@ -29,7 +29,6 @@ int nandmtd_erase_block(struct yaffs_dev *dev, int block_no)
((loff_t) block_no) * dev->param.total_bytes_per_chunk
* dev->param.chunks_per_block;
struct erase_info ei;
int retval = 0;
ei.mtd = mtd;

View File

@ -64,7 +64,7 @@ static struct nand_ecclayout nand_oob_16 = {
.eccbytes = 6,
.eccpos = {8, 9, 10, 13, 14, 15},
.oobavail = 9,
.oobfree = {{0, 4}, {6, 2}, {11, 2}, {4, 1}}
.oobfree = {{0, 4}, {6, 2}, {11, 2}, {4, 1} }
};
#endif
@ -90,7 +90,7 @@ static struct nand_ecclayout nand_oob_16 = {
* Returns YAFFS_OK or YAFFS_FAIL.
*/
int nandmtd1_write_chunk_tags(struct yaffs_dev *dev,
int nand_chunk, const u8 * data,
int nand_chunk, const u8 *data,
const struct yaffs_ext_tags *etags)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
@ -120,11 +120,11 @@ int nandmtd1_write_chunk_tags(struct yaffs_dev *dev,
pt1.deleted = 0;
}
#else
((u8 *) & pt1)[8] = 0xff;
((u8 *) &pt1)[8] = 0xff;
if (etags->is_deleted) {
memset(&pt1, 0xff, 8);
/* zero page_status byte to indicate deleted */
((u8 *) & pt1)[8] = 0;
((u8 *) &pt1)[8] = 0;
}
#endif
@ -133,13 +133,13 @@ int nandmtd1_write_chunk_tags(struct yaffs_dev *dev,
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = YTAG1_SIZE;
ops.datbuf = (u8 *) data;
ops.oobbuf = (u8 *) & pt1;
ops.oobbuf = (u8 *) &pt1;
retval = mtd->write_oob(mtd, addr, &ops);
if (retval) {
T(YAFFS_TRACE_MTD,
(TSTR("write_oob failed, chunk %d, mtd error %d" TENDSTR),
nand_chunk, retval));
yaffs_trace(YAFFS_TRACE_MTD,
"write_oob failed, chunk %d, mtd error %d",
nand_chunk, retval);
}
return retval ? YAFFS_FAIL : YAFFS_OK;
}
@ -169,7 +169,7 @@ static int rettags(struct yaffs_ext_tags *etags, int ecc_result, int retval)
* Returns YAFFS_OK or YAFFS_FAIL.
*/
int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
int nand_chunk, u8 * data,
int nand_chunk, u8 *data,
struct yaffs_ext_tags *etags)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
@ -186,7 +186,7 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = YTAG1_SIZE;
ops.datbuf = data;
ops.oobbuf = (u8 *) & pt1;
ops.oobbuf = (u8 *) &pt1;
#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 20))
/* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug;
@ -198,11 +198,10 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
* Check status and determine ECC result.
*/
retval = mtd->read_oob(mtd, addr, &ops);
if (retval) {
T(YAFFS_TRACE_MTD,
(TSTR("read_oob failed, chunk %d, mtd error %d" TENDSTR),
nand_chunk, retval));
}
if (retval)
yaffs_trace(YAFFS_TRACE_MTD,
"read_oob failed, chunk %d, mtd error %d",
nand_chunk, retval);
switch (retval) {
case 0:
@ -227,7 +226,7 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
/* Check for a blank/erased chunk.
*/
if (yaffs_check_ff((u8 *) & pt1, 8)) {
if (yaffs_check_ff((u8 *) &pt1, 8)) {
/* when blank, upper layers want ecc_result to be <= NO_ERROR */
return rettags(etags, YAFFS_ECC_RESULT_NO_ERROR, YAFFS_OK);
}
@ -239,7 +238,7 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
deleted = !pt1.deleted;
pt1.deleted = 1;
#else
deleted = (yaffs_count_bits(((u8 *) & pt1)[8]) < 7);
deleted = (hweight8(((u8 *) &pt1)[8]) < 7);
#endif
/* Check the packed tags mini-ECC and correct if necessary/possible.
@ -286,8 +285,7 @@ int nandmtd1_mark_block_bad(struct yaffs_dev *dev, int block_no)
int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk;
int retval;
T(YAFFS_TRACE_BAD_BLOCKS,
(TSTR("marking block %d bad" TENDSTR), block_no));
yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", block_no);
retval = mtd->block_markbad(mtd, (loff_t) blocksize * block_no);
return (retval) ? YAFFS_FAIL : YAFFS_OK;
@ -304,10 +302,9 @@ static int nandmtd1_test_prerequists(struct mtd_info *mtd)
int oobavail = mtd->ecclayout->oobavail;
if (oobavail < YTAG1_SIZE) {
T(YAFFS_TRACE_ERROR,
(TSTR
("mtd device has only %d bytes for tags, need %d" TENDSTR),
oobavail, YTAG1_SIZE));
yaffs_trace(YAFFS_TRACE_ERROR,
"mtd device has only %d bytes for tags, need %d",
oobavail, YTAG1_SIZE);
return YAFFS_FAIL;
}
return YAFFS_OK;
@ -342,8 +339,9 @@ int nandmtd1_query_block(struct yaffs_dev *dev, int block_no,
retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags);
etags.block_bad = (mtd->block_isbad) (mtd, addr);
if (etags.block_bad) {
T(YAFFS_TRACE_BAD_BLOCKS,
(TSTR("block %d is marked bad" TENDSTR), block_no));
yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
"block %d is marked bad",
block_no);
state = YAFFS_BLOCK_STATE_DEAD;
} else if (etags.ecc_result != YAFFS_ECC_RESULT_NO_ERROR) {
/* bad tags, need to look more closely */

View File

@ -15,15 +15,15 @@
#define __YAFFS_MTDIF1_H__
int nandmtd1_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
const u8 * data,
const u8 *data,
const struct yaffs_ext_tags *tags);
int nandmtd1_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
u8 * data, struct yaffs_ext_tags *tags);
u8 *data, struct yaffs_ext_tags *tags);
int nandmtd1_mark_block_bad(struct yaffs_dev *dev, int block_no);
int nandmtd1_query_block(struct yaffs_dev *dev, int block_no,
enum yaffs_block_state *state, u32 * seq_number);
enum yaffs_block_state *state, u32 *seq_number);
#endif

View File

@ -27,11 +27,11 @@
#include "yaffs_linux.h"
/* NB For use with inband tags....
* We assume that the data buffer is of size total_bytes_per_chunk so that we can also
* use it to load the tags.
* We assume that the data buffer is of size total_bytes_per_chunk so
* that we can also use it to load the tags.
*/
int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
const u8 * data,
const u8 *data,
const struct yaffs_ext_tags *tags)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
@ -51,10 +51,9 @@ int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
void *packed_tags_ptr =
dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt;
T(YAFFS_TRACE_MTD,
(TSTR
("nandmtd2_write_chunk_tags chunk %d data %p tags %p"
TENDSTR), nand_chunk, data, tags));
yaffs_trace(YAFFS_TRACE_MTD,
"nandmtd2_write_chunk_tags chunk %d data %p tags %p",
nand_chunk, data, tags);
addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
@ -68,11 +67,12 @@ int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
struct yaffs_packed_tags2_tags_only *pt2tp;
pt2tp =
(struct yaffs_packed_tags2_tags_only *)(data +
dev->
data_bytes_per_chunk);
dev->
data_bytes_per_chunk);
yaffs_pack_tags2_tags_only(pt2tp, tags);
} else
} else {
yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
}
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
ops.mode = MTD_OOB_AUTO;
@ -102,7 +102,7 @@ int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
}
int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
u8 * data, struct yaffs_ext_tags *tags)
u8 *data, struct yaffs_ext_tags *tags)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
@ -121,10 +121,9 @@ int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
void *packed_tags_ptr =
dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt;
T(YAFFS_TRACE_MTD,
(TSTR
("nandmtd2_read_chunk_tags chunk %d data %p tags %p"
TENDSTR), nand_chunk, data, tags));
yaffs_trace(YAFFS_TRACE_MTD,
"nandmtd2_read_chunk_tags chunk %d data %p tags %p",
nand_chunk, data, tags);
if (dev->param.inband_tags) {
@ -169,8 +168,8 @@ int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
if (tags) {
struct yaffs_packed_tags2_tags_only *pt2tp;
pt2tp =
(struct yaffs_packed_tags2_tags_only *)&data[dev->
data_bytes_per_chunk];
(struct yaffs_packed_tags2_tags_only *)
&data[dev->data_bytes_per_chunk];
yaffs_unpack_tags2_tags_only(tags, pt2tp);
}
} else {
@ -205,8 +204,9 @@ int nandmtd2_mark_block_bad(struct yaffs_dev *dev, int block_no)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
int retval;
T(YAFFS_TRACE_MTD,
(TSTR("nandmtd2_mark_block_bad %d" TENDSTR), block_no));
yaffs_trace(YAFFS_TRACE_MTD,
"nandmtd2_mark_block_bad %d",
block_no);
retval =
mtd->block_markbad(mtd,
@ -221,19 +221,19 @@ int nandmtd2_mark_block_bad(struct yaffs_dev *dev, int block_no)
}
int nandmtd2_query_block(struct yaffs_dev *dev, int block_no,
enum yaffs_block_state *state, u32 * seq_number)
enum yaffs_block_state *state, u32 *seq_number)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
int retval;
T(YAFFS_TRACE_MTD, (TSTR("nandmtd2_query_block %d" TENDSTR), block_no));
yaffs_trace(YAFFS_TRACE_MTD, "nandmtd2_query_block %d", block_no);
retval =
mtd->block_isbad(mtd,
block_no * dev->param.chunks_per_block *
dev->param.total_bytes_per_chunk);
if (retval) {
T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR)));
yaffs_trace(YAFFS_TRACE_MTD, "block is bad");
*state = YAFFS_BLOCK_STATE_DEAD;
*seq_number = 0;
@ -250,11 +250,13 @@ int nandmtd2_query_block(struct yaffs_dev *dev, int block_no,
*state = YAFFS_BLOCK_STATE_EMPTY;
}
}
T(YAFFS_TRACE_MTD,
(TSTR("block is bad seq %d state %d" TENDSTR), *seq_number, *state));
yaffs_trace(YAFFS_TRACE_MTD,
"block is bad seq %d state %d",
*seq_number, *state);
if (retval == 0)
return YAFFS_OK;
else
return YAFFS_FAIL;
}

View File

@ -18,12 +18,12 @@
#include "yaffs_guts.h"
int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
const u8 * data,
const u8 *data,
const struct yaffs_ext_tags *tags);
int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
u8 * data, struct yaffs_ext_tags *tags);
u8 *data, struct yaffs_ext_tags *tags);
int nandmtd2_mark_block_bad(struct yaffs_dev *dev, int block_no);
int nandmtd2_query_block(struct yaffs_dev *dev, int block_no,
enum yaffs_block_state *state, u32 * seq_number);
enum yaffs_block_state *state, u32 *seq_number);
#endif

View File

@ -12,15 +12,15 @@
*/
/*
* This simple implementation of a name-value store assumes a small number of values and fits
* into a small finite buffer.
* This simple implementation of a name-value store assumes a small number of
* values and fits into a small finite buffer.
*
* Each attribute is stored as a record:
* sizeof(int) bytes record size.
* strnlen+1 bytes name null terminated.
* nbytes value.
* ----------
* total size stored in record size
* total size stored in record size
*
* This code has not been tested with unicode yet.
*/
@ -29,7 +29,7 @@
#include "yportenv.h"
static int nval_find(const char *xb, int xb_size, const YCHAR * name,
static int nval_find(const char *xb, int xb_size, const YCHAR *name,
int *exist_size)
{
int pos = 0;
@ -37,7 +37,7 @@ static int nval_find(const char *xb, int xb_size, const YCHAR * name,
memcpy(&size, xb, sizeof(int));
while (size > 0 && (size < xb_size) && (pos + size < xb_size)) {
if (yaffs_strncmp
if (strncmp
((YCHAR *) (xb + pos + sizeof(int)), name, size) == 0) {
if (exist_size)
*exist_size = size;
@ -70,26 +70,28 @@ static int nval_used(const char *xb, int xb_size)
return pos;
}
int nval_del(char *xb, int xb_size, const YCHAR * name)
int nval_del(char *xb, int xb_size, const YCHAR *name)
{
int pos = nval_find(xb, xb_size, name, NULL);
int size;
if (pos >= 0 && pos < xb_size) {
/* Find size, shift rest over this record, then zero out the rest of buffer */
/* Find size, shift rest over this record,
* then zero out the rest of buffer */
memcpy(&size, xb + pos, sizeof(int));
memcpy(xb + pos, xb + pos + size, xb_size - (pos + size));
memset(xb + (xb_size - size), 0, size);
return 0;
} else
} else {
return -ENODATA;
}
}
int nval_set(char *xb, int xb_size, const YCHAR * name, const char *buf,
int bsize, int flags)
int nval_set(char *xb, int xb_size, const YCHAR *name, const char *buf,
int bsize, int flags)
{
int pos;
int namelen = yaffs_strnlen(name, xb_size);
int namelen = strnlen(name, xb_size);
int reclen;
int size_exist = 0;
int space;
@ -119,7 +121,7 @@ int nval_set(char *xb, int xb_size, const YCHAR * name, const char *buf,
memcpy(xb + pos, &reclen, sizeof(int));
pos += sizeof(int);
yaffs_strncpy((YCHAR *) (xb + pos), name, reclen);
strncpy((YCHAR *) (xb + pos), name, reclen);
pos += (namelen + 1);
memcpy(xb + pos, buf, bsize);
return 0;
@ -167,11 +169,13 @@ int nval_list(const char *xb, int xb_size, char *buf, int bsize)
int filled = 0;
memcpy(&size, xb + pos, sizeof(int));
while (size > sizeof(int) && size <= xb_size && (pos + size) < xb_size
&& !filled) {
while (size > sizeof(int) &&
size <= xb_size &&
(pos + size) < xb_size &&
!filled) {
pos += sizeof(int);
size -= sizeof(int);
name_len = yaffs_strnlen((YCHAR *) (xb + pos), size);
name_len = strnlen((YCHAR *) (xb + pos), size);
if (ncopied + name_len + 1 < bsize) {
memcpy(buf, xb + pos, name_len * sizeof(YCHAR));
buf += name_len;
@ -182,8 +186,9 @@ int nval_list(const char *xb, int xb_size, char *buf, int bsize)
buf++;
}
ncopied += (name_len + 1);
} else
} else {
filled = 1;
}
pos += size;
if (pos < xb_size - sizeof(int))
memcpy(&size, xb + pos, sizeof(int));

View File

@ -18,16 +18,15 @@
#include "yaffs_getblockinfo.h"
int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk,
u8 * buffer, struct yaffs_ext_tags *tags)
u8 *buffer, struct yaffs_ext_tags *tags)
{
int result;
struct yaffs_ext_tags local_tags;
int realigned_chunk = nand_chunk - dev->chunk_offset;
dev->n_page_reads++;
/* If there are no tags provided, use local tags to get prioritised gc working */
/* If there are no tags provided use local tags. */
if (!tags)
tags = &local_tags;
@ -46,38 +45,36 @@ int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk,
dev->param.chunks_per_block);
yaffs_handle_chunk_error(dev, bi);
}
return result;
}
int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev,
int nand_chunk,
const u8 * buffer, struct yaffs_ext_tags *tags)
int nand_chunk,
const u8 *buffer, struct yaffs_ext_tags *tags)
{
dev->n_page_writes++;
nand_chunk -= dev->chunk_offset;
if (tags) {
tags->seq_number = dev->seq_number;
tags->chunk_used = 1;
if (!yaffs_validate_tags(tags)) {
T(YAFFS_TRACE_ERROR,
(TSTR("Writing uninitialised tags" TENDSTR)));
yaffs_trace(YAFFS_TRACE_ERROR,
"Writing uninitialised tags");
YBUG();
}
T(YAFFS_TRACE_WRITE,
(TSTR("Writing chunk %d tags %d %d" TENDSTR), nand_chunk,
tags->obj_id, tags->chunk_id));
yaffs_trace(YAFFS_TRACE_WRITE,
"Writing chunk %d tags %d %d",
nand_chunk, tags->obj_id, tags->chunk_id);
} else {
T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR)));
yaffs_trace(YAFFS_TRACE_ERROR, "Writing with no tags");
YBUG();
return YAFFS_FAIL;
}
if (dev->param.write_chunk_tags_fn)
return dev->param.write_chunk_tags_fn(dev, nand_chunk, buffer,
tags);
tags);
else
return yaffs_tags_compat_wr(dev, nand_chunk, buffer, tags);
}
@ -85,7 +82,6 @@ int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev,
int yaffs_mark_bad(struct yaffs_dev *dev, int block_no)
{
block_no -= dev->block_offset;
if (dev->param.bad_block_fn)
return dev->param.bad_block_fn(dev, block_no);
else
@ -95,10 +91,9 @@ int yaffs_mark_bad(struct yaffs_dev *dev, int block_no)
int yaffs_query_init_block_state(struct yaffs_dev *dev,
int block_no,
enum yaffs_block_state *state,
u32 * seq_number)
u32 *seq_number)
{
block_no -= dev->block_offset;
if (dev->param.query_block_fn)
return dev->param.query_block_fn(dev, block_no, state,
seq_number);
@ -112,11 +107,8 @@ int yaffs_erase_block(struct yaffs_dev *dev, int flash_block)
int result;
flash_block -= dev->block_offset;
dev->n_erasures++;
result = dev->param.erase_fn(dev, flash_block);
return result;
}

View File

@ -18,11 +18,11 @@
#include "yaffs_guts.h"
int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk,
u8 * buffer, struct yaffs_ext_tags *tags);
u8 *buffer, struct yaffs_ext_tags *tags);
int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev,
int nand_chunk,
const u8 * buffer, struct yaffs_ext_tags *tags);
const u8 *buffer, struct yaffs_ext_tags *tags);
int yaffs_mark_bad(struct yaffs_dev *dev, int block_no);

View File

@ -25,15 +25,15 @@ void yaffs_pack_tags1(struct yaffs_packed_tags1 *pt,
pt->deleted = (t->is_deleted) ? 0 : 1;
pt->unused_stuff = 0;
pt->should_be_ff = 0xFFFFFFFF;
}
void yaffs_unpack_tags1(struct yaffs_ext_tags *t,
const struct yaffs_packed_tags1 *pt)
{
static const u8 all_ff[] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff
static const u8 all_ff[12] = {
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff
};
if (memcmp(all_ff, pt, sizeof(struct yaffs_packed_tags1))) {

View File

@ -38,12 +38,12 @@
#define EXTRA_OBJECT_TYPE_SHIFT (28)
#define EXTRA_OBJECT_TYPE_MASK ((0x0F) << EXTRA_OBJECT_TYPE_SHIFT)
static void yaffs_dump_packed_tags2_tags_only(const struct
yaffs_packed_tags2_tags_only *ptt)
static void yaffs_dump_packed_tags2_tags_only(
const struct yaffs_packed_tags2_tags_only *ptt)
{
T(YAFFS_TRACE_MTD,
(TSTR("packed tags obj %d chunk %d byte %d seq %d" TENDSTR),
ptt->obj_id, ptt->chunk_id, ptt->n_bytes, ptt->seq_number));
yaffs_trace(YAFFS_TRACE_MTD,
"packed tags obj %d chunk %d byte %d seq %d",
ptt->obj_id, ptt->chunk_id, ptt->n_bytes, ptt->seq_number);
}
static void yaffs_dump_packed_tags2(const struct yaffs_packed_tags2 *pt)
@ -53,12 +53,11 @@ static void yaffs_dump_packed_tags2(const struct yaffs_packed_tags2 *pt)
static void yaffs_dump_tags2(const struct yaffs_ext_tags *t)
{
T(YAFFS_TRACE_MTD,
(TSTR
("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte %d del %d ser %d seq %d"
TENDSTR), t->ecc_result, t->block_bad, t->chunk_used, t->obj_id,
t->chunk_id, t->n_bytes, t->is_deleted, t->serial_number,
t->seq_number));
yaffs_trace(YAFFS_TRACE_MTD,
"ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte %d del %d ser %d seq %d",
t->ecc_result, t->block_bad, t->chunk_used, t->obj_id,
t->chunk_id, t->n_bytes, t->is_deleted, t->serial_number,
t->seq_number);
}
@ -109,9 +108,7 @@ void yaffs_pack_tags2(struct yaffs_packed_tags2 *pt,
void yaffs_unpack_tags2_tags_only(struct yaffs_ext_tags *t,
struct yaffs_packed_tags2_tags_only *ptt)
{
memset(t, 0, sizeof(struct yaffs_ext_tags));
yaffs_init_tags(t);
if (ptt->seq_number != 0xFFFFFFFF) {
@ -125,7 +122,6 @@ void yaffs_unpack_tags2_tags_only(struct yaffs_ext_tags *t,
t->seq_number = ptt->seq_number;
/* Do extra header info stuff */
if (ptt->chunk_id & EXTRA_HEADER_INFO_FLAG) {
t->chunk_id = 0;
t->n_bytes = 0;
@ -147,16 +143,13 @@ void yaffs_unpack_tags2_tags_only(struct yaffs_ext_tags *t,
t->extra_length = ptt->n_bytes;
}
}
yaffs_dump_packed_tags2_tags_only(ptt);
yaffs_dump_tags2(t);
}
void yaffs_unpack_tags2(struct yaffs_ext_tags *t, struct yaffs_packed_tags2 *pt,
int tags_ecc)
{
enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
if (pt->t.seq_number != 0xFFFFFFFF && tags_ecc) {
@ -165,14 +158,12 @@ void yaffs_unpack_tags2(struct yaffs_ext_tags *t, struct yaffs_packed_tags2 *pt,
struct yaffs_ecc_other ecc;
int result;
yaffs_ecc_calc_other((unsigned char *)&pt->t,
sizeof(struct
yaffs_packed_tags2_tags_only),
&ecc);
sizeof(struct yaffs_packed_tags2_tags_only),
&ecc);
result =
yaffs_ecc_correct_other((unsigned char *)&pt->t,
sizeof(struct
yaffs_packed_tags2_tags_only),
&pt->ecc, &ecc);
sizeof(struct yaffs_packed_tags2_tags_only),
&pt->ecc, &ecc);
switch (result) {
case 0:
ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
@ -187,7 +178,6 @@ void yaffs_unpack_tags2(struct yaffs_ext_tags *t, struct yaffs_packed_tags2 *pt,
ecc_result = YAFFS_ECC_RESULT_UNKNOWN;
}
}
yaffs_unpack_tags2_tags_only(t, &pt->t);
t->ecc_result = ecc_result;

View File

@ -19,35 +19,10 @@
static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk);
static const char yaffs_count_bits_table[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};
int yaffs_count_bits(u8 x)
{
int ret_val;
ret_val = yaffs_count_bits_table[x];
return ret_val;
}
/********** Tags ECC calculations *********/
void yaffs_calc_ecc(const u8 * data, struct yaffs_spare *spare)
void yaffs_calc_ecc(const u8 *data, struct yaffs_spare *spare)
{
yaffs_ecc_cacl(data, spare->ecc1);
yaffs_ecc_cacl(&data[256], spare->ecc2);
@ -56,7 +31,6 @@ void yaffs_calc_ecc(const u8 * data, struct yaffs_spare *spare)
void yaffs_calc_tags_ecc(struct yaffs_tags *tags)
{
/* Calculate an ecc */
unsigned char *b = ((union yaffs_tags_union *)tags)->as_bytes;
unsigned i, j;
unsigned ecc = 0;
@ -71,9 +45,7 @@ void yaffs_calc_tags_ecc(struct yaffs_tags *tags)
ecc ^= bit;
}
}
tags->ecc = ecc;
}
int yaffs_check_tags_ecc(struct yaffs_tags *tags)
@ -101,7 +73,6 @@ int yaffs_check_tags_ecc(struct yaffs_tags *tags)
/* TODO Need to do somethiong here */
return -1; /* unrecovered error */
}
return 0;
}
@ -153,13 +124,13 @@ static void yaffs_spare_init(struct yaffs_spare *spare)
}
static int yaffs_wr_nand(struct yaffs_dev *dev,
int nand_chunk, const u8 * data,
int nand_chunk, const u8 *data,
struct yaffs_spare *spare)
{
if (nand_chunk < dev->param.start_block * dev->param.chunks_per_block) {
T(YAFFS_TRACE_ERROR,
(TSTR("**>> yaffs chunk %d is not valid" TENDSTR),
nand_chunk));
yaffs_trace(YAFFS_TRACE_ERROR,
"**>> yaffs chunk %d is not valid",
nand_chunk);
return YAFFS_FAIL;
}
@ -168,7 +139,7 @@ static int yaffs_wr_nand(struct yaffs_dev *dev,
static int yaffs_rd_chunk_nand(struct yaffs_dev *dev,
int nand_chunk,
u8 * data,
u8 *data,
struct yaffs_spare *spare,
enum yaffs_ecc_result *ecc_result,
int correct_errors)
@ -176,7 +147,7 @@ static int yaffs_rd_chunk_nand(struct yaffs_dev *dev,
int ret_val;
struct yaffs_spare local_spare;
if (!spare && data) {
if (!spare) {
/* If we don't have a real spare, then we use a local one. */
/* Need this for the calculation of the ecc */
spare = &local_spare;
@ -200,30 +171,26 @@ static int yaffs_rd_chunk_nand(struct yaffs_dev *dev,
calc_ecc);
if (ecc_result1 > 0) {
T(YAFFS_TRACE_ERROR,
(TSTR
("**>>yaffs ecc error fix performed on chunk %d:0"
TENDSTR), nand_chunk));
yaffs_trace(YAFFS_TRACE_ERROR,
"**>>yaffs ecc error fix performed on chunk %d:0",
nand_chunk);
dev->n_ecc_fixed++;
} else if (ecc_result1 < 0) {
T(YAFFS_TRACE_ERROR,
(TSTR
("**>>yaffs ecc error unfixed on chunk %d:0"
TENDSTR), nand_chunk));
yaffs_trace(YAFFS_TRACE_ERROR,
"**>>yaffs ecc error unfixed on chunk %d:0",
nand_chunk);
dev->n_ecc_unfixed++;
}
if (ecc_result2 > 0) {
T(YAFFS_TRACE_ERROR,
(TSTR
("**>>yaffs ecc error fix performed on chunk %d:1"
TENDSTR), nand_chunk));
yaffs_trace(YAFFS_TRACE_ERROR,
"**>>yaffs ecc error fix performed on chunk %d:1",
nand_chunk);
dev->n_ecc_fixed++;
} else if (ecc_result2 < 0) {
T(YAFFS_TRACE_ERROR,
(TSTR
("**>>yaffs ecc error unfixed on chunk %d:1"
TENDSTR), nand_chunk));
yaffs_trace(YAFFS_TRACE_ERROR,
"**>>yaffs ecc error unfixed on chunk %d:1",
nand_chunk);
dev->n_ecc_unfixed++;
}
@ -252,27 +219,23 @@ static int yaffs_rd_chunk_nand(struct yaffs_dev *dev,
memcpy(spare, &nspare, sizeof(struct yaffs_spare));
if (data && correct_errors) {
if (nspare.eccres1 > 0) {
T(YAFFS_TRACE_ERROR,
(TSTR
("**>>mtd ecc error fix performed on chunk %d:0"
TENDSTR), nand_chunk));
yaffs_trace(YAFFS_TRACE_ERROR,
"**>>mtd ecc error fix performed on chunk %d:0",
nand_chunk);
} else if (nspare.eccres1 < 0) {
T(YAFFS_TRACE_ERROR,
(TSTR
("**>>mtd ecc error unfixed on chunk %d:0"
TENDSTR), nand_chunk));
yaffs_trace(YAFFS_TRACE_ERROR,
"**>>mtd ecc error unfixed on chunk %d:0",
nand_chunk);
}
if (nspare.eccres2 > 0) {
T(YAFFS_TRACE_ERROR,
(TSTR
("**>>mtd ecc error fix performed on chunk %d:1"
TENDSTR), nand_chunk));
yaffs_trace(YAFFS_TRACE_ERROR,
"**>>mtd ecc error fix performed on chunk %d:1",
nand_chunk);
} else if (nspare.eccres2 < 0) {
T(YAFFS_TRACE_ERROR,
(TSTR
("**>>mtd ecc error unfixed on chunk %d:1"
TENDSTR), nand_chunk));
yaffs_trace(YAFFS_TRACE_ERROR,
"**>>mtd ecc error unfixed on chunk %d:1",
nand_chunk);
}
if (nspare.eccres1 || nspare.eccres2) {
@ -301,11 +264,11 @@ static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk)
int flash_block = nand_chunk / dev->param.chunks_per_block;
/* Mark the block for retirement */
yaffs_get_block_info(dev,
flash_block + dev->block_offset)->needs_retiring =
1;
T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
(TSTR("**>>Block %d marked for retirement" TENDSTR), flash_block));
yaffs_get_block_info(dev, flash_block + dev->block_offset)->
needs_retiring = 1;
yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
"**>>Block %d marked for retirement",
flash_block);
/* TODO:
* Just do a garbage collection on the affected block
@ -316,7 +279,7 @@ static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk)
int yaffs_tags_compat_wr(struct yaffs_dev *dev,
int nand_chunk,
const u8 * data, const struct yaffs_ext_tags *ext_tags)
const u8 *data, const struct yaffs_ext_tags *ext_tags)
{
struct yaffs_spare spare;
struct yaffs_tags tags;
@ -350,13 +313,11 @@ int yaffs_tags_compat_wr(struct yaffs_dev *dev,
int yaffs_tags_compat_rd(struct yaffs_dev *dev,
int nand_chunk,
u8 * data, struct yaffs_ext_tags *ext_tags)
u8 *data, struct yaffs_ext_tags *ext_tags)
{
struct yaffs_spare spare;
struct yaffs_tags tags;
enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_UNKNOWN;
static struct yaffs_spare spare_ff;
static int init;
@ -365,12 +326,13 @@ int yaffs_tags_compat_rd(struct yaffs_dev *dev,
init = 1;
}
if (yaffs_rd_chunk_nand(dev, nand_chunk, data, &spare, &ecc_result, 1)) {
if (yaffs_rd_chunk_nand(dev, nand_chunk,
data, &spare, &ecc_result, 1)) {
/* ext_tags may be NULL */
if (ext_tags) {
int deleted =
(yaffs_count_bits(spare.page_status) < 7) ? 1 : 0;
(hweight8(spare.page_status) < 7) ? 1 : 0;
ext_tags->is_deleted = deleted;
ext_tags->ecc_result = ecc_result;
@ -404,7 +366,6 @@ int yaffs_tags_compat_rd(struct yaffs_dev *dev,
int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block)
{
struct yaffs_spare spare;
memset(&spare, 0xff, sizeof(struct yaffs_spare));
@ -417,15 +378,13 @@ int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block)
NULL, &spare);
return YAFFS_OK;
}
int yaffs_tags_compat_query_block(struct yaffs_dev *dev,
int block_no,
enum yaffs_block_state *state,
u32 * seq_number)
u32 *seq_number)
{
struct yaffs_spare spare0, spare1;
static struct yaffs_spare spare_ff;
static int init;
@ -443,7 +402,7 @@ int yaffs_tags_compat_query_block(struct yaffs_dev *dev,
yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block + 1,
NULL, &spare1, &dummy, 1);
if (yaffs_count_bits(spare0.block_status & spare1.block_status) < 7)
if (hweight8(spare0.block_status & spare1.block_status) < 7)
*state = YAFFS_BLOCK_STATE_DEAD;
else if (memcmp(&spare_ff, &spare0, sizeof(spare_ff)) == 0)
*state = YAFFS_BLOCK_STATE_EMPTY;

View File

@ -19,15 +19,15 @@
#include "yaffs_guts.h"
int yaffs_tags_compat_wr(struct yaffs_dev *dev,
int nand_chunk,
const u8 * data, const struct yaffs_ext_tags *tags);
const u8 *data, const struct yaffs_ext_tags *tags);
int yaffs_tags_compat_rd(struct yaffs_dev *dev,
int nand_chunk,
u8 * data, struct yaffs_ext_tags *tags);
u8 *data, struct yaffs_ext_tags *tags);
int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int block_no);
int yaffs_tags_compat_query_block(struct yaffs_dev *dev,
int block_no,
enum yaffs_block_state *state,
u32 * seq_number);
u32 *seq_number);
void yaffs_calc_tags_ecc(struct yaffs_tags *tags);
int yaffs_check_tags_ecc(struct yaffs_tags *tags);

View File

@ -23,5 +23,4 @@ void yaffs_init_tags(struct yaffs_ext_tags *tags)
int yaffs_validate_tags(struct yaffs_ext_tags *tags)
{
return (tags->validity0 == 0xAAAAAAAA && tags->validity1 == 0x55555555);
}

View File

@ -48,11 +48,10 @@ extern unsigned int yaffs_wr_attempts;
#define YAFFS_TRACE_SYNC 0x00100000
#define YAFFS_TRACE_BACKGROUND 0x00200000
#define YAFFS_TRACE_LOCK 0x00400000
#define YAFFS_TRACE_MOUNT 0x00800000
#define YAFFS_TRACE_ERROR 0x40000000
#define YAFFS_TRACE_BUG 0x80000000
#define YAFFS_TRACE_ALWAYS 0xF0000000
#define T(mask, p) do { if ((mask) & (yaffs_trace_mask | YAFFS_TRACE_ALWAYS)) TOUT(p); } while (0)
#endif

View File

@ -36,7 +36,7 @@ static int yaffs_skip_nand_verification(struct yaffs_dev *dev)
return !(yaffs_trace_mask & (YAFFS_TRACE_VERIFY_NAND));
}
static const char *block_state_name[] = {
static const char * const block_state_name[] = {
"Unknown",
"Needs scanning",
"Scanning",
@ -59,17 +59,17 @@ void yaffs_verify_blk(struct yaffs_dev *dev, struct yaffs_block_info *bi, int n)
/* Report illegal runtime states */
if (bi->block_state >= YAFFS_NUMBER_OF_BLOCK_STATES)
T(YAFFS_TRACE_VERIFY,
(TSTR("Block %d has undefined state %d" TENDSTR), n,
bi->block_state));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Block %d has undefined state %d",
n, bi->block_state);
switch (bi->block_state) {
case YAFFS_BLOCK_STATE_UNKNOWN:
case YAFFS_BLOCK_STATE_SCANNING:
case YAFFS_BLOCK_STATE_NEEDS_SCANNING:
T(YAFFS_TRACE_VERIFY,
(TSTR("Block %d has bad run-state %s" TENDSTR), n,
block_state_name[bi->block_state]));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Block %d has bad run-state %s",
n, block_state_name[bi->block_state]);
}
/* Check pages in use and soft deletions are legal */
@ -81,19 +81,16 @@ void yaffs_verify_blk(struct yaffs_dev *dev, struct yaffs_block_info *bi, int n)
|| bi->soft_del_pages < 0
|| bi->soft_del_pages > dev->param.chunks_per_block
|| actually_used < 0 || actually_used > dev->param.chunks_per_block)
T(YAFFS_TRACE_VERIFY,
(TSTR
("Block %d has illegal values pages_in_used %d soft_del_pages %d"
TENDSTR), n, bi->pages_in_use, bi->soft_del_pages));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Block %d has illegal values pages_in_used %d soft_del_pages %d",
n, bi->pages_in_use, bi->soft_del_pages);
/* Check chunk bitmap legal */
in_use = yaffs_count_chunk_bits(dev, n);
if (in_use != bi->pages_in_use)
T(YAFFS_TRACE_VERIFY,
(TSTR
("Block %d has inconsistent values pages_in_use %d counted chunk bits %d"
TENDSTR), n, bi->pages_in_use, in_use));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Block %d has inconsistent values pages_in_use %d counted chunk bits %d",
n, bi->pages_in_use, in_use);
}
void yaffs_verify_collected_blk(struct yaffs_dev *dev,
@ -105,10 +102,9 @@ void yaffs_verify_collected_blk(struct yaffs_dev *dev,
if (bi->block_state != YAFFS_BLOCK_STATE_COLLECTING &&
bi->block_state != YAFFS_BLOCK_STATE_EMPTY) {
T(YAFFS_TRACE_ERROR,
(TSTR
("Block %d is in state %d after gc, should be erased"
TENDSTR), n, bi->block_state));
yaffs_trace(YAFFS_TRACE_ERROR,
"Block %d is in state %d after gc, should be erased",
n, bi->block_state);
}
}
@ -133,43 +129,41 @@ void yaffs_verify_blocks(struct yaffs_dev *dev)
illegal_states++;
}
T(YAFFS_TRACE_VERIFY, (TSTR("" TENDSTR)));
T(YAFFS_TRACE_VERIFY, (TSTR("Block summary" TENDSTR)));
yaffs_trace(YAFFS_TRACE_VERIFY, "Block summary");
T(YAFFS_TRACE_VERIFY,
(TSTR("%d blocks have illegal states" TENDSTR), illegal_states));
yaffs_trace(YAFFS_TRACE_VERIFY,
"%d blocks have illegal states",
illegal_states);
if (state_count[YAFFS_BLOCK_STATE_ALLOCATING] > 1)
T(YAFFS_TRACE_VERIFY,
(TSTR("Too many allocating blocks" TENDSTR)));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Too many allocating blocks");
for (i = 0; i < YAFFS_NUMBER_OF_BLOCK_STATES; i++)
T(YAFFS_TRACE_VERIFY,
(TSTR("%s %d blocks" TENDSTR),
block_state_name[i], state_count[i]));
yaffs_trace(YAFFS_TRACE_VERIFY,
"%s %d blocks",
block_state_name[i], state_count[i]);
if (dev->blocks_in_checkpt != state_count[YAFFS_BLOCK_STATE_CHECKPOINT])
T(YAFFS_TRACE_VERIFY,
(TSTR("Checkpoint block count wrong dev %d count %d" TENDSTR),
dev->blocks_in_checkpt,
state_count[YAFFS_BLOCK_STATE_CHECKPOINT]));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Checkpoint block count wrong dev %d count %d",
dev->blocks_in_checkpt,
state_count[YAFFS_BLOCK_STATE_CHECKPOINT]);
if (dev->n_erased_blocks != state_count[YAFFS_BLOCK_STATE_EMPTY])
T(YAFFS_TRACE_VERIFY,
(TSTR("Erased block count wrong dev %d count %d" TENDSTR),
dev->n_erased_blocks, state_count[YAFFS_BLOCK_STATE_EMPTY]));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Erased block count wrong dev %d count %d",
dev->n_erased_blocks,
state_count[YAFFS_BLOCK_STATE_EMPTY]);
if (state_count[YAFFS_BLOCK_STATE_COLLECTING] > 1)
T(YAFFS_TRACE_VERIFY,
(TSTR("Too many collecting blocks %d (max is 1)" TENDSTR),
state_count[YAFFS_BLOCK_STATE_COLLECTING]));
T(YAFFS_TRACE_VERIFY, (TSTR("" TENDSTR)));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Too many collecting blocks %d (max is 1)",
state_count[YAFFS_BLOCK_STATE_COLLECTING]);
}
/*
* Verify the object header. oh must be valid, but obj and tags may be NULL in which
* case those tests will not be performed.
* Verify the object header. oh must be valid, but obj and tags may be NULL in
* which case those tests will not be performed.
*/
void yaffs_verify_oh(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh,
struct yaffs_ext_tags *tags, int parent_check)
@ -178,22 +172,22 @@ void yaffs_verify_oh(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh,
return;
if (!(tags && obj && oh)) {
T(YAFFS_TRACE_VERIFY,
(TSTR("Verifying object header tags %p obj %p oh %p" TENDSTR),
tags, obj, oh));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Verifying object header tags %p obj %p oh %p",
tags, obj, oh);
return;
}
if (oh->type <= YAFFS_OBJECT_TYPE_UNKNOWN ||
oh->type > YAFFS_OBJECT_TYPE_MAX)
T(YAFFS_TRACE_VERIFY,
(TSTR("Obj %d header type is illegal value 0x%x" TENDSTR),
tags->obj_id, oh->type));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Obj %d header type is illegal value 0x%x",
tags->obj_id, oh->type);
if (tags->obj_id != obj->obj_id)
T(YAFFS_TRACE_VERIFY,
(TSTR("Obj %d header mismatch obj_id %d" TENDSTR),
tags->obj_id, obj->obj_id));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Obj %d header mismatch obj_id %d",
tags->obj_id, obj->obj_id);
/*
* Check that the object's parent ids match if parent_check requested.
@ -202,28 +196,28 @@ void yaffs_verify_oh(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh,
*/
if (parent_check && tags->obj_id > 1 && !obj->parent)
T(YAFFS_TRACE_VERIFY,
(TSTR
("Obj %d header mismatch parent_id %d obj->parent is NULL"
TENDSTR), tags->obj_id, oh->parent_obj_id));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Obj %d header mismatch parent_id %d obj->parent is NULL",
tags->obj_id, oh->parent_obj_id);
if (parent_check && obj->parent &&
oh->parent_obj_id != obj->parent->obj_id &&
(oh->parent_obj_id != YAFFS_OBJECTID_UNLINKED ||
obj->parent->obj_id != YAFFS_OBJECTID_DELETED))
T(YAFFS_TRACE_VERIFY,
(TSTR
("Obj %d header mismatch parent_id %d parent_obj_id %d"
TENDSTR), tags->obj_id, oh->parent_obj_id,
obj->parent->obj_id));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Obj %d header mismatch parent_id %d parent_obj_id %d",
tags->obj_id, oh->parent_obj_id,
obj->parent->obj_id);
if (tags->obj_id > 1 && oh->name[0] == 0) /* Null name */
T(YAFFS_TRACE_VERIFY,
(TSTR("Obj %d header name is NULL" TENDSTR), obj->obj_id));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Obj %d header name is NULL",
obj->obj_id);
if (tags->obj_id > 1 && ((u8) (oh->name[0])) == 0xff) /* Trashed name */
T(YAFFS_TRACE_VERIFY,
(TSTR("Obj %d header name is 0xFF" TENDSTR), obj->obj_id));
if (tags->obj_id > 1 && ((u8) (oh->name[0])) == 0xff) /* Junk name */
yaffs_trace(YAFFS_TRACE_VERIFY,
"Obj %d header name is 0xFF",
obj->obj_id);
}
void yaffs_verify_file(struct yaffs_obj *obj)
@ -273,16 +267,13 @@ void yaffs_verify_file(struct yaffs_obj *obj)
if (tn) {
u32 the_chunk = yaffs_get_group_base(dev, tn, i);
if (the_chunk > 0) {
/* T(~0,(TSTR("verifying (%d:%d) %d"TENDSTR),obj_id,i,the_chunk)); */
yaffs_rd_chunk_tags_nand(dev, the_chunk, NULL,
&tags);
if (tags.obj_id != obj_id || tags.chunk_id != i) {
T(~0,
(TSTR
("Object %d chunk_id %d NAND mismatch chunk %d tags (%d:%d)"
TENDSTR), obj_id, i, the_chunk,
tags.obj_id, tags.chunk_id));
}
if (tags.obj_id != obj_id || tags.chunk_id != i)
yaffs_trace(YAFFS_TRACE_VERIFY,
"Object %d chunk_id %d NAND mismatch chunk %d tags (%d:%d)",
obj_id, i, the_chunk,
tags.obj_id, tags.chunk_id);
}
}
}
@ -313,10 +304,8 @@ void yaffs_verify_special(struct yaffs_obj *obj)
void yaffs_verify_obj(struct yaffs_obj *obj)
{
struct yaffs_dev *dev;
u32 chunk_min;
u32 chunk_max;
u32 chunk_id_ok;
u32 chunk_in_range;
u32 chunk_wrongly_deleted;
@ -348,13 +337,12 @@ void yaffs_verify_obj(struct yaffs_obj *obj)
obj->hdr_chunk % dev->param.chunks_per_block);
chunk_wrongly_deleted = chunk_in_range && !chunk_valid;
if (!obj->fake && (!chunk_id_ok || chunk_wrongly_deleted)) {
T(YAFFS_TRACE_VERIFY,
(TSTR("Obj %d has chunk_id %d %s %s" TENDSTR),
obj->obj_id, obj->hdr_chunk,
chunk_id_ok ? "" : ",out of range",
chunk_wrongly_deleted ? ",marked as deleted" : ""));
}
if (!obj->fake && (!chunk_id_ok || chunk_wrongly_deleted))
yaffs_trace(YAFFS_TRACE_VERIFY,
"Obj %d has chunk_id %d %s %s",
obj->obj_id, obj->hdr_chunk,
chunk_id_ok ? "" : ",out of range",
chunk_wrongly_deleted ? ",marked as deleted" : "");
if (chunk_valid && !yaffs_skip_nand_verification(dev)) {
struct yaffs_ext_tags tags;
@ -372,18 +360,17 @@ void yaffs_verify_obj(struct yaffs_obj *obj)
/* Verify it has a parent */
if (obj && !obj->fake && (!obj->parent || obj->parent->my_dev != dev)) {
T(YAFFS_TRACE_VERIFY,
(TSTR
("Obj %d has parent pointer %p which does not look like an object"
TENDSTR), obj->obj_id, obj->parent));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Obj %d has parent pointer %p which does not look like an object",
obj->obj_id, obj->parent);
}
/* Verify parent is a directory */
if (obj->parent
&& obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
T(YAFFS_TRACE_VERIFY,
(TSTR("Obj %d's parent is not a directory (type %d)" TENDSTR),
obj->obj_id, obj->parent->variant_type));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Obj %d's parent is not a directory (type %d)",
obj->obj_id, obj->parent->variant_type);
}
switch (obj->variant_type) {
@ -404,9 +391,9 @@ void yaffs_verify_obj(struct yaffs_obj *obj)
break;
case YAFFS_OBJECT_TYPE_UNKNOWN:
default:
T(YAFFS_TRACE_VERIFY,
(TSTR("Obj %d has illegaltype %d" TENDSTR),
obj->obj_id, obj->variant_type));
yaffs_trace(YAFFS_TRACE_VERIFY,
"Obj %d has illegaltype %d",
obj->obj_id, obj->variant_type);
break;
}
}
@ -424,11 +411,8 @@ void yaffs_verify_objects(struct yaffs_dev *dev)
for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
list_for_each(lh, &dev->obj_bucket[i].list) {
if (lh) {
obj =
list_entry(lh, struct yaffs_obj, hash_link);
yaffs_verify_obj(obj);
}
obj = list_entry(lh, struct yaffs_obj, hash_link);
yaffs_verify_obj(obj);
}
}
}
@ -437,11 +421,10 @@ void yaffs_verify_obj_in_dir(struct yaffs_obj *obj)
{
struct list_head *lh;
struct yaffs_obj *list_obj;
int count = 0;
if (!obj) {
T(YAFFS_TRACE_ALWAYS, (TSTR("No object to verify" TENDSTR)));
yaffs_trace(YAFFS_TRACE_ALWAYS, "No object to verify");
YBUG();
return;
}
@ -450,32 +433,29 @@ void yaffs_verify_obj_in_dir(struct yaffs_obj *obj)
return;
if (!obj->parent) {
T(YAFFS_TRACE_ALWAYS,
(TSTR("Object does not have parent" TENDSTR)));
yaffs_trace(YAFFS_TRACE_ALWAYS, "Object does not have parent");
YBUG();
return;
}
if (obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
T(YAFFS_TRACE_ALWAYS,
(TSTR("Parent is not directory" TENDSTR)));
yaffs_trace(YAFFS_TRACE_ALWAYS, "Parent is not directory");
YBUG();
}
/* Iterate through the objects in each hash entry */
list_for_each(lh, &obj->parent->variant.dir_variant.children) {
if (lh) {
list_obj = list_entry(lh, struct yaffs_obj, siblings);
yaffs_verify_obj(list_obj);
if (obj == list_obj)
count++;
}
list_obj = list_entry(lh, struct yaffs_obj, siblings);
yaffs_verify_obj(list_obj);
if (obj == list_obj)
count++;
}
if (count != 1) {
T(YAFFS_TRACE_ALWAYS,
(TSTR("Object in directory %d times" TENDSTR), count));
yaffs_trace(YAFFS_TRACE_ALWAYS,
"Object in directory %d times",
count);
YBUG();
}
}
@ -494,26 +474,23 @@ void yaffs_verify_dir(struct yaffs_obj *directory)
return;
if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
T(YAFFS_TRACE_ALWAYS,
(TSTR("Directory has wrong type: %d" TENDSTR),
directory->variant_type));
yaffs_trace(YAFFS_TRACE_ALWAYS,
"Directory has wrong type: %d",
directory->variant_type);
YBUG();
}
/* Iterate through the objects in each hash entry */
list_for_each(lh, &directory->variant.dir_variant.children) {
if (lh) {
list_obj = list_entry(lh, struct yaffs_obj, siblings);
if (list_obj->parent != directory) {
T(YAFFS_TRACE_ALWAYS,
(TSTR
("Object in directory list has wrong parent %p"
TENDSTR), list_obj->parent));
YBUG();
}
yaffs_verify_obj_in_dir(list_obj);
list_obj = list_entry(lh, struct yaffs_obj, siblings);
if (list_obj->parent != directory) {
yaffs_trace(YAFFS_TRACE_ALWAYS,
"Object in directory list has wrong parent %p",
list_obj->parent);
YBUG();
}
yaffs_verify_obj_in_dir(list_obj);
}
}
@ -532,9 +509,9 @@ void yaffs_verify_free_chunks(struct yaffs_dev *dev)
difference = dev->n_free_chunks - counted;
if (difference) {
T(YAFFS_TRACE_ALWAYS,
(TSTR("Freechunks verification failure %d %d %d" TENDSTR),
dev->n_free_chunks, counted, difference));
yaffs_trace(YAFFS_TRACE_ALWAYS,
"Freechunks verification failure %d %d %d",
dev->n_free_chunks, counted, difference);
yaffs_free_verification_failures++;
}
}
@ -544,3 +521,4 @@ int yaffs_verify_file_sane(struct yaffs_obj *in)
in = in;
return YAFFS_OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,6 @@ int yaffs1_scan(struct yaffs_dev *dev)
struct yaffs_ext_tags tags;
int blk;
int result;
int chunk;
int c;
int deleted;
@ -35,16 +34,13 @@ int yaffs1_scan(struct yaffs_dev *dev)
struct yaffs_obj_hdr *oh;
struct yaffs_obj *in;
struct yaffs_obj *parent;
int alloc_failed = 0;
struct yaffs_shadow_fixer *shadow_fixers = NULL;
u8 *chunk_data;
T(YAFFS_TRACE_SCAN,
(TSTR("yaffs1_scan starts intstartblk %d intendblk %d..." TENDSTR),
dev->internal_start_block, dev->internal_end_block));
yaffs_trace(YAFFS_TRACE_SCAN,
"yaffs1_scan starts intstartblk %d intendblk %d...",
dev->internal_start_block, dev->internal_end_block);
chunk_data = yaffs_get_temp_buffer(dev, __LINE__);
@ -66,16 +62,15 @@ int yaffs1_scan(struct yaffs_dev *dev)
if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK)
bi->block_state = state = YAFFS_BLOCK_STATE_DEAD;
T(YAFFS_TRACE_SCAN_DEBUG,
(TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
state, seq_number));
yaffs_trace(YAFFS_TRACE_SCAN_DEBUG,
"Block scanning block %d state %d seq %d",
blk, state, seq_number);
if (state == YAFFS_BLOCK_STATE_DEAD) {
T(YAFFS_TRACE_BAD_BLOCKS,
(TSTR("block %d is bad" TENDSTR), blk));
yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
"block %d is bad", blk);
} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
T(YAFFS_TRACE_SCAN_DEBUG,
(TSTR("Block empty " TENDSTR)));
yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "Block empty ");
dev->n_erased_blocks++;
dev->n_free_chunks += dev->param.chunks_per_block;
}
@ -86,7 +81,7 @@ int yaffs1_scan(struct yaffs_dev *dev)
for (blk = dev->internal_start_block;
!alloc_failed && blk <= dev->internal_end_block; blk++) {
YYIELD();
cond_resched();
bi = yaffs_get_block_info(dev, blk);
state = bi->block_state;
@ -111,7 +106,6 @@ int yaffs1_scan(struct yaffs_dev *dev)
*/
deleted++;
dev->n_free_chunks++;
/*T((" %d %d deleted\n",blk,c)); */
} else if (!tags.chunk_used) {
/* An unassigned chunk in the block
* This means that either the block is empty or
@ -119,20 +113,19 @@ int yaffs1_scan(struct yaffs_dev *dev)
*/
if (c == 0) {
/* We're looking at the first chunk in the block so the block is unused */
/* We're looking at the first chunk in
*the block so the block is unused */
state = YAFFS_BLOCK_STATE_EMPTY;
dev->n_erased_blocks++;
} else {
/* this is the block being allocated from */
T(YAFFS_TRACE_SCAN,
(TSTR
(" Allocating from %d %d" TENDSTR),
blk, c));
/* this is the block being allocated */
yaffs_trace(YAFFS_TRACE_SCAN,
" Allocating from %d %d",
blk, c);
state = YAFFS_BLOCK_STATE_ALLOCATING;
dev->alloc_block = blk;
dev->alloc_page = c;
dev->alloc_block_finder = blk;
/* Set block finder here to encourage the allocator to go forth from here. */
}
@ -146,10 +139,10 @@ int yaffs1_scan(struct yaffs_dev *dev)
bi->pages_in_use++;
in = yaffs_find_or_create_by_number(dev,
tags.obj_id,
YAFFS_OBJECT_TYPE_FILE);
/* PutChunkIntoFile checks for a clash (two data chunks with
* the same chunk_id).
tags.obj_id,
YAFFS_OBJECT_TYPE_FILE);
/* PutChunkIntoFile checks for a clash
* (two data chunks with the same chunk_id).
*/
if (!in)
@ -162,13 +155,13 @@ int yaffs1_scan(struct yaffs_dev *dev)
}
endpos =
(tags.chunk_id -
1) * dev->data_bytes_per_chunk +
(tags.chunk_id - 1) *
dev->data_bytes_per_chunk +
tags.n_bytes;
if (in
&& in->variant_type ==
YAFFS_OBJECT_TYPE_FILE
&& in->variant.file_variant.scanned_size <
if (in &&
in->variant_type ==
YAFFS_OBJECT_TYPE_FILE &&
in->variant.file_variant.scanned_size <
endpos) {
in->variant.file_variant.scanned_size =
endpos;
@ -180,10 +173,9 @@ int yaffs1_scan(struct yaffs_dev *dev)
}
}
/* T((" %d %d data %d %d\n",blk,c,tags.obj_id,tags.chunk_id)); */
} else {
/* chunk_id == 0, so it is an ObjectHeader.
* Thus, we read in the object header and make the object
* Make the object
*/
yaffs_set_chunk_bit(dev, blk, c);
bi->pages_in_use++;
@ -197,18 +189,19 @@ int yaffs1_scan(struct yaffs_dev *dev)
in = yaffs_find_by_number(dev, tags.obj_id);
if (in && in->variant_type != oh->type) {
/* This should not happen, but somehow
* Wev'e ended up with an obj_id that has been reused but not yet
* deleted, and worse still it has changed type. Delete the old object.
* Wev'e ended up with an obj_id that
* has been reused but not yet deleted,
* and worse still it has changed type.
* Delete the old object.
*/
yaffs_del_obj(in);
in = 0;
in = NULL;
}
in = yaffs_find_or_create_by_number(dev,
tags.obj_id,
oh->type);
tags.obj_id,
oh->type);
if (!in)
alloc_failed = 1;
@ -217,27 +210,28 @@ int yaffs1_scan(struct yaffs_dev *dev)
struct yaffs_shadow_fixer *fixer;
fixer =
YMALLOC(sizeof
(struct
yaffs_shadow_fixer));
kmalloc(sizeof
(struct yaffs_shadow_fixer),
GFP_NOFS);
if (fixer) {
fixer->next = shadow_fixers;
shadow_fixers = fixer;
fixer->obj_id = tags.obj_id;
fixer->shadowed_id =
oh->shadows_obj;
T(YAFFS_TRACE_SCAN,
(TSTR
(" Shadow fixer: %d shadows %d"
TENDSTR), fixer->obj_id,
fixer->shadowed_id));
yaffs_trace(YAFFS_TRACE_SCAN,
" Shadow fixer: %d shadows %d",
fixer->obj_id,
fixer->shadowed_id);
}
}
if (in && in->valid) {
/* We have already filled this one. We have a duplicate and need to resolve it. */
/* We have already filled this one.
* We have a duplicate and need to
* resolve it. */
unsigned existing_serial = in->serial;
unsigned new_serial =
@ -245,13 +239,15 @@ int yaffs1_scan(struct yaffs_dev *dev)
if (((existing_serial + 1) & 3) ==
new_serial) {
/* Use new one - destroy the exisiting one */
/* Use new one - destroy the
* exisiting one */
yaffs_chunk_del(dev,
in->hdr_chunk,
1, __LINE__);
in->valid = 0;
} else {
/* Use existing - destroy this one. */
/* Use existing - destroy
* this one. */
yaffs_chunk_del(dev, chunk, 1,
__LINE__);
}
@ -261,7 +257,8 @@ int yaffs1_scan(struct yaffs_dev *dev)
(tags.obj_id == YAFFS_OBJECTID_ROOT ||
tags.obj_id ==
YAFFS_OBJECTID_LOSTNFOUND)) {
/* We only load some info, don't fiddle with directory structure */
/* We only load some info, don't fiddle
* with directory structure */
in->valid = 1;
in->variant_type = oh->type;
@ -300,37 +297,24 @@ int yaffs1_scan(struct yaffs_dev *dev)
parent->variant_type =
YAFFS_OBJECT_TYPE_DIRECTORY;
INIT_LIST_HEAD(&parent->
variant.dir_variant.children);
} else if (!parent
|| parent->variant_type !=
YAFFS_OBJECT_TYPE_DIRECTORY)
{
/* Hoosterman, another problem....
* We're trying to use a non-directory as a directory
variant.dir_variant.
children);
} else if (!parent ||
parent->variant_type !=
YAFFS_OBJECT_TYPE_DIRECTORY) {
/* Hoosterman, a problem....
* We're trying to use a
* non-directory as a directory
*/
T(YAFFS_TRACE_ERROR,
(TSTR
("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
TENDSTR)));
yaffs_trace(YAFFS_TRACE_ERROR,
"yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
);
parent = dev->lost_n_found;
}
yaffs_add_obj_to_dir(parent, in);
if (0 && (parent == dev->del_dir ||
parent ==
dev->unlinked_dir)) {
in->deleted = 1; /* If it is unlinked at start up then it wants deleting */
dev->n_deleted_files++;
}
/* Note re hardlinks.
* Since we might scan a hardlink before its equivalent object is scanned
* we put them all in a list.
* After scanning is complete, we should have all the objects, so we run through this
* list and fix up all the chains.
*/
switch (in->variant_type) {
case YAFFS_OBJECT_TYPE_UNKNOWN:
/* Todo got a problem */
@ -340,7 +324,7 @@ int yaffs1_scan(struct yaffs_dev *dev)
use_header_file_size)
in->variant.
file_variant.file_size
file_variant.file_size
= oh->file_size;
break;
@ -368,18 +352,19 @@ int yaffs1_scan(struct yaffs_dev *dev)
alloc_failed = 1;
break;
}
}
}
}
if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
/* If we got this far while scanning, then the block is fully allocated. */
/* If we got this far while scanning,
* then the block is fully allocated. */
state = YAFFS_BLOCK_STATE_FULL;
}
if (state == YAFFS_BLOCK_STATE_ALLOCATING) {
/* If the block was partially allocated then treat it as fully allocated. */
/* If the block was partially allocated then
* treat it as fully allocated. */
state = YAFFS_BLOCK_STATE_FULL;
dev->alloc_block = -1;
}
@ -392,13 +377,12 @@ int yaffs1_scan(struct yaffs_dev *dev)
bi->block_state == YAFFS_BLOCK_STATE_FULL) {
yaffs_block_became_dirty(dev, blk);
}
}
/* Ok, we've done all the scanning.
* Fix up the hard link chains.
* We should now have scanned all the objects, now it's time to add these
* hardlinks.
* We should now have scanned all the objects, now it's time to add
* these hardlinks.
*/
yaffs_link_fixup(dev, hard_list);
@ -411,8 +395,9 @@ int yaffs1_scan(struct yaffs_dev *dev)
while (shadow_fixers) {
fixer = shadow_fixers;
shadow_fixers = fixer->next;
/* Complete the rename transaction by deleting the shadowed object
* then setting the object header to unshadowed.
/* Complete the rename transaction by deleting the
* shadowed object then setting the object header
to unshadowed.
*/
obj = yaffs_find_by_number(dev, fixer->shadowed_id);
if (obj)
@ -423,7 +408,7 @@ int yaffs1_scan(struct yaffs_dev *dev)
if (obj)
yaffs_update_oh(obj, NULL, 1, 0, 0, NULL);
YFREE(fixer);
kfree(fixer);
}
}
@ -432,7 +417,7 @@ int yaffs1_scan(struct yaffs_dev *dev)
if (alloc_failed)
return YAFFS_FAIL;
T(YAFFS_TRACE_SCAN, (TSTR("yaffs1_scan ends" TENDSTR)));
yaffs_trace(YAFFS_TRACE_SCAN, "yaffs1_scan ends");
return YAFFS_OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -24,15 +24,9 @@
#define MTD_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
#if defined CONFIG_YAFFS_WINCE
#include "ywinceenv.h"
#elif defined __KERNEL__
#ifdef YAFFS_OUT_OF_TREE
#include "moduleconfig.h"
/* Linux kernel */
#endif
#include <linux/version.h>
#define MTD_VERSION_CODE LINUX_VERSION_CODE
@ -53,33 +47,15 @@
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/sort.h>
#include <linux/bitops.h>
#define YCHAR char
#define YUCHAR unsigned char
#define _Y(x) x
#define yaffs_strcat(a, b) strcat(a, b)
#define yaffs_strcpy(a, b) strcpy(a, b)
#define yaffs_strncpy(a, b, c) strncpy(a, b, c)
#define yaffs_strncmp(a, b, c) strncmp(a, b, c)
#define yaffs_strnlen(s,m) strnlen(s,m)
#define yaffs_sprintf sprintf
#define yaffs_toupper(a) toupper(a)
#define yaffs_sort(base, n, sz, cmp_fn) sort(base, n, sz, cmp_fn, NULL)
#define Y_INLINE __inline__
#define YAFFS_LOSTNFOUND_NAME "lost+found"
#define YAFFS_LOSTNFOUND_PREFIX "obj"
/* #define YPRINTF(x) printk x */
#define YMALLOC(x) kmalloc(x, GFP_NOFS)
#define YFREE(x) kfree(x)
#define YMALLOC_ALT(x) vmalloc(x)
#define YFREE_ALT(x) vfree(x)
#define YMALLOC_DMA(x) YMALLOC(x)
#define YYIELD() schedule()
#define Y_DUMP_STACK() dump_stack()
#define YAFFS_ROOT_MODE 0755
#define YAFFS_LOSTNFOUND_MODE 0700
@ -92,246 +68,24 @@
#define Y_TIME_CONVERT(x) (x)
#endif
#define yaffs_sum_cmp(x, y) ((x) == (y))
#define yaffs_strcmp(a, b) strcmp(a, b)
#define TENDSTR "\n"
#define TSTR(x) KERN_DEBUG x
#define TCONT(x) x
#define TOUT(p) printk p
#define compile_time_assertion(assertion) \
({ int x = __builtin_choose_expr(assertion, 0, (void)0); (void) x; })
#elif defined CONFIG_YAFFS_DIRECT
#define MTD_VERSION_CODE MTD_VERSION(2, 6, 22)
/* Direct interface */
#include "ydirectenv.h"
#elif defined CONFIG_YAFFS_UTIL
/* Stuff for YAFFS utilities */
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#define YMALLOC(x) malloc(x)
#define YFREE(x) free(x)
#define YMALLOC_ALT(x) malloc(x)
#define YFREE_ALT(x) free(x)
#define YCHAR char
#define YUCHAR unsigned char
#define _Y(x) x
#define yaffs_strcat(a, b) strcat(a, b)
#define yaffs_strcpy(a, b) strcpy(a, b)
#define yaffs_strncpy(a, b, c) strncpy(a, b, c)
#define yaffs_strnlen(s,m) strnlen(s,m)
#define yaffs_sprintf sprintf
#define yaffs_toupper(a) toupper(a)
#define Y_INLINE inline
/* #define YINFO(s) YPRINTF(( __FILE__ " %d %s\n",__LINE__,s)) */
/* #define YALERT(s) YINFO(s) */
#define TENDSTR "\n"
#define TSTR(x) x
#define TOUT(p) printf p
#define YAFFS_LOSTNFOUND_NAME "lost+found"
#define YAFFS_LOSTNFOUND_PREFIX "obj"
/* #define YPRINTF(x) printf x */
#define YAFFS_ROOT_MODE 0755
#define YAFFS_LOSTNFOUND_MODE 0700
#define yaffs_sum_cmp(x, y) ((x) == (y))
#define yaffs_strcmp(a, b) strcmp(a, b)
#else
/* Should have specified a configuration type */
#error Unknown configuration
#endif
#if defined(CONFIG_YAFFS_DIRECT) || defined(CONFIG_YAFFS_WINCE)
#ifdef CONFIG_YAFFSFS_PROVIDE_VALUES
#ifndef O_RDONLY
#define O_RDONLY 00
#endif
#ifndef O_WRONLY
#define O_WRONLY 01
#endif
#ifndef O_RDWR
#define O_RDWR 02
#endif
#ifndef O_CREAT
#define O_CREAT 0100
#endif
#ifndef O_EXCL
#define O_EXCL 0200
#endif
#ifndef O_TRUNC
#define O_TRUNC 01000
#endif
#ifndef O_APPEND
#define O_APPEND 02000
#endif
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif
#ifndef EBUSY
#define EBUSY 16
#endif
#ifndef ENODEV
#define ENODEV 19
#endif
#ifndef EINVAL
#define EINVAL 22
#endif
#ifndef ENFILE
#define ENFILE 23
#endif
#ifndef EBADF
#define EBADF 9
#endif
#ifndef EACCES
#define EACCES 13
#endif
#ifndef EXDEV
#define EXDEV 18
#endif
#ifndef ENOENT
#define ENOENT 2
#endif
#ifndef ENOSPC
#define ENOSPC 28
#endif
#ifndef ERANGE
#define ERANGE 34
#endif
#ifndef ENODATA
#define ENODATA 61
#endif
#ifndef ENOTEMPTY
#define ENOTEMPTY 39
#endif
#ifndef ENAMETOOLONG
#define ENAMETOOLONG 36
#endif
#ifndef ENOMEM
#define ENOMEM 12
#endif
#ifndef EEXIST
#define EEXIST 17
#endif
#ifndef ENOTDIR
#define ENOTDIR 20
#endif
#ifndef EISDIR
#define EISDIR 21
#endif
// Mode flags
#ifndef S_IFMT
#define S_IFMT 0170000
#endif
#ifndef S_IFLNK
#define S_IFLNK 0120000
#endif
#ifndef S_IFDIR
#define S_IFDIR 0040000
#endif
#ifndef S_IFREG
#define S_IFREG 0100000
#endif
#ifndef S_IREAD
#define S_IREAD 0000400
#endif
#ifndef S_IWRITE
#define S_IWRITE 0000200
#endif
#ifndef S_IEXEC
#define S_IEXEC 0000100
#endif
#ifndef XATTR_CREATE
#define XATTR_CREATE 1
#endif
#ifndef XATTR_REPLACE
#define XATTR_REPLACE 2
#endif
#ifndef R_OK
#define R_OK 4
#define W_OK 2
#define X_OK 1
#define F_OK 0
#endif
#else
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
#endif
#ifndef Y_DUMP_STACK
#define Y_DUMP_STACK() do { } while (0)
#define Y_DUMP_STACK() dump_stack()
#endif
#define yaffs_trace(msk, fmt, ...) do { \
if (yaffs_trace_mask & (msk)) \
printk(KERN_DEBUG "yaffs: " fmt "\n", ##__VA_ARGS__); \
} while (0)
#ifndef YBUG
#define YBUG() do {\
T(YAFFS_TRACE_BUG,\
(TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR),\
__LINE__));\
yaffs_trace(YAFFS_TRACE_BUG,\
"bug " __FILE__ " %d",\
__LINE__);\
Y_DUMP_STACK();\
} while (0)
#endif