X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_checkptrw.c;h=5f5a4758e5559f259b6d7f7ca5b1d99a265d32d2;hp=4e40f437e655e8a04873c325f608a8cdd64238a2;hb=6648cbf52d6695755941ff8607fd7a0cda542e05;hpb=d223baa0fa5644b48c2626f8d42b05ac45b1daf6 diff --git a/yaffs_checkptrw.c b/yaffs_checkptrw.c index 4e40f43..5f5a475 100644 --- a/yaffs_checkptrw.c +++ b/yaffs_checkptrw.c @@ -1,7 +1,7 @@ /* * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. * - * Copyright (C) 2002-2010 Aleph One Ltd. + * Copyright (C) 2002-2011 Aleph One Ltd. * for Toby Churchill Ltd and Brightstar Engineering * * Created by Charles Manning @@ -44,7 +44,7 @@ static int yaffs_checkpt_erase(struct yaffs_dev *dev) 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,6 +65,7 @@ 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; + 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, @@ -136,6 +137,7 @@ static void yaffs2_checkpt_find_block(struct yaffs_dev *dev) int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing) { + int i; dev->checkpt_open_write = writing; @@ -167,31 +169,31 @@ int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing) memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk); dev->checkpt_byte_offs = 0; return yaffs_checkpt_erase(dev); - } else { - 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 */ - dev->blocks_in_checkpt = 0; - dev->checkpt_max_blocks = - (dev->internal_end_block - dev->internal_start_block) / 16 + - 2; - dev->checkpt_block_list = - kmalloc(sizeof(int) * dev->checkpt_max_blocks, GFP_NOFS); - if (!dev->checkpt_block_list) - return 0; - - for (i = 0; i < dev->checkpt_max_blocks; i++) - dev->checkpt_block_list[i] = -1; } + /* 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 */ + dev->blocks_in_checkpt = 0; + dev->checkpt_max_blocks = + (dev->internal_end_block - dev->internal_start_block) / 16 + 2; + dev->checkpt_block_list = + kmalloc(sizeof(int) * dev->checkpt_max_blocks, GFP_NOFS); + + if (!dev->checkpt_block_list) + return 0; + + for (i = 0; i < dev->checkpt_max_blocks; i++) + dev->checkpt_block_list[i] = -1; + return 1; } 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; @@ -201,7 +203,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) { @@ -257,7 +258,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) @@ -289,10 +289,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) @@ -311,50 +309,47 @@ int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes) dev->checkpt_cur_chunk = 0; } - if (dev->checkpt_cur_block < 0) + if (dev->checkpt_cur_block < 0) { ok = 0; - else { - chunk = dev->checkpt_cur_block * - dev->param.chunks_per_block + - dev->checkpt_cur_chunk; - - realigned_chunk = chunk - dev->chunk_offset; - - dev->n_page_reads++; - - /* read in the next chunk */ - dev->param.read_chunk_tags_fn(dev, - realigned_chunk, - dev-> - checkpt_buffer, - &tags); - - if (tags.chunk_id != (dev->checkpt_page_seq + 1) - || tags.ecc_result > YAFFS_ECC_RESULT_FIXED - || tags.seq_number != - YAFFS_SEQUENCE_CHECKPOINT_DATA) - ok = 0; - - dev->checkpt_byte_offs = 0; - dev->checkpt_page_seq++; - dev->checkpt_cur_chunk++; - - if (dev->checkpt_cur_chunk >= - dev->param.chunks_per_block) - dev->checkpt_cur_block = -1; + break; } - } - if (ok) { - *data_bytes = - dev->checkpt_buffer[dev->checkpt_byte_offs]; - dev->checkpt_sum += *data_bytes; - dev->checkpt_xor ^= *data_bytes; - dev->checkpt_byte_offs++; - i++; - data_bytes++; - dev->checkpt_byte_count++; + chunk = dev->checkpt_cur_block * + dev->param.chunks_per_block + + dev->checkpt_cur_chunk; + + realigned_chunk = chunk - dev->chunk_offset; + dev->n_page_reads++; + + /* read in the next chunk */ + dev->param.read_chunk_tags_fn(dev, + realigned_chunk, + dev->checkpt_buffer, + &tags); + + if (tags.chunk_id != (dev->checkpt_page_seq + 1) || + tags.ecc_result > YAFFS_ECC_RESULT_FIXED || + tags.seq_number != YAFFS_SEQUENCE_CHECKPOINT_DATA) { + ok = 0; + break; + } + + dev->checkpt_byte_offs = 0; + dev->checkpt_page_seq++; + dev->checkpt_cur_chunk++; + + if (dev->checkpt_cur_chunk >= + dev->param.chunks_per_block) + dev->checkpt_cur_block = -1; } + + *data_bytes = dev->checkpt_buffer[dev->checkpt_byte_offs]; + dev->checkpt_sum += *data_bytes; + dev->checkpt_xor ^= *data_bytes; + dev->checkpt_byte_offs++; + i++; + data_bytes++; + dev->checkpt_byte_count++; } return i; @@ -362,35 +357,33 @@ int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes) int yaffs_checkpt_close(struct yaffs_dev *dev) { + int i; if (dev->checkpt_open_write) { if (dev->checkpt_byte_offs != 0) yaffs2_checkpt_flush_buffer(dev); } else if (dev->checkpt_block_list) { - int i; for (i = 0; - i < dev->blocks_in_checkpt - && dev->checkpt_block_list[i] >= 0; i++) { + i < dev->blocks_in_checkpt && + dev->checkpt_block_list[i] >= 0; i++) { int blk = dev->checkpt_block_list[i]; struct yaffs_block_info *bi = NULL; - if (dev->internal_start_block <= blk - && blk <= dev->internal_end_block) + + if (dev->internal_start_block <= blk && + blk <= dev->internal_end_block) 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... */ - } } kfree(dev->checkpt_block_list); dev->checkpt_block_list = NULL; } dev->n_free_chunks -= - dev->blocks_in_checkpt * dev->param.chunks_per_block; + dev->blocks_in_checkpt * dev->param.chunks_per_block; dev->n_erased_blocks -= dev->blocks_in_checkpt; - yaffs_trace(YAFFS_TRACE_CHECKPOINT,"checkpoint byte count %d", + yaffs_trace(YAFFS_TRACE_CHECKPOINT, "checkpoint byte count %d", dev->checkpt_byte_count); if (dev->checkpt_buffer) { @@ -400,7 +393,7 @@ int yaffs_checkpt_close(struct yaffs_dev *dev) return 1; } else { return 0; - } + } } int yaffs2_checkpt_invalidate_stream(struct yaffs_dev *dev)