#define YAFFS_GC_GOOD_ENOUGH 2
#define YAFFS_GC_PASSIVE_THRESHOLD 4
+#define YAFFS_MAX_CACHE_USAGE 100000000
+
#include "yaffs_ecc.h"
/* Forward declarations */
static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk,
- const u8 *buffer, int n_bytes, int use_reserve);
+ const u8 *buffer, u32 n_bytes, int use_reserve);
static void yaffs_fix_null_name(struct yaffs_obj *obj, YCHAR *name,
int buffer_size);
/* Function to calculate chunk and offset */
void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
- int *chunk_out, u32 *offset_out)
+ u32 *chunk_out, u32 *offset_out)
{
- int chunk;
+ u32 chunk;
u32 offset;
chunk = (u32) (addr >> dev->chunk_shift);
* be hellishly efficient.
*/
-static inline u32 calc_shifts_ceiling(u32 x)
+static inline u32 yaffs_calc_shifts_ceiling(u32 x)
{
int extra_bits;
int shifts;
}
}
-static void yaffs_handle_chunk_wr_error(struct yaffs_dev *dev, int nand_chunk,
+static void yaffs_handle_chunk_wr_error(struct yaffs_dev *dev, u32 nand_chunk,
int erased_ok)
{
- int flash_block = nand_chunk / dev->param.chunks_per_block;
+ u32 flash_block = nand_chunk / dev->param.chunks_per_block;
struct yaffs_block_info *bi = yaffs_get_block_info(dev, flash_block);
yaffs_handle_chunk_error(dev, bi, YAFFS_ECC_RESULT_FIXED);
int retval = YAFFS_OK;
u8 *data = yaffs_get_temp_buffer(dev);
struct yaffs_ext_tags tags;
- int result;
- result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, data, &tags);
+ yaffs_rd_chunk_tags_nand(dev, nand_chunk, data, &tags);
if (tags.ecc_result > YAFFS_ECC_RESULT_NO_ERROR)
retval = YAFFS_FAIL;
int retval = YAFFS_OK;
struct yaffs_ext_tags temp_tags;
u8 *buffer = yaffs_get_temp_buffer(dev);
- int result;
- result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, buffer, &temp_tags);
+ yaffs_rd_chunk_tags_nand(dev, nand_chunk, buffer, &temp_tags);
if (memcmp(buffer, data, dev->data_bytes_per_chunk) ||
temp_tags.obj_id != tags->obj_id ||
temp_tags.chunk_id != tags->chunk_id ||
static int yaffs_find_alloc_block(struct yaffs_dev *dev)
{
- int i;
+ u32 i;
struct yaffs_block_info *bi;
if (dev->n_erased_blocks < 1) {
return -1;
}
- if (dev->n_erased_blocks < dev->param.n_reserved_blocks
+ if (dev->n_erased_blocks < (int)dev->param.n_reserved_blocks
&& dev->alloc_page == 0)
yaffs_trace(YAFFS_TRACE_ALLOCATE, "Allocating reserve");
dev->n_free_chunks--;
/* If the block is full set the state to full */
- if (dev->alloc_page >= dev->param.chunks_per_block) {
+ if (dev->alloc_page >= (int)dev->param.chunks_per_block) {
bi->block_state = YAFFS_BLOCK_STATE_FULL;
dev->alloc_block = -1;
}
char *ascii_oh_name = (char *)oh_name;
int n = YAFFS_MAX_NAME_LENGTH - 1;
while (n > 0 && *name) {
- *ascii_oh_name = *name;
+ *ascii_oh_name = (char)*name;
name++;
ascii_oh_name++;
n--;
* in the tree. 0 means only the level 0 tnode is in the tree.
*/
-/* FindLevel0Tnode finds the level 0 tnode, if one exists. */
+/* yaffs_find_tnode_0 finds the level 0 tnode, if one exists. */
struct yaffs_tnode *yaffs_find_tnode_0(struct yaffs_dev *dev,
struct yaffs_file_var *file_struct,
u32 chunk_id)
return tn;
}
-static int yaffs_tags_match(const struct yaffs_ext_tags *tags, int obj_id,
- int chunk_obj)
+static int yaffs_tags_match(const struct yaffs_ext_tags *tags, u32 obj_id,
+ u32 chunk_obj)
{
return (tags->chunk_id == chunk_obj &&
tags->obj_id == obj_id &&
}
-static int yaffs_find_chunk_in_group(struct yaffs_dev *dev, int the_chunk,
- struct yaffs_ext_tags *tags, int obj_id,
- int inode_chunk)
+static int yaffs_find_chunk_in_group(struct yaffs_dev *dev, u32 the_chunk,
+ struct yaffs_ext_tags *tags, u32 obj_id,
+ u32 inode_chunk)
{
- int j;
+ u32 j;
for (j = 0; the_chunk && j < dev->chunk_grp_size; j++) {
if (yaffs_check_chunk_bit
*/
static struct yaffs_cache *yaffs_grab_chunk_worker(struct yaffs_dev *dev)
{
- int i;
+ u32 i;
if (dev->param.n_caches > 0) {
for (i = 0; i < dev->param.n_caches; i++) {
static struct yaffs_cache *yaffs_grab_chunk_cache(struct yaffs_dev *dev)
{
struct yaffs_cache *cache;
- int usage;
- int i;
+ u32 usage;
+ u32 i;
if (dev->param.n_caches < 1)
return NULL;
* Find the LRU cache and flush it if it is dirty.
*/
- usage = -1;
+ usage = YAFFS_MAX_CACHE_USAGE + 100; /* Silly high number */
cache = NULL;
for (i = 0; i < dev->param.n_caches; i++) {
int chunk_id)
{
struct yaffs_dev *dev = obj->my_dev;
- int i;
+ u32 i;
if (dev->param.n_caches < 1)
return NULL;
static void yaffs_use_cache(struct yaffs_dev *dev, struct yaffs_cache *cache,
int is_write)
{
- int i;
-
if (dev->param.n_caches < 1)
return;
- if (dev->cache_last_use < 0 ||
- dev->cache_last_use > 100000000) {
+ if (dev->cache_last_use > YAFFS_MAX_CACHE_USAGE) {
+ u32 i;
+
/* Reset the cache usages */
for (i = 1; i < dev->param.n_caches; i++)
dev->cache[i].last_use = 0;
*/
static void yaffs_invalidate_whole_cache(struct yaffs_obj *in)
{
- int i;
+ u32 i;
struct yaffs_dev *dev = in->my_dev;
if (dev->param.n_caches > 0) {
return YAFFS_FAIL;
}
-
-void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no)
+void yaffs_block_became_dirty(struct yaffs_dev *dev, u32 block_no)
{
struct yaffs_block_info *bi = yaffs_get_block_info(dev, block_no);
int erased_ok = 0;
- int i;
+ u32 i;
/* If the block is still healthy erase it and mark as clean.
* If the block has had a data failure, then retire it.
{
int old_chunk;
int ret_val = YAFFS_OK;
- int i;
+ u32 i;
int is_checkpt_block;
int max_copies;
int chunks_before = yaffs_get_erased_chunks(dev);
static unsigned yaffs_find_gc_block(struct yaffs_dev *dev,
int aggressive, int background)
{
- int i;
- int iterations;
+ u32 i;
+ u32 iterations;
unsigned selected = 0;
int prioritised = 0;
int prioritised_exist = 0;
struct yaffs_block_info *bi;
- int threshold;
+ u32 threshold;
/* First let's see if we need to grab a prioritised block */
if (dev->has_pending_prioritised_gc && !aggressive) {
*/
if (!selected) {
- int pages_used;
- int n_blocks =
+ u32 pages_used;
+ u32 n_blocks =
dev->internal_end_block - dev->internal_start_block + 1;
if (aggressive) {
threshold = dev->param.chunks_per_block;
iterations = n_blocks;
} else {
- int max_threshold;
+ u32 max_threshold;
if (background)
max_threshold = dev->param.chunks_per_block / 2;
*/
if (!selected && dev->param.is_yaffs2 &&
- dev->gc_not_done >= (background ? 10 : 20)) {
+ dev->gc_not_done >= (unsigned)(background ? 10 : 20)) {
yaffs2_find_oldest_dirty_seq(dev);
if (dev->oldest_dirty_block > 0) {
selected = dev->oldest_dirty_block;
gc_ok = yaffs_gc_block(dev, dev->gc_block, aggressive);
}
- if (dev->n_erased_blocks < (dev->param.n_reserved_blocks) &&
+ if (dev->n_erased_blocks < (int)dev->param.n_reserved_blocks &&
dev->gc_block > 0) {
yaffs_trace(YAFFS_TRACE_GC,
"yaffs: GC !!!no reclaim!!! n_erased_blocks %d after try %d block %d",
dev->n_erased_blocks, max_tries,
dev->gc_block);
}
- } while ((dev->n_erased_blocks < dev->param.n_reserved_blocks) &&
+ } while ((dev->n_erased_blocks < (int)dev->param.n_reserved_blocks) &&
(dev->gc_block > 0) && (max_tries < 2));
return aggressive ? gc_ok : YAFFS_OK;
}
static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk,
- const u8 *buffer, int n_bytes, int use_reserve)
+ const u8 *buffer, u32 n_bytes, int use_reserve)
{
/* Find old chunk Need to do this to get serial number
* Write new one and patch into tree.
if (n_bytes < 1 || n_bytes > dev->param.total_bytes_per_chunk) {
yaffs_trace(YAFFS_TRACE_ERROR,
- "Writing %d bytes to chunk!!!!!!!!!",
+ "Writing %u bytes to chunk!!!!!!!!!",
n_bytes);
BUG();
}
struct yaffs_obj_hdr *oh;
struct yaffs_dev *dev;
struct yaffs_ext_tags tags;
- int result;
- int alloc_failed = 0;
if (!in || !in->lazy_loaded || in->hdr_chunk < 1)
return;
in->lazy_loaded = 0;
buf = yaffs_get_temp_buffer(dev);
- result = yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, buf, &tags);
+ yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, buf, &tags);
oh = (struct yaffs_obj_hdr *)buf;
in->yst_mode = oh->yst_mode;
if (in->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) {
in->variant.symlink_variant.alias =
yaffs_clone_str(oh->alias);
- if (!in->variant.symlink_variant.alias)
- alloc_failed = 1; /* Not returned */
}
yaffs_release_temp_buffer(dev, buf);
}
struct yaffs_dev *dev = in->my_dev;
int prev_chunk_id;
int ret_val = 0;
- int result = 0;
int new_chunk_id;
struct yaffs_ext_tags new_tags;
struct yaffs_ext_tags old_tags;
prev_chunk_id = in->hdr_chunk;
if (prev_chunk_id > 0) {
- result = yaffs_rd_chunk_tags_nand(dev, prev_chunk_id,
+ yaffs_rd_chunk_tags_nand(dev, prev_chunk_id,
buffer, &old_tags);
yaffs_verify_oh(in, oh, &old_tags, 0);
* Curve-balls: the first chunk might also be the last chunk.
*/
-int yaffs_file_rd(struct yaffs_obj *in, u8 * buffer, loff_t offset, int n_bytes)
+int yaffs_file_rd(struct yaffs_obj *in, u8 * buffer, loff_t offset, u32 n_bytes)
{
- int chunk;
+ u32 chunk;
u32 start;
- int n_copy;
- int n = n_bytes;
- int n_done = 0;
+ u32 n_copy;
+ u32 n = n_bytes;
+ u32 n_done = 0;
struct yaffs_cache *cache;
struct yaffs_dev *dev;
buffer += n_copy;
n_done += n_copy;
}
- return n_done;
+ return (int)n_done;
}
int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
- int n_bytes, int write_through)
+ u32 n_bytes, int write_through)
{
- int chunk;
+ u32 chunk;
u32 start;
- int n_copy;
- int n = n_bytes;
- int n_done = 0;
- int n_writeback;
+ u32 n_copy;
+ u32 n = n_bytes;
+ u32 n_done = 0;
+ u32 n_writeback;
loff_t start_write = offset;
int chunk_written = 0;
u32 n_bytes_read;
dev->data_bytes_per_chunk + start != offset ||
start >= dev->data_bytes_per_chunk) {
yaffs_trace(YAFFS_TRACE_ERROR,
- "AddrToChunk of offset %lld gives chunk %d start %d",
- offset, chunk, start);
+ "addr_to_chunk() of offset %lld gives chunk %u start %u",
+ (long long int)offset, chunk, start);
}
chunk++; /* File pos to chunk in file offset */
n_bytes_read = dev->data_bytes_per_chunk;
n_writeback =
- (n_bytes_read >
- (start + n)) ? n_bytes_read : (start + n);
+ (n_bytes_read > (start + n)) ?
+ n_bytes_read : (start + n);
- if (n_writeback < 0 ||
- n_writeback > dev->data_bytes_per_chunk)
+ if (n_writeback > dev->data_bytes_per_chunk)
BUG();
} else {
/* Update file object */
- if ((start_write + n_done) > in->variant.file_variant.file_size)
+ if ((start_write + n_done) > (u32)in->variant.file_variant.file_size)
in->variant.file_variant.file_size = (start_write + n_done);
in->dirty = 1;
}
int yaffs_wr_file(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
- int n_bytes, int write_through)
+ u32 n_bytes, int write_through)
{
yaffs2_handle_hole(in, offset);
return yaffs_do_file_wr(in, buffer, offset, n_bytes, write_through);
struct yaffs_dev *dev = in->my_dev;
loff_t old_size = in->variant.file_variant.file_size;
- int i;
+ u32 i;
int chunk_id;
u32 dummy;
- int last_del;
- int start_del;
+ u32 last_del;
+ u32 start_del;
if (old_size > 0)
yaffs_addr_to_chunk(dev, old_size - 1, &last_del, &dummy);
if (chunk_id < 1)
continue;
- if (chunk_id <
+ if ((u32)chunk_id <
(dev->internal_start_block * dev->param.chunks_per_block) ||
- chunk_id >=
+ (u32)chunk_id >=
((dev->internal_end_block + 1) *
dev->param.chunks_per_block)) {
yaffs_trace(YAFFS_TRACE_ALWAYS,
void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size)
{
- int new_full;
+ u32 new_full;
u32 new_partial;
struct yaffs_dev *dev = obj->my_dev;
/*----------------------- Initialisation Scanning ---------------------- */
-void yaffs_handle_shadowed_obj(struct yaffs_dev *dev, int obj_id,
+void yaffs_handle_shadowed_obj(struct yaffs_dev *dev, u32 obj_id,
int backward_scanning)
{
struct yaffs_obj *obj;
} else if (obj->short_name[0]) {
strcpy(name, obj->short_name);
} else if (obj->hdr_chunk > 0) {
- int result;
u8 *buffer = yaffs_get_temp_buffer(obj->my_dev);
struct yaffs_obj_hdr *oh = (struct yaffs_obj_hdr *)buffer;
memset(buffer, 0, obj->my_dev->data_bytes_per_chunk);
- if (obj->hdr_chunk > 0) {
- result = yaffs_rd_chunk_tags_nand(obj->my_dev,
+ if (obj->hdr_chunk > 0)
+ yaffs_rd_chunk_tags_nand(obj->my_dev,
obj->hdr_chunk,
buffer, NULL);
- }
+
yaffs_load_name_from_oh(obj->my_dev, name, oh->name,
buffer_size);
int yaffs_guts_format_dev(struct yaffs_dev *dev)
{
- int i;
+ u32 i;
enum yaffs_block_state state;
u32 dummy;
{
int init_failed = 0;
unsigned x;
- int bits;
+ unsigned bits;
if(yaffs_guts_ll_init(dev) != YAFFS_OK)
return YAFFS_FAIL;
x = dev->param.chunks_per_block * (dev->internal_end_block + 1);
- bits = calc_shifts_ceiling(x);
+ bits = yaffs_calc_shifts_ceiling(x);
/* Set up tnode width if wide tnodes are enabled. */
if (!dev->param.wide_tnodes_disabled) {
dev->gc_cleanup_list = NULL;
if (!init_failed && dev->param.n_caches > 0) {
- int i;
+ u32 i;
void *buf;
int cache_bytes =
dev->param.n_caches * sizeof(struct yaffs_cache);
void yaffs_deinitialise(struct yaffs_dev *dev)
{
if (dev->is_mounted) {
- int i;
+ u32 i;
yaffs_deinit_blocks(dev);
yaffs_deinit_tnodes_and_objs(dev);
int yaffs_count_free_chunks(struct yaffs_dev *dev)
{
- int n_free = 0;
- int b;
+ u32 n_free = 0;
+ u32 b;
struct yaffs_block_info *blk;
blk = dev->block_info;
}
blk++;
}
- return n_free;
+ return (int)n_free;
}
int yaffs_get_n_free_chunks(struct yaffs_dev *dev)
int n_free;
int n_dirty_caches;
int blocks_for_checkpt;
- int i;
+ u32 i;
n_free = dev->n_free_chunks;
n_free += dev->n_deleted_files;
*/
void yaffs_oh_size_load(struct yaffs_obj_hdr *oh, loff_t fsize)
{
+ int shift = 32;
+
oh->file_size_low = (fsize & 0xFFFFFFFF);
- oh->file_size_high = ((fsize >> 32) & 0xFFFFFFFF);
+ if (sizeof(loff_t) >= 8)
+ oh->file_size_high = ((fsize >> shift) & 0xFFFFFFFF);
+ else
+ oh->file_size_high = 0;
}
loff_t yaffs_oh_to_size(struct yaffs_obj_hdr *oh)
{
+ int shift = 32;
loff_t retval;
if (sizeof(loff_t) >= 8 && ~(oh->file_size_high))
- retval = (((loff_t) oh->file_size_high) << 32) |
+ retval = (((loff_t) oh->file_size_high) << shift) |
(((loff_t) oh->file_size_low) & 0xFFFFFFFF);
else
retval = (loff_t) oh->file_size_low;
void yaffs_count_blocks_by_state(struct yaffs_dev *dev, int bs[10])
{
- int i;
+ u32 i;
struct yaffs_block_info *bi;
int s;