jffs2文件系统浅析----第二章从文件创建到flash固化存储

第二章 从文件创建到flash固化存储

    在第一章中我们讲述了jffs2文件系统如何通过文件ino信息找到flash中对应文件的数据实体,本章将解析如何将文件固化到flash中存储。

一、文件系统操作实例

    jffs2文件系统将写文件方法绑定到全局量变中,对外提供一个写对象,隐藏具体的实现细节。从中我们可以看出对文件的操作分为三个阶段,可以简单看作读文件、写文件预处理、实际写文件。

const struct address_space_operations jffs2_file_address_operations =
{
	.read_folio =	jffs2_read_folio,
	.write_begin =	jffs2_write_begin,
	.write_end =	jffs2_write_end,
};

1.1 读文件

     下面我们来看下前处理jffs2_read_folio的代码逻辑。前处理中主要是通jffs2_read_inode_range函数,从flash上读取文件的一个页框中[offset, offset + len]区域的内容到页高速缓存中。对于已经压缩的数据还需要执行解压操作。

static int jffs2_read_folio(struct file *file, struct folio *folio)
{
	...
	ret = __jffs2_read_folio(file, folio);
	...
}
int __jffs2_read_folio(struct file *file, struct folio *folio)
{
	int ret = jffs2_do_readpage_nolock(folio->mapping->host, &folio->page);
	folio_unlock(folio);
	return ret;
}
static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
{
	...
	ret = jffs2_read_inode_range(c, f, pg_buf, pg->index << PAGE_SHIFT,
				     PAGE_SIZE);
	...
}
int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
			   unsigned char *buf, uint32_t offset, uint32_t len)
{
	/* 从flash中读出数据(已压缩数据还需解压jffs2_decompress) */
	ret = jffs2_read_dnode(c, f, frag->node, buf, fragofs + frag->ofs - frag->node->ofs, readlen);
}

1.2 写文件预处理

     剔除部分无效数据,我们可以看到,预处理阶段,将文件的数据实体之间的空洞先写0。

static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
			loff_t pos, unsigned len,
			struct page **pagep, void **fsdata)
{
	...
	fn = jffs2_write_dnode(c, f, &ri, NULL, 0, ALLOC_NORMAL);
	...
}

1.3 实际写文件处理

     我们可以看出,主要通过jffs2_write_dnode将压缩过的数据分段写入flash中。因此,我们实际在操作文件写时,可以在应用层也可执行小力度的文件数据写入,进而在busy状态快速终止写文件操作。

static int jffs2_write_end(struct file *filp, struct address_space *mapping,
			loff_t pos, unsigned len, unsigned copied,
			struct page *pg, void *fsdata)
{
	...
	ret = jffs2_write_inode_range(c, f, ri, page_address(pg) + aligned_start,
				      (pg->index << PAGE_SHIFT) + aligned_start,
				      end - aligned_start, &writtenlen);
	...
}
int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
			    struct jffs2_raw_inode *ri, unsigned char *buf,
			    uint32_t offset, uint32_t writelen, uint32_t *retlen)
{
	/* 分段写入数据 */
	datalen = min_t(uint32_t, writelen, PAGE_SIZE - (offset & (PAGE_SIZE-1)));
	cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen);
	...
	/* 压缩文件数据 */
	comprtype = jffs2_compress(c, f, buf, &comprbuf, &datalen, &cdatalen);
	...
	/* 将文件数据写入flash */
	fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, ALLOC_NORETRY);
	...
}

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值