X-Git-Url: https://yaffs.net/gitweb/?a=blobdiff_plain;f=yaffs_guts.c;h=bf58eca1da0b3ceaf0316adbb7ed055b6519733b;hb=33308768bd24abe4e1f59c5025a3dd824119ae1d;hp=6a12aba23ebdaf89543980b3cf0fda1c4805a9ba;hpb=30f956c32c235e6b5fa77fb29965ababbd497561;p=yaffs2.git diff --git a/yaffs_guts.c b/yaffs_guts.c index 6a12aba..bf58eca 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -631,6 +631,78 @@ static void yaffs_retire_block(struct yaffs_dev *dev, int flash_block) /*---------------- Name handling functions ------------*/ +static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR *name, + const YCHAR *oh_name, int buff_size) +{ +#ifdef CONFIG_YAFFS_AUTO_UNICODE + if (dev->param.auto_unicode) { + if (*oh_name) { + /* It is an ASCII name, do an ASCII to + * unicode conversion */ + const char *ascii_oh_name = (const char *)oh_name; + int n = buff_size - 1; + while (n > 0 && *ascii_oh_name) { + *name = *ascii_oh_name; + name++; + ascii_oh_name++; + n--; + } + } else { + strncpy(name, oh_name + 1, buff_size - 1); + } + } else { +#else + (void) dev; + { +#endif + strncpy(name, oh_name, buff_size - 1); + } +} + +static void yaffs_load_oh_from_name(struct yaffs_dev *dev, YCHAR *oh_name, + const YCHAR *name) +{ +#ifdef CONFIG_YAFFS_AUTO_UNICODE + + int is_ascii; + const YCHAR *w; + + if (dev->param.auto_unicode) { + + is_ascii = 1; + w = name; + + /* Figure out if the name will fit in ascii character set */ + while (is_ascii && *w) { + if ((*w) & 0xff00) + is_ascii = 0; + w++; + } + + if (is_ascii) { + /* It is an ASCII name, so convert unicode to ascii */ + char *ascii_oh_name = (char *)oh_name; + int n = YAFFS_MAX_NAME_LENGTH - 1; + while (n > 0 && *name) { + *ascii_oh_name = *name; + name++; + ascii_oh_name++; + n--; + } + } else { + /* Unicode name, so save starting at the second YCHAR */ + *oh_name = 0; + strncpy(oh_name + 1, name, YAFFS_MAX_NAME_LENGTH - 2); + } + } else { +#else + dev = dev; + { +#endif + strncpy(oh_name, name, YAFFS_MAX_NAME_LENGTH - 1); + } +} + static u16 yaffs_calc_name_sum(const YCHAR *name) { u16 sum = 0; @@ -1850,21 +1922,18 @@ static int yaffs_new_obj_id(struct yaffs_dev *dev) struct list_head *i; u32 n = (u32) bucket; - /* Now find an object value that has not already been taken - * by scanning the list. + /* + * Now find an object value that has not already been taken + * by scanning the list, incrementing each time by number of buckets. */ - while (!found) { found = 1; n += YAFFS_NOBJECT_BUCKETS; - if (1 || dev->obj_bucket[bucket].count > 0) { - list_for_each(i, &dev->obj_bucket[bucket].list) { - /* If there is already one in the list */ - if (i && list_entry(i, struct yaffs_obj, - hash_link)->obj_id == n) { - found = 0; - } - } + list_for_each(i, &dev->obj_bucket[bucket].list) { + /* Check if this value is already taken. */ + if (i && list_entry(i, struct yaffs_obj, + hash_link)->obj_id == n) + found = 0; } } return n; @@ -1932,7 +2001,7 @@ static struct yaffs_obj *yaffs_new_obj(struct yaffs_dev *dev, int number, switch (type) { case YAFFS_OBJECT_TYPE_FILE: the_obj->variant.file_variant.file_size = 0; - the_obj->variant.file_variant.scanned_size = 0; + the_obj->variant.file_variant.stored_size = 0; the_obj->variant.file_variant.shrink_size = yaffs_max_file_size(dev); the_obj->variant.file_variant.top_level = 0; @@ -2478,9 +2547,9 @@ static inline int yaffs_gc_process_chunk(struct yaffs_dev *dev, /* Update file size */ if (object->variant_type == YAFFS_OBJECT_TYPE_FILE) { yaffs_oh_size_load(oh, - object->variant.file_variant.file_size); + object->variant.file_variant.stored_size); tags.extra_file_size = - object->variant.file_variant.file_size; + object->variant.file_variant.stored_size; } yaffs_verify_oh(object, oh, &tags, 1); @@ -2981,6 +3050,7 @@ static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk, int new_chunk_id; struct yaffs_ext_tags new_tags; struct yaffs_dev *dev = in->my_dev; + loff_t endpos; yaffs_check_gc(dev, 0); @@ -3002,13 +3072,24 @@ static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk, (prev_chunk_id > 0) ? prev_tags.serial_number + 1 : 1; new_tags.n_bytes = n_bytes; - if (n_bytes < 1 || n_bytes > dev->param.total_bytes_per_chunk) { + if (n_bytes < 1 || n_bytes > dev->data_bytes_per_chunk) { yaffs_trace(YAFFS_TRACE_ERROR, "Writing %d bytes to chunk!!!!!!!!!", n_bytes); BUG(); } + /* + * If this is a data chunk and the write goes past the end of the stored + * size then update the stored_size. + */ + if (inode_chunk > 0) { + endpos = (inode_chunk - 1) * dev->data_bytes_per_chunk + + n_bytes; + if (in->variant.file_variant.stored_size < endpos) + in->variant.file_variant.stored_size = endpos; + } + new_chunk_id = yaffs_write_new_chunk(dev, buffer, &new_tags, use_reserve); @@ -3021,7 +3102,6 @@ static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk, yaffs_verify_file_sane(in); } return new_chunk_id; - } @@ -3176,78 +3256,6 @@ static void yaffs_check_obj_details_loaded(struct yaffs_obj *in) yaffs_release_temp_buffer(dev, buf); } -static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR *name, - const YCHAR *oh_name, int buff_size) -{ -#ifdef CONFIG_YAFFS_AUTO_UNICODE - if (dev->param.auto_unicode) { - if (*oh_name) { - /* It is an ASCII name, do an ASCII to - * unicode conversion */ - const char *ascii_oh_name = (const char *)oh_name; - int n = buff_size - 1; - while (n > 0 && *ascii_oh_name) { - *name = *ascii_oh_name; - name++; - ascii_oh_name++; - n--; - } - } else { - strncpy(name, oh_name + 1, buff_size - 1); - } - } else { -#else - (void) dev; - { -#endif - strncpy(name, oh_name, buff_size - 1); - } -} - -static void yaffs_load_oh_from_name(struct yaffs_dev *dev, YCHAR *oh_name, - const YCHAR *name) -{ -#ifdef CONFIG_YAFFS_AUTO_UNICODE - - int is_ascii; - YCHAR *w; - - if (dev->param.auto_unicode) { - - is_ascii = 1; - w = name; - - /* Figure out if the name will fit in ascii character set */ - while (is_ascii && *w) { - if ((*w) & 0xff00) - is_ascii = 0; - w++; - } - - if (is_ascii) { - /* It is an ASCII name, so convert unicode to ascii */ - char *ascii_oh_name = (char *)oh_name; - int n = YAFFS_MAX_NAME_LENGTH - 1; - while (n > 0 && *name) { - *ascii_oh_name = *name; - name++; - ascii_oh_name++; - n--; - } - } else { - /* Unicode name, so save starting at the second YCHAR */ - *oh_name = 0; - strncpy(oh_name + 1, name, YAFFS_MAX_NAME_LENGTH - 2); - } - } else { -#else - dev = dev; - { -#endif - strncpy(oh_name, name, YAFFS_MAX_NAME_LENGTH - 1); - } -} - /* UpdateObjectHeader updates the header on NAND for an object. * If name is not NULL, then that new name is used. */ @@ -3322,7 +3330,7 @@ int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, int force, case YAFFS_OBJECT_TYPE_FILE: if (oh->parent_obj_id != YAFFS_OBJECTID_DELETED && oh->parent_obj_id != YAFFS_OBJECTID_UNLINKED) - file_size = in->variant.file_variant.file_size; + file_size = in->variant.file_variant.stored_size; yaffs_oh_size_load(oh, file_size); break; case YAFFS_OBJECT_TYPE_HARDLINK: @@ -3743,6 +3751,7 @@ void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size) } obj->variant.file_variant.file_size = new_size; + obj->variant.file_variant.stored_size = new_size; yaffs_prune_tree(dev, &obj->variant.file_variant); } @@ -4083,7 +4092,7 @@ static int yaffs_unlink_worker(struct yaffs_obj *obj) } } -static int yaffs_unlink_obj(struct yaffs_obj *obj) +int yaffs_unlink_obj(struct yaffs_obj *obj) { if (obj && obj->unlink_allowed) return yaffs_unlink_worker(obj); @@ -5022,8 +5031,15 @@ void yaffs_deinitialise(struct yaffs_dev *dev) kfree(dev->gc_cleanup_list); - for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) + for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { kfree(dev->temp_buffer[i].buffer); + dev->temp_buffer[i].buffer = NULL; + } + + kfree(dev->checkpt_buffer); + dev->checkpt_buffer = NULL; + kfree(dev->checkpt_block_list); + dev->checkpt_block_list = NULL; dev->is_mounted = 0;