一. yaffs是怎样创建文件的呢
启动linux完成进入shell后,在shell中执行如下命令,会发生什么情况呢?当前文件系统是yaffs2
[root@OK6410]# touch 123
调用过程如下,先不分析与yaffs2无关的
-
sys_open
-
do_sys_open
-
do_filp_open
-
path_openat
-
do_last
-
vfs_create
-
yaffs_create
-
--> yaffs_mknod
-
--> yaffs_create_file
-
--> yaffs_create_obj
1. 创建文件,目录,特殊文件,软链接,硬链接都需要调用函数yaffs_create_obj
-
static struct yaffs_obj *yaffs_create_obj(enum yaffs_obj_type type, struct yaffs_obj *parent, const YCHAR *name,
-
u32 mode, u32 uid, u32 gid, struct yaffs_obj *equiv_obj, const YCHAR *alias_str, u32 rdev)
-
{
-
struct yaffs_obj *in;
-
YCHAR *str = NULL;
-
struct yaffs_dev *dev = parent->my_dev;
-
-
if (yaffs_find_by_name(parent, name)) //1. 检查是否有重名文件存在
-
return NULL;
-
-
if (type == YAFFS_OBJECT_TYPE_SYMLINK) {
-
str = yaffs_clone_str(alias_str); //2.如果是软链接 clone
-
if (!str)
-
return NULL;
-
}
-
-
in = yaffs_new_obj(dev, -1, type); //3.new一个obj
-
-
in->hdr_chunk = 0;
-
in->valid = 1;
-
in->variant_type = type;
-
-
in->yst_mode = mode;
-
-
yaffs_attribs_init(in, gid, uid, rdev); //4. 权限初始化
-
-
in->n_data_chunks = 0;
-
yaffs_set_obj_name(in, name); //5. 命名;并对文件名取sum,保存在in->sum中
-
in->dirty = 1;
-
-
yaffs_add_obj_to_dir(parent, in); //6. 把文件添加到目录
-
-
in->my_dev = parent->my_dev;
-
-
switch (type) {
-
case YAFFS_OBJECT_TYPE_SYMLINK:
-
in->variant.symlink_variant.alias = str;
-
break;
-
case YAFFS_OBJECT_TYPE_HARDLINK:
-
in->variant.hardlink_variant.equiv_obj = equiv_obj;
-
in->variant.hardlink_variant.equiv_id = equiv_obj->obj_id;
-
list_add(&in->hard_links, &equiv_obj->hard_links);
-
break;
-
case YAFFS_OBJECT_TYPE_FILE:
-
case YAFFS_OBJECT_TYPE_DIRECTORY:
-
case YAFFS_OBJECT_TYPE_SPECIAL:
-
case YAFFS_OBJECT_TYPE_UNKNOWN:
-
/* do nothing */
-
break;
-
}
-
-
if (yaffs_update_oh(in, name, 0, 0, 0, NULL) < 0) { //7.把信息写入
-
yaffs_del_obj(in);
-
in = NULL;
-
}
-
-
if (in)
-
yaffs_update_parent(parent); //8.把信息写入到parent
-
-
return in;
-
}
1.1 在目录directory中查找是否有重名的,没有重名返回NULL
-
struct yaffs_obj *yaffs_find_by_name(struct yaffs_obj *directory, const YCHAR *name)
-
{
-
int sum;
-
struct list_head *i;
-
YCHAR buffer[YAFFS_MAX_NAME_LENGTH + 1];
-
struct yaffs_obj *l;
-
-
-
if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { //首先检查参数,directory的类型是DIRECTORY
-
BUG();
-
}
-
-
sum = yaffs_calc_name_sum(name); //对文件名取个sum,可以认为是个标志
-
-
list_for_each(i, &directory->variant.dir_variant.children) {
-
l = list_entry(i, struct yaffs_obj, siblings);
-
-
if (l->parent != directory)
-
BUG();
-
-
yaffs_check_obj_details_loaded(l);
-
-
if (l->obj_id == YAFFS_OBJECTID_LOSTNFOUND) {
-
if (!strcmp(name, YAFFS_LOSTNFOUND_NAME))
-
return l;
-
} else if (l->sum == sum || l->hdr_chunk <= 0) { //拿刚才作的sum与该目录下所有的文件进行比较
-
yaffs_get_obj_name(l, buffer, YAFFS_MAX_NAME_LENGTH + 1); // 如果sum值相等,再进行真正的字符串比较,看两个文件是否真的一样
-
if (strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH) == 0)
-
return l;
-
}
-
}
-
return NULL;
-
}
注意: 这个查找重名函数,并不是将要创建文件的name与目录下所有的文件都按字符串进行比较,
而是对要创建的文件按名作sum,则比较时只比较sum值是不是相等,这样可以缩减比较时间;
如果相等了再按照字符串对两个文个进行比较,看是否真的一样.
同时其它文件的sum值会在开机启动时调用yaffs_lookup进行扫描时保存在文件结构体的in->sum中.
1.3 申请一个obj结构体
-
struct yaffs_obj *yaffs_new_obj(struct yaffs_dev *dev, int number, enum yaffs_obj_type type)
-
{
-
struct yaffs_obj *the_obj = NULL;
-
struct yaffs_tnode *tn = NULL;
-
-
if (number < 0)
-
number = yaffs_new_obj_id(dev); //在hash表中找到一个未用的obj_id
-
-
if (type == YAFFS_OBJECT_TYPE_FILE) {
-
tn = yaffs_get_tnode(dev); //申请一个tnode结构体
-
if (!tn)
-
return NULL;
-
}
-
-
the_obj = yaffs_alloc_empty_obj(dev); //申请一个yaffs_obj结构体
-
if (!the_obj) {
-
if (tn)
-
yaffs_free_tnode(dev, tn);
-
return NULL;
-
}
-
-
the_obj->fake = 0;
-
the_obj->rename_allowed = 1;
-
the_obj->unlink_allowed = 1;
-
the_obj->obj_id = number;
-
yaffs_hash_obj(the_obj); //把yaffs_obj按obj_id,存于hash表中
-
the_obj->variant_type = type;
-
yaffs_load_current_time(the_obj, 1, 1); //对obj设置当前时间
-
-
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.shrink_size = ~0; /* max */
-
the_obj->variant.file_variant.top_level = 0;
-
the_obj->variant.file_variant.top = tn; //如果是普通文件,第一个tnode就是刚才申请的tnode
-
break;
-
case YAFFS_OBJECT_TYPE_DIRECTORY:
-
INIT_LIST_HEAD(&the_obj->variant.dir_variant.children); //如果是目录就创建两个list
-
INIT_LIST_HEAD(&the_obj->variant.dir_variant.dirty); //一个作为文件列表,另一个回收
-
break;
-
case YAFFS_OBJECT_TYPE_SYMLINK:
-
case YAFFS_OBJECT_TYPE_HARDLINK:
-
case YAFFS_OBJECT_TYPE_SPECIAL:
-
/* No action required */
-
break;
-
case YAFFS_OBJECT_TYPE_UNKNOWN:
-
/* todo this should not happen */
-
break;
-
}
-
return the_obj;
-
}
1.5 设置文件名的同时,计算文件名的sum值
-
void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR * name)
-
{
-
memset(obj->short_name, 0, sizeof(obj->short_name));
-
if (name && strnlen(name, YAFFS_SHORT_NAME_LENGTH + 1) <= YAFFS_SHORT_NAME_LENGTH)
-
strcpy(obj->short_name, name); //直接strcpy
-
else
-
obj->short_name[0] = _Y('\0');
-
obj->sum = yaffs_calc_name_sum(name); //将计算出的sum值保存在obj->sum中
-
}
1.6 把obj添加到目录
-
void yaffs_add_obj_to_dir(struct yaffs_obj *directory, struct yaffs_obj *obj)
-
{
-
if (!directory)
-
return;
-
-
if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
-
BUG();
-
-
if (obj->siblings.prev == NULL)
-
BUG();
-
-
yaffs_verify_dir(directory);
-
-
yaffs_remove_obj_from_dir(obj); //为什么这儿要remove呢?因为初始化时parent=root_dir
-
-
list_add(&obj->siblings, &directory->variant.dir_variant.children); //添加到parent
-
obj->parent = directory;
-
-
if (directory == obj->my_dev->unlinked_dir || directory == obj->my_dev->del_dir) {
-
obj->unlinked = 1;
-
obj->my_dev->n_unlinked_files++;
-
obj->rename_allowed = 0;
-
}
-
-
yaffs_verify_dir(directory);
-
yaffs_verify_obj_in_dir(obj);
-
}
在添加到新目录之前,要删掉它在旧目录的指针.
yaffs_add_obj_to_dir
--> yaffs_remove_obj_from_dir
-
static void yaffs_remove_obj_from_dir(struct yaffs_obj *obj)
-
{
-
struct yaffs_dev *dev = obj->my_dev;
-
struct yaffs_obj *parent;
-
-
yaffs_verify_obj_in_dir(obj);
-
parent = obj->parent; //获取parent目录指针
-
-
yaffs_verify_dir(parent);
-
-
if (dev && dev->param.remove_obj_fn)
-
dev->param.remove_obj_fn(obj); //从parent目录中去掉obj
-
-
list_del_init(&obj->siblings);
-
obj->parent = NULL;
-
-
yaffs_verify_dir(parent);
-
}
注:为什么要调用yaffs_remove_obj_from_dir呢?因为在创建empty_obj时,会将obj的parent初始化为root_dir,所以这个地方要先从root_dir中删掉
yaffs_create_obj-->yaffs_new_obj--> yaffs_alloc_empty_obj
-
static struct yaffs_obj *yaffs_alloc_empty_obj(struct yaffs_dev *dev)
-
{
-
if (dev->root_dir) {
-
obj->parent = dev->root_dir;
-
list_add(&(obj->siblings), &dev->root_dir->variant.dir_variant.children);
-
}
-
}
yaffs_add_obj_to_dir
--> yaffs_remove_obj_from_dir
--> dev
->param
.remove_obj_fn
-
static void yaffs_remove_obj_callback(struct yaffs_obj *obj) //这个地方还没有看明白
-
{
-
-
struct list_head *i;
-
struct yaffs_search_context *sc;
-
struct list_head *search_contexts = &(yaffs_dev_to_lc(obj->my_dev)->search_contexts);
-
-
/* Iterate through the directory search contexts.
-
* If any are currently on the object being removed, then advance
-
* the search context to the next object to prevent a hanging pointer.
-
*/
-
list_for_each(i, search_contexts) {
-
sc = list_entry(i, struct yaffs_search_context, others);
-
if (sc->next_return == obj)
-
yaffs_search_advance(sc);
-
}
-
-
}
1.7 更新object_header并把信息写到nand_flash中
yaffs_create_obj
-->yaffs_update_oh(in, name, 0, 0, 0, NULL)
-
/* UpdateObjectHeader updates the header on NAND for an object.
-
* If name is not NULL, then that new name is used.
-
*/
-
int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, int force,
-
int is_shrink, int shadows, struct yaffs_xattr_mod *xmod)
-
{
-
-
struct yaffs_block_info *bi;
-
struct yaffs_dev *dev = in->my_dev;
-
int prev_chunk_id;
-
int ret_val = 0;
-
int result = 0;
-
int new_chunk_id;
-
struct yaffs_ext_tags new_tags;
-
struct yaffs_ext_tags old_tags;
-
const YCHAR *alias = NULL;
-
u8 *buffer = NULL;
-
YCHAR old_name[YAFFS_MAX_NAME_LENGTH + 1];
-
struct yaffs_obj_hdr *oh = NULL;
-
-
strcpy(old_name, _Y("silly old name"));
-
-
if (in->fake && in != dev->root_dir && !force && !xmod)
-
return ret_val;
-
-
yaffs_check_gc(dev, 0);
-
yaffs_check_obj_details_loaded(in); //在yaffs_create_obj中 in->hdr_chunk=0,这个函数直接返回
-
buffer = yaffs_get_temp_buffer(in->my_dev); //1. 获取temp_buffer
-
oh = (struct yaffs_obj_hdr *)buffer;
-
-
prev_chunk_id = in->hdr_chunk;
-
-
if (prev_chunk_id > 0) { //在yaffs_create_obj中 in->hdr_chunk=0
-
result = yaffs_rd_chunk_tags_nand(dev, prev_chunk_id, buffer, &old_tags);
-
yaffs_verify_oh(in, oh, &old_tags, 0);
-
memcpy(old_name, oh->name, sizeof(oh->name));
-
memset(buffer, 0xff, sizeof(struct yaffs_obj_hdr));
-
} else {
-
memset(buffer, 0xff, dev->data_bytes_per_chunk); //设置chunk的数值都为0xff
-
}
-
-
oh->type = in->variant_type; /* 填充oh结构体
-
oh->yst_mode = in->yst_mode; *
-
oh->shadows_obj = oh->inband_shadowed_obj_id = shadows; *
-
yaffs_load_attribs_oh(oh, in); */
-
-
if (in->parent)
-
oh->parent_obj_id = in->parent->obj_id;
-
else
-
oh->parent_obj_id = 0;
-
-
if (name && *name) {
-
memset(oh->name, 0, sizeof(oh->name));
-
yaffs_load_oh_from_name(dev, oh->name, name); //文件名copy
-
} else if (prev_chunk_id > 0) {
-
memcpy(oh->name, old_name, sizeof(oh->name));
-
} else {
-
memset(oh->name, 0, sizeof(oh->name));
-
}
-
-
oh->is_shrink = is_shrink;
-
-
switch (in->variant_type) {
-
case YAFFS_OBJECT_TYPE_UNKNOWN:
-
/* Should not happen */
-
break;
-
case YAFFS_OBJECT_TYPE_FILE:
-
oh->file_size =(oh->parent_obj_id == YAFFS_OBJECTID_DELETED || oh->parent_obj_id == YAFFS_OBJECTID_UNLINKED) ?
-
0 : in->variant.file_variant.file_size;
-
break;
-
case YAFFS_OBJECT_TYPE_HARDLINK:
-
oh->equiv_id = in->variant.hardlink_variant.equiv_id;
-
break;
-
case YAFFS_OBJECT_TYPE_SPECIAL:
-
/* Do nothing */
-
break;
-
case YAFFS_OBJECT_TYPE_DIRECTORY:
-
/* Do nothing */
-
break;
-
case YAFFS_OBJECT_TYPE_SYMLINK:
-
alias = in->variant.symlink_variant.alias;
-
if (!alias)
-
alias = _Y("no alias");
-
strncpy(oh->alias, alias, YAFFS_MAX_ALIAS_LENGTH);
-
oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0;
-
break;
-
}
-
-
/* Tags */
-
memset(&new_tags, 0, sizeof(new_tags));
-
in->serial++;
-
new_tags.chunk_id = 0;
-
new_tags.obj_id = in->obj_id;
-
new_tags.serial_number = in->serial;
-
-
/* Add extra info for file header */
-
new_tags.extra_available = 1;
-
new_tags.extra_parent_id = oh->parent_obj_id;
-
new_tags.extra_length = oh->file_size;
-
new_tags.extra_is_shrink = oh->is_shrink;
-
new_tags.extra_equiv_id = oh->equiv_id;
-
new_tags.extra_shadows = (oh->shadows_obj > 0) ? 1 : 0;
-
new_tags.extra_obj_type = in->variant_type;
-
yaffs_verify_oh(in, oh, &new_tags, 1);
-
-
/* Create new chunk in NAND */
-
new_chunk_id = yaffs_write_new_chunk(dev, buffer, &new_tags, (prev_chunk_id > 0) ? 1 : 0); //将数据写入到nand_flash中
-
-
if (buffer)
-
yaffs_release_temp_buffer(dev, buffer);
-
-
if (new_chunk_id < 0)
-
return new_chunk_id;
-
-
in->hdr_chunk = new_chunk_id; //返回新的chunk_id,就是刚才写入到nand_flash中的chunk_id,把它保存起来
-
-
if (prev_chunk_id > 0)
-
yaffs_chunk_del(dev, prev_chunk_id, 1, __LINE__);
-
-
if (!yaffs_obj_cache_dirty(in))
-
in->dirty = 0;
-
-
/* If this was a shrink, then mark the block
-
* that the chunk lives on */
-
if (is_shrink) {
-
bi = yaffs_get_block_info(in->my_dev,
-
new_chunk_id /
-
in->my_dev->param.chunks_per_block);
-
bi->has_shrink_hdr = 1;
-
}
-
-
-
return new_chunk_id;
-
}
1.7.2 写数据到nand_flash
yaffs_create_obj
-->yaffs_update_oh(in, name, 0, 0, 0, NULL)
-->
yaffs_write_new_chunk
-
static int yaffs_write_new_chunk(struct yaffs_dev *dev, const u8 *data, struct yaffs_ext_tags *tags, int use_reserver)
-
{
-
int attempts = 0;
-
int write_ok = 0;
-
int chunk;
-
-
yaffs2_checkpt_invalidate(dev);
-
-
do {
-
struct yaffs_block_info *bi = 0;
-
int erased_ok = 0;
-
-
chunk = yaffs_alloc_chunk(dev, use_reserver, &bi); //申请一个chunk
-
if (chunk < 0) {
-
/* no space */
-
break;
-
}
-
attempts++;
-
-
if (dev->param.always_check_erased)
-
bi->skip_erased_check = 0;
-
-
if (!bi->skip_erased_check) {
-
erased_ok = yaffs_check_chunk_erased(dev, chunk); //1.检查这个chunk是否己擦除,即chunk中全是0xff
-
if (erased_ok != YAFFS_OK) {
-
yaffs_chunk_del(dev, chunk, 1, __LINE__); //经检查这个chunk没有被擦除,把这个chunk del
-
yaffs_skip_rest_of_block(dev); //到下一次循环时重新申请一个chunk,再检查
-
continue;
-
}
-
}
-
-
write_ok = yaffs_wr_chunk_tags_nand(dev, chunk, data, tags); //2.此时的chunk己擦除过的,就把tags写入到这个nand_flash中
-
-
if (!bi->skip_erased_check)
-
write_ok = yaffs_verify_chunk_written(dev, chunk, data, tags);
-
-
if (write_ok != YAFFS_OK) {
-
yaffs_handle_chunk_wr_error(dev, chunk, erased_ok);
-
continue;
-
}
-
-
bi->skip_erased_check = 1;
-
-
yaffs_handle_chunk_wr_ok(dev, chunk, data, tags); //3.把文件中的数据写入到nand_flash中
-
-
} while (write_ok != YAFFS_OK && (yaffs_wr_attempts <= 0 || attempts <= yaffs_wr_attempts));
-
-
if (!write_ok)
-
chunk = -1;
-
-
if (attempts > 1) {
-
dev->n_retried_writes += (attempts - 1);
-
}
-
-
return chunk;
-
}
1.7.2.1 检查某个chunk是否擦除过
yaffs_create_obj
-->yaffs_update_oh(in, name, 0, 0, 0, NULL)
-->
yaffs_write_new_chunk(dev, buffer, &new_tags, 0);
--> yaffs_check_chunk_erased
-
static int yaffs_check_chunk_erased(struct yaffs_dev *dev, int nand_chunk)
-
{
-
int retval = YAFFS_OK;
-
u8 *data = yaffs_get_temp_buffer(dev);
-
struct yaffs_ext_tags tags;
-
int result;
-
-
result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, data, &tags); //读取chunk的数据到data
-
-
if (tags.ecc_result > YAFFS_ECC_RESULT_NO_ERROR)
-
retval = YAFFS_FAIL;
-
-
if (!yaffs_check_ff(data, dev->data_bytes_per_chunk) || //检查是不是每个字节都是0xff
-
tags.chunk_used) {
-
retval = YAFFS_FAIL;
-
}
-
-
yaffs_release_temp_buffer(dev, data);
-
-
return retval; //如果每个字节都是0xff,返回YAFFS_OK
-
-
}
1.7.2.1.1 读取chunk中的数据到buffer
-
int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk, u8 *buffer, struct yaffs_ext_tags *tags)
-
{
-
int result;
-
struct yaffs_ext_tags local_tags;
-
int flash_chunk = nand_chunk - dev->chunk_offset;
-
-
dev->n_page_reads++;
-
-
if (!tags)
-
tags = &local_tags;
-
-
if (dev->param.read_chunk_tags_fn)
-
result = dev->param.read_chunk_tags_fn(dev, flash_chunk, buffer, tags); //直接调用的param.read_chunk_tags_fn来读取
-
else
-
result = yaffs_tags_compat_rd(dev, flash_chunk, buffer, tags);
-
if (tags && tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) {
-
struct yaffs_block_info *bi;
-
bi = yaffs_get_block_info(dev, nand_chunk/dev->param.chunks_per_block);
-
yaffs_handle_chunk_error(dev, bi);
-
}
-
return result;
-
}
1.7.2.2 将buffer中的数据到nand_flash中的chunk上
yaffs_create_obj
-->yaffs_update_oh(in, name, 0, 0, 0, NULL)
-->
yaffs_write_new_chunk(dev, buffer, &new_tags, 0);
-->
yaffs_wr_chunk_tags_nand
-
int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk, const u8 *buffer, struct yaffs_ext_tags *tags)
-
{
-
int result;
-
int flash_chunk = nand_chunk - dev->chunk_offset;
-
-
dev->n_page_writes++;
-
if (tags) {
-
tags->seq_number = dev->seq_number;
-
tags->chunk_used = 1;
-
} else {
-
return YAFFS_FAIL;
-
}
-
-
if (dev->param.write_chunk_tags_fn)
-
result = dev->param.write_chunk_tags_fn(dev, flash_chunk, buffer, tags); //直接调用param.write_chunk_tags_fn写入
-
else
-
result = yaffs_tags_compat_wr(dev, flash_chunk, buffer, tags);
-
-
yaffs_summary_add(dev, tags, nand_chunk);
-
-
return result;
-
}
其中两个函数指针:
dev
->param
.write_chunk_tags_fn
dev->param.read_chunk_tags_fn
的初始化是在yaffs_internal_read_super中
-
yaffs_internal_read_super()
-
{
-
if (yaffs_version == 2) {
-
param->write_chunk_tags_fn = nandmtd2_write_chunk_tags;
-
param->read_chunk_tags_fn = nandmtd2_read_chunk_tags;
-
param->bad_block_fn = nandmtd2_mark_block_bad;
-
param->query_block_fn = nandmtd2_query_block;
-
}
-
}
下面是读取过程
-
int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk, u8 *data, struct yaffs_ext_tags *tags)
-
{
-
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-
struct mtd_oob_ops ops;
-
size_t dummy;
-
int retval = 0;
-
int local_data = 0;
-
-
loff_t addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
-
-
struct yaffs_packed_tags2 pt;
-
-
int packed_tags_size = dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt); //dev->param.no_tags_ecc=1
-
void *packed_tags_ptr = dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt; //packed_tags_size=16, packed_tags_ptr=pt.t
-
-
if (tags) {
-
ops.mode = MTD_OOB_AUTO;
-
ops.ooblen = packed_tags_size;
-
ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
-
ops.ooboffs = 0;
-
ops.datbuf = data;
-
ops.oobbuf = yaffs_dev_to_lc(dev)->spare_buffer;
-
retval = mtd->read_oob(mtd, addr, &ops); //从nand_flash中读取nand_chunk到data中,oob读到ops.oobbuf中
-
}
-
if (tags) {
-
memcpy(packed_tags_ptr, yaffs_dev_to_lc(dev)->spare_buffer, packed_tags_size); //将oobbuf中的数据cp到pt.t中
-
yaffs_unpack_tags2(tags, &pt, !dev->param.no_tags_ecc); //如果param.no_tags_ecc=0,就要对pt->t进行ecc校验,并修正,但是这儿param.no_tags_ecc=1,所以不校验
-
} //将 struct yaffs_packed_tags2 *pt 转化为struct yaffs_ext_tags *tags
-
-
if (local_data)
-
yaffs_release_temp_buffer(dev, data);
-
-
if (tags && retval == -EBADMSG && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
-
tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED;
-
dev->n_ecc_unfixed++;
-
}
-
if (tags && retval == -EUCLEAN && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
-
tags->ecc_result = YAFFS_ECC_RESULT_FIXED;
-
dev->n_ecc_fixed++;
-
-
retval = 0; // gjl
-
}
-
if (retval == 0)
-
return YAFFS_OK;
-
else
-
return YAFFS_FAIL;
-
}
阅读(3124) | 评论(0) | 转发(2) |