X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_checkptrw.c;h=7faf2860f923775952300824a34562d152641ad7;hp=711df13e5cd36ef18523f8eacec75b3d23ee1cb8;hb=6500cebaa2c93512d544719956af259ca13f83b7;hpb=6120ba5a0a029e945f4a2e7e5955896f112d4adc diff --git a/yaffs_checkptrw.c b/yaffs_checkptrw.c index 711df13..7faf286 100644 --- a/yaffs_checkptrw.c +++ b/yaffs_checkptrw.c @@ -137,6 +137,8 @@ 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; /* Got the functions we need? */ @@ -167,25 +169,24 @@ 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; } @@ -308,49 +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; @@ -358,18 +357,20 @@ 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; @@ -379,7 +380,7 @@ int yaffs_checkpt_close(struct yaffs_dev *dev) } 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",