yaffs: moved to newest official xyaffs driver
This commit is contained in:
parent
fc0148dc57
commit
1130964c5c
@ -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.
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -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
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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))) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user