yaffs2源码学习3:文件创建与删除

本文详细介绍了嵌入式文件系统yaffs2中文件的创建和删除过程。从基本概念出发,包括文件创建的三个步骤:创建文件或目录、链接文件和写文件,以及文件删除的三个阶段:解除链接、软删除和删除。通过对yaffs2内部函数的分析,揭示了文件系统如何管理文件的生命周期。
摘要由CSDN通过智能技术生成

一、基本概念

在研究文件系统前,先对文件系统中涉及的基本的概念进行定义。

  • 域(field):是基本数据单元。一个域包含一个值。
  • 记录(record):是一组相关的域的集合,它可以看做是应用程序的一个单元。
  • 文件(file):是一组相似记录的集合,它被用户和应用程序看做是一个实体,并可以通过名字访问。
  • 文件管理系统:是一组系统软件,为使用文件的用户和应用程序提供服务。在典型情况下,文件管理系统是用户或应用程序访问文件的唯一方式,它使得用户和程序员不需要为每个应用程序开发专用软件,并且给系统提供了控制最重要资源的方法。

在嵌入式系统中,通常使用flash作为外部存储设备,而yaffs2是针对闪存的文件系统做的比较好的,本篇文章首先学习文件的创建和索引,文件系统怎么通过文件名来找到一个文件,然后介绍文件的删除。

二、文件创建

2.1 create file or directory

创建file或directory均转调用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;

	/* Check if the entry exists.
	 * If it does then fail the call since we don't want a dup. */
	if (yaffs_find_by_name(parent, name))
		return NULL;

	if (type == YAFFS_OBJECT_TYPE_SYMLINK) {
   
		str = yaffs_clone_str(alias_str);
		if (!str)
			return NULL;
	}

	in = yaffs_new_obj(dev, -1, type);
	/*此时object位于“lost+found”,无object header,如果object为file,则已关联空的tnode tree*/

	if (!in) {
   
		kfree(str);
		return NULL;
	}

	in->hdr_chunk = 0;
	in->valid = 1;
	in->variant_type = type;

	in->yst_mode = mode;

	yaffs_attribs_init(in, gid, uid, rdev);

	in->n_data_chunks = 0;    /*如果为文件,初始化记录文件的内容为chunk数*/

	yaffs_set_obj_name(in, name);
	in->dirty = 1;

	yaffs_add_obj_to_dir(parent, in);  /*放入期待的目录中*/

	in->my_dev = parent->my_dev;

	switch (type) {
          /*根据不同的类型,对in进行相应的处理*/
	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) {
         /*关联上object header*/
		/* Could not create the object header, fail */
		yaffs_del_obj(in);
		in = NULL;
	}

	if (in)
		yaffs_update_parent(parent);

	return in;
}

从函数体中,我们看出调用了函数yaffs_find_by_name(parent, name),其中定义了文件名的字符数不能超过128个,又通过函数yaffs_get_obj_name()到函数yaffs_fix_null_name()来创建根据用户设置的文件名定义的文件。
in = yaffs_new_obj(dev, -1, type);创建该文件对象在tnode树的结构,
yaffs_add_obj_to_dir(parent, in);将in文件装入其父目录中。
yaffs_update_oh(in, name, 0, 0, 0, NULL),将in关联到其对象头上,更新其chunk_id。

2.2 link file

一个可被访问的file一定存在于某个绝对路径中,如/nand0/dev/yaffs2/readme.txt,文件readme.txt在绝对路径/nand0/dev/yaffs2/中,yaff2是它所在的目录,此时称readme.txt已经link。在删除readme.txt之前,必须将它unlink,即从绝对路径中剥离开来。
在link阶段,最终是调用yaffs_check_obj_details_loaded(in),将对象in的路径连接在其对应的结构上。

static void yaffs_check_obj_details_loaded(struct yaffs_obj *in)
{
   
	u8 *buf;
	struct yaffs_obj_hdr *oh;
	struct yaffs_dev *dev;
	struct yaffs_ext_tags tags;
	int result;

	if (!in || !in->lazy_loaded || in->hdr_chunk < 1)
		return;

	dev = in->my_dev;
	buf = yaffs_get_temp_buffer(dev);

	result = yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, buf, &tags);

	if (result == YAFFS_FAIL)
		return;

	oh = (struct yaffs_obj_hdr *)buf;

	yaffs_do_endian_oh(dev, oh);

	in->lazy_loaded 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值