X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=dfabf4c29d23ea75e1b0e9bfb4d0b6a5e7360ab4;hp=403ce11bb2cea2a0022ca496beec118f7fa0e1e8;hb=7cf801a7e52bba91529fbc9f29be50bec808a545;hpb=472c70456396a6f2019bfabe83bd292782dbd978 diff --git a/yaffs_guts.c b/yaffs_guts.c index 403ce11..dfabf4c 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -15,7 +15,6 @@ #include "yaffs_trace.h" #include "yaffs_guts.h" -#include "yaffs_tagsvalidity.h" #include "yaffs_getblockinfo.h" #include "yaffs_tagscompat.h" #include "yaffs_nand.h" @@ -28,6 +27,7 @@ #include "yaffs_nameval.h" #include "yaffs_allocator.h" #include "yaffs_attribs.h" +#include "yaffs_summary.h" /* Note YAFFS_GC_GOOD_ENOUGH must be <= YAFFS_GC_PASSIVE_THRESHOLD */ #define YAFFS_GC_GOOD_ENOUGH 2 @@ -128,44 +128,30 @@ static int yaffs_init_tmp_buffers(struct yaffs_dev *dev) memset(dev->temp_buffer, 0, sizeof(dev->temp_buffer)); for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) { - dev->temp_buffer[i].line = 0; /* not in use */ - dev->temp_buffer[i].buffer = buf = - kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS); + dev->temp_buffer[i].in_use = 0; + buf = kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS); + dev->temp_buffer[i].buffer = buf; } return buf ? YAFFS_OK : YAFFS_FAIL; } -u8 *yaffs_get_temp_buffer(struct yaffs_dev * dev, int line_no) +u8 *yaffs_get_temp_buffer(struct yaffs_dev * dev) { int i; - int j; dev->temp_in_use++; if (dev->temp_in_use > dev->max_temp) dev->max_temp = dev->temp_in_use; for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { - if (dev->temp_buffer[i].line == 0) { - dev->temp_buffer[i].line = line_no; - if ((i + 1) > dev->max_temp) { - dev->max_temp = i + 1; - for (j = 0; j <= i; j++) - dev->temp_buffer[j].max_line = - dev->temp_buffer[j].line; - } - + if (dev->temp_buffer[i].in_use == 0) { + dev->temp_buffer[i].in_use = 1; return dev->temp_buffer[i].buffer; } } - yaffs_trace(YAFFS_TRACE_BUFFERS, - "Out of temp buffers at line %d, other held by lines:", - line_no); - for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) - yaffs_trace(YAFFS_TRACE_BUFFERS, - " %d", dev->temp_buffer[i].line); - + yaffs_trace(YAFFS_TRACE_BUFFERS, "Out of temp buffers"); /* * If we got here then we have to allocate an unmanaged one * This is not good. @@ -176,7 +162,7 @@ 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 i; @@ -184,16 +170,14 @@ void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer, int line_no) for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { if (dev->temp_buffer[i].buffer == buffer) { - dev->temp_buffer[i].line = 0; + dev->temp_buffer[i].in_use = 0; return; } } if (buffer) { /* assume it is an unmanaged one. */ - yaffs_trace(YAFFS_TRACE_BUFFERS, - "Releasing unmanaged temp buffer in line %d", - line_no); + yaffs_trace(YAFFS_TRACE_BUFFERS, "Releasing unmanaged temp buffer"); kfree(buffer); dev->unmanaged_buffer_deallocs++; } @@ -333,7 +317,7 @@ int yaffs_check_ff(u8 *buffer, int n_bytes) static int yaffs_check_chunk_erased(struct yaffs_dev *dev, int nand_chunk) { int retval = YAFFS_OK; - u8 *data = yaffs_get_temp_buffer(dev, __LINE__); + u8 *data = yaffs_get_temp_buffer(dev); struct yaffs_ext_tags tags; int result; @@ -349,7 +333,7 @@ static int yaffs_check_chunk_erased(struct yaffs_dev *dev, int nand_chunk) retval = YAFFS_FAIL; } - yaffs_release_temp_buffer(dev, data, __LINE__); + yaffs_release_temp_buffer(dev, data); return retval; @@ -362,7 +346,7 @@ static int yaffs_verify_chunk_written(struct yaffs_dev *dev, { int retval = YAFFS_OK; struct yaffs_ext_tags temp_tags; - u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__); + u8 *buffer = yaffs_get_temp_buffer(dev); int result; result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, buffer, &temp_tags); @@ -372,7 +356,7 @@ static int yaffs_verify_chunk_written(struct yaffs_dev *dev, temp_tags.n_bytes != tags->n_bytes) retval = YAFFS_FAIL; - yaffs_release_temp_buffer(dev, buffer, __LINE__); + yaffs_release_temp_buffer(dev, buffer); return retval; } @@ -642,10 +626,10 @@ static void yaffs_retire_block(struct yaffs_dev *dev, int flash_block) int chunk_id = flash_block * dev->param.chunks_per_block; - u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__); + u8 *buffer = yaffs_get_temp_buffer(dev); memset(buffer, 0xff, dev->data_bytes_per_chunk); - yaffs_init_tags(&tags); + memset(&tags, 0, sizeof(tags)); tags.seq_number = YAFFS_SEQUENCE_BAD_BLOCK; if (dev->param.write_chunk_tags_fn(dev, chunk_id - dev->chunk_offset, @@ -655,7 +639,7 @@ static void yaffs_retire_block(struct yaffs_dev *dev, int flash_block) "yaffs: Failed to write bad block marker to block %d", flash_block); - yaffs_release_temp_buffer(dev, buffer, __LINE__); + yaffs_release_temp_buffer(dev, buffer); } } @@ -2399,6 +2383,8 @@ void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no) bi->has_shrink_hdr = 0; bi->skip_erased_check = 1; /* Clean, so no need to check */ bi->gc_prioritise = 0; + bi->has_summary=0; + yaffs_clear_chunk_bits(dev, block_no); yaffs_trace(YAFFS_TRACE_ERASE, "Erased block %d", block_no); @@ -2415,7 +2401,7 @@ static inline int yaffs_gc_process_chunk(struct yaffs_dev *dev, int matching_chunk; int ret_val = YAFFS_OK; - yaffs_init_tags(&tags); + memset(&tags, 0, sizeof(tags)); yaffs_rd_chunk_tags_nand(dev, old_chunk, buffer, &tags); object = yaffs_find_by_number(dev, tags.obj_id); @@ -2574,6 +2560,8 @@ static int yaffs_gc_block(struct yaffs_dev *dev, int block, int whole_block) dev->gc_disable = 1; + yaffs_summary_gc(dev, block); + if (is_checkpt_block || !yaffs_still_some_chunks(dev, block)) { yaffs_trace(YAFFS_TRACE_TRACING, "Collecting block %d that has no chunks in use", @@ -2581,7 +2569,7 @@ static int yaffs_gc_block(struct yaffs_dev *dev, int block, int whole_block) yaffs_block_became_dirty(dev, block); } else { - u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__); + u8 *buffer = yaffs_get_temp_buffer(dev); yaffs_verify_blk(dev, bi, block); @@ -2601,7 +2589,7 @@ static int yaffs_gc_block(struct yaffs_dev *dev, int block, int whole_block) old_chunk, buffer); } } - yaffs_release_temp_buffer(dev, buffer, __LINE__); + yaffs_release_temp_buffer(dev, buffer); } yaffs_verify_collected_blk(dev, bi, block); @@ -2971,7 +2959,7 @@ void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash, if (!dev->param.is_yaffs2 && mark_flash && bi->block_state != YAFFS_BLOCK_STATE_COLLECTING) { - yaffs_init_tags(&tags); + memset(&tags, 0, sizeof(tags)); tags.is_deleted = 1; yaffs_wr_chunk_tags_nand(dev, chunk_id, NULL, &tags); yaffs_handle_chunk_update(dev, chunk_id, &tags); @@ -3025,7 +3013,7 @@ static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk, return 0; /* Set up new tags */ - yaffs_init_tags(&new_tags); + memset(&new_tags, 0, sizeof(new_tags)); new_tags.chunk_id = inode_chunk; new_tags.obj_id = in->obj_id; @@ -3127,7 +3115,7 @@ static int yaffs_do_xattrib_fetch(struct yaffs_obj *obj, const YCHAR *name, return 0; } - buffer = (char *)yaffs_get_temp_buffer(dev, __LINE__); + buffer = (char *)yaffs_get_temp_buffer(dev); if (!buffer) return -ENOMEM; @@ -3149,7 +3137,7 @@ static int yaffs_do_xattrib_fetch(struct yaffs_obj *obj, const YCHAR *name, else retval = nval_list(x_buffer, x_size, value, size); } - yaffs_release_temp_buffer(dev, (u8 *) buffer, __LINE__); + yaffs_release_temp_buffer(dev, (u8 *) buffer); return retval; } @@ -3189,7 +3177,7 @@ static void yaffs_check_obj_details_loaded(struct yaffs_obj *in) dev = in->my_dev; in->lazy_loaded = 0; - buf = yaffs_get_temp_buffer(dev, __LINE__); + buf = yaffs_get_temp_buffer(dev); result = yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, buf, &tags); oh = (struct yaffs_obj_hdr *)buf; @@ -3204,7 +3192,7 @@ static void yaffs_check_obj_details_loaded(struct yaffs_obj *in) if (!in->variant.symlink_variant.alias) alloc_failed = 1; /* Not returned */ } - yaffs_release_temp_buffer(dev, buf, __LINE__); + yaffs_release_temp_buffer(dev, buf); } static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR *name, @@ -3305,7 +3293,7 @@ int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, int force, yaffs_check_gc(dev, 0); yaffs_check_obj_details_loaded(in); - buffer = yaffs_get_temp_buffer(in->my_dev, __LINE__); + buffer = yaffs_get_temp_buffer(in->my_dev); oh = (struct yaffs_obj_hdr *)buffer; prev_chunk_id = in->hdr_chunk; @@ -3376,7 +3364,7 @@ int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, int force, yaffs_apply_xattrib_mod(in, (char *)buffer, xmod); /* Tags */ - yaffs_init_tags(&new_tags); + memset(&new_tags, 0, sizeof(new_tags)); in->serial++; new_tags.chunk_id = 0; new_tags.obj_id = in->obj_id; @@ -3398,7 +3386,7 @@ int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, int force, (prev_chunk_id > 0) ? 1 : 0); if (buffer) - yaffs_release_temp_buffer(dev, buffer, __LINE__); + yaffs_release_temp_buffer(dev, buffer); if (new_chunk_id < 0) return new_chunk_id; @@ -3494,13 +3482,12 @@ int yaffs_file_rd(struct yaffs_obj *in, u8 * buffer, loff_t offset, int n_bytes) /* Read into the local buffer then copy.. */ u8 *local_buffer = - yaffs_get_temp_buffer(dev, __LINE__); + yaffs_get_temp_buffer(dev); yaffs_rd_data_obj(in, chunk, local_buffer); memcpy(buffer, &local_buffer[start], n_copy); - yaffs_release_temp_buffer(dev, local_buffer, - __LINE__); + yaffs_release_temp_buffer(dev, local_buffer); } } else { /* A full chunk. Read directly into the buffer. */ @@ -3642,8 +3629,7 @@ int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset, * local buffer then copy over and write back. */ - u8 *local_buffer = - yaffs_get_temp_buffer(dev, __LINE__); + u8 *local_buffer = yaffs_get_temp_buffer(dev); yaffs_rd_data_obj(in, chunk, local_buffer); memcpy(&local_buffer[start], buffer, n_copy); @@ -3653,8 +3639,7 @@ int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset, local_buffer, n_writeback, 0); - yaffs_release_temp_buffer(dev, local_buffer, - __LINE__); + yaffs_release_temp_buffer(dev, local_buffer); } } else { /* A full chunk. Write directly from the buffer. */ @@ -3747,7 +3732,7 @@ void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size) if (new_partial != 0) { int last_chunk = 1 + new_full; - u8 *local_buffer = yaffs_get_temp_buffer(dev, __LINE__); + u8 *local_buffer = yaffs_get_temp_buffer(dev); /* Rewrite the last chunk with its new size and zero pad */ yaffs_rd_data_obj(obj, last_chunk, local_buffer); @@ -3757,7 +3742,7 @@ void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size) yaffs_wr_data_obj(obj, last_chunk, local_buffer, new_partial, 1); - yaffs_release_temp_buffer(dev, local_buffer, __LINE__); + yaffs_release_temp_buffer(dev, local_buffer); } obj->variant.file_variant.file_size = new_size; @@ -4441,7 +4426,7 @@ int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR *name, int buffer_size) #endif else if (obj->hdr_chunk > 0) { int result; - u8 *buffer = yaffs_get_temp_buffer(obj->my_dev, __LINE__); + u8 *buffer = yaffs_get_temp_buffer(obj->my_dev); struct yaffs_obj_hdr *oh = (struct yaffs_obj_hdr *)buffer; @@ -4455,7 +4440,7 @@ int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR *name, int buffer_size) yaffs_load_name_from_oh(obj->my_dev, name, oh->name, buffer_size); - yaffs_release_temp_buffer(obj->my_dev, buffer, __LINE__); + yaffs_release_temp_buffer(obj->my_dev, buffer); } yaffs_fix_null_name(obj, name, buffer_size); @@ -4833,6 +4818,11 @@ int yaffs_guts_initialise(struct yaffs_dev *dev) if (!init_failed && !yaffs_create_initial_dir(dev)) init_failed = 1; + if(!init_failed && dev->param.is_yaffs2 && + !dev->param.disable_summary && + !yaffs_summary_init(dev)) + init_failed = 1; + if (!init_failed) { /* Now scan the flash. */ if (dev->param.is_yaffs2) { @@ -4918,6 +4908,8 @@ void yaffs_deinitialise(struct yaffs_dev *dev) yaffs_deinit_blocks(dev); yaffs_deinit_tnodes_and_objs(dev); + yaffs_summary_deinit(dev); + if (dev->param.n_caches > 0 && dev->cache) { for (i = 0; i < dev->param.n_caches; i++) {