From: Charles Manning Date: Mon, 21 May 2012 22:28:11 +0000 (+1200) Subject: yaffs2 checkpointing: Add further checkpoint data sanity checking X-Git-Tag: pre-driver-refactoring~10 X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=commitdiff_plain;h=662466a25f6c97bba330ad5d9e9ba215ca8874ee yaffs2 checkpointing: Add further checkpoint data sanity checking Add a header to each chunk of checkpoint data to verify that the checkpoint data is correct. Signed-off-by: Charles Manning --- diff --git a/direct/basic-test/dtest.c b/direct/basic-test/dtest.c index e3abe0f..153d274 100644 --- a/direct/basic-test/dtest.c +++ b/direct/basic-test/dtest.c @@ -2791,7 +2791,9 @@ void max_files_test(const char *mountpt) result = yaffs_close(h); } - h =yaffs_open(hn,O_RDWR,0); + yaffs_unmount(mountpt); + + //h =yaffs_open(hn,O_RDWR,0); } void case_insensitive_test(const char *mountpt) @@ -3147,12 +3149,12 @@ int main(int argc, char *argv[]) // link_follow_test("/yaffs2"); //basic_utime_test("/yaffs2"); - //max_files_test("/yaffs2"); + max_files_test("/yaffs2"); //start_twice("/yaffs2"); //large_file_test("/yaffs2"); - readdir_test("/yaffs2"); + //readdir_test("/yaffs2"); //basic_utime_test("/yaffs2"); //case_insensitive_test("/yaffs2"); diff --git a/yaffs_checkptrw.c b/yaffs_checkptrw.c index 918c382..d897044 100644 --- a/yaffs_checkptrw.c +++ b/yaffs_checkptrw.c @@ -14,6 +14,41 @@ #include "yaffs_checkptrw.h" #include "yaffs_getblockinfo.h" +struct yaffs_checkpt_chunk_hdr { + int version; + int seq; + u32 sum; + u32 xor; +} ; + +static void yaffs2_checkpt_init_chunk_hdr(struct yaffs_dev *dev) +{ + struct yaffs_checkpt_chunk_hdr hdr; + + hdr.version = YAFFS_CHECKPOINT_VERSION; + hdr.seq = dev->checkpt_page_seq; + hdr.sum = dev->checkpt_sum; + hdr.xor = dev->checkpt_xor; + + dev->checkpt_byte_offs = sizeof(hdr); + + memcpy(dev->checkpt_buffer, &hdr, sizeof(hdr)); +} + +static int yaffs2_checkpt_check_chunk_hdr(struct yaffs_dev *dev) +{ + struct yaffs_checkpt_chunk_hdr hdr; + + memcpy(&hdr, dev->checkpt_buffer, sizeof(hdr)); + + dev->checkpt_byte_offs = sizeof(hdr); + + return hdr.version == YAFFS_CHECKPOINT_VERSION && + hdr.seq == dev->checkpt_page_seq && + hdr.sum == dev->checkpt_sum && + hdr.xor == dev->checkpt_xor; +} + static int yaffs2_checkpt_space_ok(struct yaffs_dev *dev) { int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks; @@ -171,13 +206,13 @@ int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing) dev->checkpt_cur_chunk = -1; dev->checkpt_next_block = dev->internal_start_block; - /* Erase all the blocks in the checkpoint area */ if (writing) { memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk); - dev->checkpt_byte_offs = 0; + yaffs2_checkpt_init_chunk_hdr(dev); return yaffs_checkpt_erase(dev); } + /* Opening for a read */ /* 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 @@ -249,7 +284,6 @@ static int yaffs2_checkpt_flush_buffer(struct yaffs_dev *dev) dev->param.write_chunk_tags_fn(dev, realigned_chunk, dev->checkpt_buffer, &tags); - dev->checkpt_byte_offs = 0; dev->checkpt_page_seq++; dev->checkpt_cur_chunk++; if (dev->checkpt_cur_chunk >= dev->param.chunks_per_block) { @@ -258,6 +292,9 @@ static int yaffs2_checkpt_flush_buffer(struct yaffs_dev *dev) } memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk); + yaffs2_checkpt_init_chunk_hdr(dev); + + return 1; } @@ -340,14 +377,18 @@ int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes) ok = 0; break; } + if(!yaffs2_checkpt_check_chunk_hdr(dev)) { + 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]; @@ -367,7 +408,8 @@ int yaffs_checkpt_close(struct yaffs_dev *dev) int i; if (dev->checkpt_open_write) { - if (dev->checkpt_byte_offs != 0) + if (dev->checkpt_byte_offs != + sizeof(sizeof(struct yaffs_checkpt_chunk_hdr))) yaffs2_checkpt_flush_buffer(dev); } else if (dev->checkpt_block_list) { for (i = 0; diff --git a/yaffs_guts.h b/yaffs_guts.h index e3558c5..d320070 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -77,7 +77,7 @@ /* Binary data version stamps */ #define YAFFS_SUMMARY_VERSION 1 -#define YAFFS_CHECKPOINT_VERSION 6 +#define YAFFS_CHECKPOINT_VERSION 7 #ifdef CONFIG_YAFFS_UNICODE #define YAFFS_MAX_NAME_LENGTH 127