Yaffs通过VFS层的读写

合集下载

linux vfs实现原理

linux vfs实现原理

linux vfs实现原理Linux VFS(Virtual File System)是Linux操作系统中的核心组件之一,它提供了统一的文件访问接口以及文件系统的抽象层,使得用户可以透明地访问不同类型的文件系统,包括本地文件系统和网络文件系统。

VFS的实现原理包括文件系统的注册、路径解析、文件的打开与读写、文件的索引、文件系统的缓存管理等。

文件系统注册是VFS的第一步,Linux内核中存在一个全局的文件系统注册表,它记录了所有已注册的文件系统类型和对应的操作函数。

当内核需要访问一个特定的文件系统时,根据文件路径的前缀,VFS会选择相应的文件系统类型进行处理。

路径解析是VFS的核心流程之一,它负责将用户传入的路径字符串转化为内核中的表示方式。

路径解析从根目录开始逐级查找,解析过程包括检查目录存在性、权限检查、查找文件并获取inode等。

路径解析的结果就是一个表示文件的inode对象,它包含了文件的元数据信息以及文件系统特定的操作函数。

文件的打开与读写是用户访问文件的主要操作,VFS提供了一系列的系统调用接口,例如open、read、write等。

当用户调用这些接口时,内核会根据文件的inode对象调用相应文件系统提供的操作函数。

文件系统的操作函数通过底层的驱动程序实现具体的文件读写操作,可能是读取磁盘上的数据,也可能是通过网络传输数据。

文件的索引是为了提高文件查找的效率,VFS使用dentry缓存来存储文件名和对应的inode对象之间的映射关系。

dentry是VFS中的一个重要概念,它代表目录项(directory entry),包含了文件名、inode和其他的元数据信息。

在路径解析的过程中,VFS会逐级查找并创建dentry对象,将其添加到dentry缓存中。

下次再次访问相同的文件时,可以直接从缓存中获取对应的dentry对象,避免了不必要的查找操作,提高了文件查找的性能。

文件系统的缓存管理是为了提高文件读取的效率,VFS使用page cache来缓存文件系统中的数据页面。

嵌入式 NAND flash文件系统JFFS2和YAFFS比较

嵌入式 NAND flash文件系统JFFS2和YAFFS比较

嵌入式NAND flash文件系统JFFS2和YAFFS比较JFFS是由瑞典的Axis Communications Ab公司开发的(1999,以GNU发布),针对flash设备的特性为嵌入式设备开发的JFFS1和JFFS2的设计中都考虑到了FLASH的特性特别是满足了上述3个条件,包括了垃圾回收,坏块管理等功能. 这两种文件系统属于LFS(Log-structured File System).这种文件系统的特点是一旦数据出错,容易恢复,但是系统运行是需要占用一定的内存空间,这些空间就是用来存储”log”的.JFFS的缺点就是加载时间太长,因为每次加载都需要将FLASH上的所有节点(JFFS的存储单位)到内存,这样也占用了可观的内存空间.除此之外,”circle log”设计使得在对文件数据进行所有的数据都会被重写,这样造成不必要的时间,同时也会减少FLASH的寿命.JFFS2对JFFS1作了些改进,比如所需的内存变少了,垃圾回收机制也优化了.针对JFFS1,JFFS2的缺点,JFFS3出现了.YAFFS1 ">“Yet Another Flash File System”作者是新西兰的Charles Manning为一家名叫Alpha one 的公司(/)设计的,是第一个为NAND Flash设计的文件系统.共两个版本YAFFS1 和YAFFS2.YAFFS1支持512Bytes/Page的NAND Flash;后者YAFFS2支持2kBytes/Page的NAND Flash. YAFFS文件系统也属于LFS.跟其他文件系统比较,它具有更好的可移植性,甚至可以使用在没有操作系统的设备上(called “YAFFS/Direct”). YAFFS采用模块化设计,虽然最初是用在linux系统上的,但是也已经移植到其他系统比如wince.还有个突出的优点是它在mount的时候需要很少的内存.(如果是小页―512byte/page,每1MByte NAND大约需要4KBytes内存;大页需要大概1KBytes RAM/1MByte NAND) JFFS与YAFFS比较,两者各有长处. 一般来说,对于小于64MBytes的NAND Flash,可以选用JFFS;如果超过64MBytes,用YAFFS比较合适.由于嵌入式系统自身存在一些特殊要求,使得一些传统的文件系统(如FAT、EXT2等) 并不十分适合。

YAFFS嵌入式文件系统原理分析

YAFFS嵌入式文件系统原理分析
YAFFs还带有NAND nash芯片驱动,并为嵌入式系统提 供了直接访问文件系统的API,用户可以不使用“nux中的 MTD和VFs,直接对文件进行操作。NAND Flash大多采用 MTD+YAFFs的模式。MTD(Memory Technology Devices,内 存技术设备)是对FIash操作的接口,提供了一系列的标准函 数,将硬件驱动设计和系统程序设计分开。图1列出了嵌入式 系统的文件系统结构。
YAFFs是一种类似于JFFs/JFFs2的专门为NAND Flash 设计的嵌入式文件系统。与专为NOR Flash而设计的JFFs相 比,它减少了一些功能,因此速度更快、占用内存更少。
表1 NAND和NOR两种Flash技术比较
NAND
NOR
性能
读速度慢 写速度快 擦除速度4m8 大多数写入操作前先进行擦 除操作擦除单元更小题。当每次页被 重写时,serialNumber就增加一次,对比不同的seriaINumber就
可以找出当前的页。 chunkId非O值说明这是个数据chunk,并且标示这个
chunk在文件中的位置(除文件头外文件的第一个chunk其 chunkId就是1)。为。表示这个chunk包含的是文件头信息。
表2 chunk中字节分配
字节
用途
0..5ll 512..515 516 517
文件和文件头数据 标记 数据状态。如果超过4位是O,表示这一页是被 丢弃的 块状态
518..519 标记
520..522 523..524
chuIlk中第二个256字节数据的Ecc 标记
525..527 chunk中第一个256字节数据的Ecc
嵌入式蒸巯编程
EMBEDDED SYSTEM PROGRAMMING

深入理解yaffs2文件系统(一)

深入理解yaffs2文件系统(一)

深⼊理解yaffs2⽂件系统(⼀)深⼊理解yaffs2⽂件系统(⼀)1、Flash⽂件系统1.1、背景已经有多种flash⽂件系统(FFSs)或flash块驱动(在之上运⾏⼀个常规的FS),同时都有优点或缺点。

Flash存储器有⾮常多的限制,这⾥就不⼀⼀列举了。

已经有各种⽅法解决这些限制,以提供⼀个⽂件系统。

必须认识到,“flash”,包括NOR和NAND,各⾃有不同的限制。

很容易被专业术语“flash”误导,误以为⽤于NorFlash的⽅法也⽴即适⽤于NandFlash。

Nand块驱动⼀般采⽤FAT16作为⽂件系统,但不够健壮,也不够贴近Flash的特性。

这些块驱动通过⼀个“本地--物理”的映射层来仿真可写的、类似于磁盘扇区的块。

当使⽤FAT16时,这些⽂件系统⼯作的相当好,它们内存消耗⼩,代码尺⼨也很⼩。

但就像所有基于FAT 的系统⼀样,它们很容易损坏(如,丢失簇)。

其他的途径则是设计整个⽂件系统,不是基于块驱动,⽽且是flash友好的,这允许更多的余地来解决上述所提到的问题。

当前有两个linux⽂件系统能⾮常好的⽀持NorFLash,那就是JFFS以及它的升级版本JFFS2。

这两者都提供⽇志机制,⼤⼤的提升了健壮性,这也是嵌⼊式系统特别重要的⼀个特性。

不幸的是,它们在RAM消耗和启动时间⽅⾯都不是很好。

JFFS在flash中的每⼀个journalling⽇志节点,需要⼀个基于RAM的jffs_node结构,每⼀个节点为48字节。

JFFS2做了⼀个⼤改进,通过剪裁相关的结构体(jffs2_raw_node_ref)⽽减少到16字节。

即使如此,在512字节页⼤⼩128M的NandFlash,按平均节点⼤⼩来算,也需要250000字节约4M⼤⼩。

JFFS和JFFS2在启动时,需要扫描整个flash阵列来查找journaling节点,并决定⽂件结构。

由于NAND容量⼤、慢、连续访问、需要ECC校验,这些特性将导致不可接受的、很长的启动时间。

linux vfs实现原理 -回复

linux vfs实现原理 -回复

linux vfs实现原理-回复Linux VFS(Virtual File System)是一个抽象的文件系统接口,它为不同的文件系统提供了统一的访问方法,使得用户和应用程序可以无需关心底层文件系统的细节而进行文件的读取、写入以及其他操作。

本文将一步一步解析Linux VFS的实现原理,包括它的功能、设计思想以及层次结构。

首先,让我们来了解一下Linux VFS的基本功能。

Linux VFS负责将不同类型的文件系统(如ext4、NTFS等)统一封装成统一的接口,使得用户和应用程序可以通过相同的方式对不同文件系统进行访问。

VFS提供了一系列的系统调用,如open、read、write等,这些系统调用通过VFS层传递给具体文件系统的实现。

无论是本地文件系统还是网络文件系统,只要实现了VFS所定义的接口,就可以方便地和Linux内核进行交互。

为了实现这一目标,Linux VFS采用了一种抽象的设计思想,即将不同文件系统的实现细节隐藏在VFS层之下。

这种设计思想可以使得用户及应用程序的编写变得更加简单,同时也方便了操作多个文件系统的统一管理。

在Linux VFS的层次结构中,最上层是用户空间的应用程序,它们通过系统调用间接地与VFS层进行交互。

VFS层负责解析不同系统调用,并将其转发给底层的具体文件系统实现。

在VFS层中,有一些关键的数据结构,比如文件描述符(file descriptor)以及与进程相关的文件系统状态(例如,当前目录、打开的文件列表等)。

接下来,我们来详细描述Linux VFS的实现原理。

当用户应用程序调用open系统调用时,VFS层会进行一系列的操作来实现文件的打开。

首先,VFS会根据文件路径找到对应的inode(节点),inode是文件在文件系统中的表示,它包含了文件的元数据信息,如权限、文件大小等。

VFS会判断文件系统的类型,并将文件操作转发给具体的文件系统实现。

文件系统实现根据inode找到对应的数据块,并通过驱动程序将数据块从磁盘读取到内存中。

文件系统(大地小神之个人收藏)

文件系统(大地小神之个人收藏)

YAFFSYAFFS(Y e t A n o t h e r F l a s h F i l e S y s t e m)是第一个专门为NAND Flash存储器设计的嵌入式文件系统,适用于大容量的存储设备;并且是在GPL(General Public License)协议下发布的,可在其网站免费获得源代码。

YAFFS中,文件是以固定大小的数据块进行存储的,块的大小可以是512字节、1 024字节或者2 048字节。

这种实现依赖于它能够将一个数据块头和每个数据块关联起来。

每个文件(包括目录)都有一个数据块头与之相对应,数据块头中保存了ECC(Error Correction Code)和文件系统的组织信息,用于错误检测和坏块处理。

充分考虑了NAND Flash的特点,YAFFS把这个数据块头存储在Flash的16字节备用空间中。

当文件系统被挂载时,只须扫描存储器的备用空间就能将文件系统信息读入内存,并且驻留在内存中,不仅加快了文件系统的加载速度,也提高了文件的访问速度,但是增加了内存的消耗。

为了在节省内存的同时提高文件数据块的查找速度,YAFFS利用更高效的映射结构把文件位置映射到物理位置。

文件的数据段被组织成树型结构,这个树型结构具有32字节的节点,每个内部节点都包括8个指向其他节点的指针,叶节点包括16个2字节的指向物理地址的指针。

Y AFFS在文件进行改写时总是先写入新的数据块,然后将旧的数据块从文件中删除。

这样即使在修改文件时意外掉电,丢失的也只是这一次修改数据的最小写入单位,从而实现了掉电保护,保证了数据完整性。

结合贪心算法的高效性和随机选择的平均性,YAFFS实现了兼顾损耗平均和减小系统开销的目的。

当满足特定的小概率条件时,就会尝试随机选择一个可回收的页面;而在其他情况下,则使用贪心算法来回收最“脏”的块。

YAFFS文件系统是按层次结构设计的,分成以下4部分:yaffs_guts.c,文件系统的主要算法,这部分代码完全是用可移植的C 语言编写的;yaffs_fs.c,Linux VFS层的接口;NAND 接口,yaffs_guts 和NAND 内存访问函数之间的包装层,例如调用Linux mtd 层或者RAM模拟层;可移植函数,服务的包装函数。

vfs函数

vfs函数

vfs函数VFS(Virtual File System)是一个抽象层,即一个虚拟的文件系统。

VFS屏蔽了底层文件系统的具体实现细节,提供了一组标准的文件操作接口,应用程序只需通过调用这组接口即可完成对各种文件系统的访问。

VFS是Linux内核的一部分,作为Linux内核的一个核心组件,VFS函数对于操作系统的正常运行至关重要。

以下是围绕VFS函数的分步骤解析:1. VFS函数的作用在Linux系统中,当用户需要通过软件程序调用文件系统实现文件读写时,核心服务就需要进行相应的文件系统操作。

VFS函数提供了一系列的接口,用于支持用户和应用程序访问各种文件系统。

这些接口包括:文件打开和关闭、文件读取和写入、文件大小和文件偏移量、文件重命名、文件属性访问等。

这些接口封装在一个共同的抽象层中,使得不同的文件系统都可以使用统一的接口进行访问。

2. VFS函数的结构体定义在Linux内核中,VFS函数使用结构体进行封装。

其中,最为核心的结构体是“file_operations”和“inode_operations”。

在Linux内核中,每一种文件系统都有一个唯一的inode_operations指针和file_operations指针。

这两个指针封装了访问某一种特定文件系统的所有必需功能。

3. VFS函数的实现实现VFS函数的方式有多种。

其中,Linux内核提供了多种方便高效的接口,常见的有内存映射和DMA(直接内存访问)等。

这些接口可以让应用程序更加高效地访问文件系统。

4. VFS函数的调试对于Linux内核程序员来说,调试是不可避免的一项工作。

在调试VFS函数时,最常见的方式就是通过内核调试器来实现。

例如,Linux提供了GDB(GNU调试器)这样的调试工具,程序员可以使用它来跟踪VFS函数的执行过程,检查代码逻辑并定位问题。

5. VFS函数的优化随着文件系统越来越复杂,VFS函数经常会成为性能优化的瓶颈。

YAFFS 文件系统的工作原理

YAFFS 文件系统的工作原理

/view/c10d30ea81c758f5f61f67dd.html通常一个具体的文件系统都会在VFS 的SuperBlock 结构中存储通用的数据,同时也有自己私有的数据。

Y AFFS 文件系统的专用数据是一个yaffs_DeviceStruct 的数据结构,主要用来存储一些相关硬件配置信息,相关函数指针和统计信息等。

由于Y AFFS 文件系统中该结构的特殊性,使得它的工作原理与Ext2 等文件系统有所不同。

1. 加载Y AFFS 文件系统Y AFFS 文件系统的SuperBlock 块是在文件系统加载的过程中由read_super() 函数填充的,存储在NAND Flash 上的文件系统结构中并不存在所谓的SuperBlock 块,同时,也没有存储标示Y AFFS 文件系统的魔术数,这个特殊的数值也是在文件系统加载的过程中直接赋值的,所以存储在NAND Flash 上的任何文件系统都能被当做Y AFFS 文件系统加载上来,只是对于非Y AFFS 文件系统的数据都会被当做错误数据放在lost+found 目录中。

2. 建立目录结构在执行read_super() 函数的过程中,Y AFFS 文件系统需要文件系统的目录结构在内存中建立起来。

首先需要扫描Y AFFS 分区,根据从OOB (Out of Band)中读取出的yaffs_tags 数据结构判断出是文件头页面还是数据页面。

在根据文件头页面中的内容以及数据页面中ObjectID、CHunkID、serial Number等信息在内存中为每个文件建立一个对应的yaffs_object 对象。

在yaffs_object 对象中,主要包含了:> 用做组织结构的,如指向父目录的Parent 指针,指向同级目录中其他对象链表的siblings 双向链表头结构> 用做Y AFFS 文件系统维护用的各种标记位,如脏标记,删除标记等> 修改时间,用户ID、组ID 等文件属性此外根据yaffs_object 对象类型的不同,对应于某一具体类型的对象,如目录,文件,链接等,在yaffs_object 中还有其各自的数据内容。

yaffs第三篇之综述篇

yaffs第三篇之综述篇

最近做了一件事情,就是把yaffs从linux中拨出来移植到了实地址模式下(yaffs direct),既然是实地址,所以可以直接用在不跑操作系统的程序中,或者运行ucos, nucleus等实地址的操作系统。

网上盛行的将yaffs移植到c51下就是这种方式。

yaffs 为这种方式起了个名字叫yaffs dircet,其实这部分的移植只要理解了yaffs的基本框架,读一下yaffs中documents,个人觉得难度不大,这里就不把移植过程贴出来了,如果各位有需要,可以发邮件告诉我,leeming1203@,可以提供代码。

好像有点跑题了,为什么之前讲了这么一大堆关于yaffs directory的话,因为如果要真正的理解yaffs,看yaffs directory是最方便,也是最容易理解yaffs核心的方法。

因为yaffs direct 直接是文件系统和nandflash之间的交互,少了在linux mtd的概念,能更清晰的理解,当然核心代码是不变的。

而且阅读yaffs direct还有一个好处,少去了linux下vfs的转换,可以清楚的看到怎么样来构建一个文件系统,怎么对一个文件进行读写,特别是yaffs direct可以直接用ice单步,感觉棒极了!先贴一段基于yaffs direct的应用代码:int file_rw_test(void){int a;int i;char buffer1[1000];memset(buffer1,0,sizeof(buffer1));yaffs_StartUp();yaffs_mount("/flash");a = yaffs_open("/flash/j",O_CREAT | O_RDWR , S_IREAD | S_IWRITE);yaffs_lseek(a,0,SEEK_SET);yaffs_write(a,"abcdefghijklmnopqrstuvwxyz",20);yaffs_lseek(a,0,SEEK_SET);yaffs_read(a,buffer1,20);printf("the read buffer is %s\n",buffer1);// if you want the data from cache to the nand, must remember yaffs_closeyaffs_close(a);return 1;}可以看到使用yaffs最最核心的函数有:yaffs_StartUp();//对使用的yaffs分区设定yaffs_mount("/flash");// /flash是在yaffs_StartUp()设定的分区,这里是把这个分区挂载上去yaffs_open("/flash/j",O_CREAT | O_RDWR , S_IREAD | S_IWRITE);//在/flash目录下创建一个名叫j的文件。

yaffs2 结构 -回复

yaffs2 结构 -回复

yaffs2 结构-回复YAFFS2 结构YAFFS2(Yet Another Flash File System 2)是一种用于嵌入式系统的文件系统,特别适用于闪存设备。

它的灵感来自于早期的YAFFS文件系统,但在架构和功能上有所改进。

YAFFS2提供了高效的数据存储和管理方式,使闪存设备在读写操作方面更加稳定和可靠。

YAFFS2的主要结构包括:块(Block)、页(Page)、幸存页(Spare Page)和节点(Node)。

首先,让我们从块开始。

块是YAFFS2中最小的存储单元,它由连续的页组成。

每个块的大小通常为128KB或256KB。

闪存设备的数据存储是以块为单位进行的,这意味着当我们需要存储一个文件或一个数据块时,实际上是将其存储到一个或多个连续的块中。

在每个块中,数据被分为多个页。

每个页的大小通常为2KB或4KB。

这样的设计使得YAFFS2能够更高效地进行读写操作,因为闪存设备的读写速度是以页为单位的。

幸存页是指在每个块中用于存储元数据的页。

元数据包括节点、标志位、CRC等信息。

幸存页的存在使得YAFFS2能够更好地管理闪存设备的使用情况,并使得数据的读写更加可靠。

最后,我们来看一下节点。

节点对于YAFFS2来说非常重要,它是文件系统中的基本单位。

每个节点对应着一个文件或目录。

节点存储了文件的元数据,如文件名、文件大小、文件权限等。

除此之外,节点还存储了指向文件数据在闪存设备上位置的指针。

通过以上的结构,YAFFS2实现了对闪存设备的高效管理和读写。

当我们在闪存设备上创建一个文件时,YAFFS2会为该文件创建一个对应的节点,并将其相关信息存储在该节点中。

当我们写入数据时,YAFFS2将数据分为页,并将这些页存储在连续的块中。

为了保证数据的完整性,YAFFS2还会计算并存储CRC等校验信息。

在读取数据时,YAFFS2会通过节点找到数据的位置,并将其读取到应用程序中。

此外,YAFFS2还具备一些高级功能,如快照(Snapshot)和压缩(Compression)。

YAFFS文件系统详细介绍

YAFFS文件系统详细介绍

yaffs_Object 可以是档案(File)、目录
(Directory)、SoftLink 或是 Hardlink 其中一种,而每一个 yaffs_Object 都会对应到一个 yaffs_ObjectHeader,而 yaffs_ObjectHeader 则是用以储存此 yaffs_Object 的一些属性 值,例如该 yaffs_Object 是 File 或是 Directory,此 yaffs_Object 的 parentObjectId 为何…等等。yaffs_Object 亦有如下的目录结构:
YAFFS 文件系统详细介绍
一、 摘要 在现在 Embedded System 的广泛应用下,其硬件及软件的建置及设 计则需要相当大的考虑,亦因为其所需要的效率考虑下,挑选适用的内 部储存装置则相当的重要,一般常见的内部储存装置为硬盘及闪存 (Flash Memory),虽然硬盘的容量相当大,但是其执行速度相当的慢、 体积大且不耐震,较不适用于需要效率、体积及耐震考虑的 Embedded System,因为 Flash Memory 速度快,体积小及耐震的特性,大部份的 Embedded System 皆使用 Flash Memory 做为其内部储存装置。如市面上 最常见到的行动电话、PDA(Personal Digital Assistant)内部储存 装置等或是数字相机所使用的记忆卡,皆使用 Flash Memory。因此该怎 么操作或更有效率的使用 Flash Memory,都是我们所要去关注的。 二、动机 Flash Memory 目前分为两种:NOR Flash Memory 及 NAND Flash Memory, 尤于 NAND Flash Memory 有较快的 Erase Time、Small Size 及成本较 低的特性下,使得 NAND 更适用于 Embedded System。Flash Memory 是 一储存装置, 若要使用此储存装置, 亦须要在 Flash Memory 上使用 File System。在一般的 Block Device(e.g. Disk)上使用的 File System, 如:NTFS、FAT32 和 ext2 等等,都可用于 Flash Memory 上,但是这些 File System 并非专为 Flash 所设计的,所以无针对 Flash 的特性去操

linux vfs实现原理

linux vfs实现原理

linux vfs实现原理【原创实用版】目录1.虚拟文件系统(VFS)的概念与作用2.VFS 的原理与实现3.VFS 在 Linux 中的应用实例4.VFS 的发展与未来趋势正文虚拟文件系统(VFS,Virtual Filesystem)是 Linux 中一种重要的文件系统技术。

它并不是一个具体的文件系统,而是一种抽象的、用于管理多个文件系统的机制。

VFS 为不同的文件系统提供了统一的接口,使得在操作系统中,用户和应用程序可以通过这个接口对各种文件系统进行操作。

一、虚拟文件系统(VFS)的概念与作用1.概念虚拟文件系统是一种操作系统中的抽象层,用于在实际文件系统之上统一管理和操作多种不同类型的文件系统。

VFS 将不同类型的文件系统(如 ext2、ext3、jffs 等)统一起来,为上层应用程序提供了一个简化、统一的文件操作接口。

2.作用VFS 的主要作用有:(1)简化文件操作:通过 VFS,应用程序可以对多种不同类型的文件系统进行统一操作,无需关心底层文件系统的具体实现。

(2)提高系统可扩展性:VFS 允许系统管理员灵活地挂载、卸载文件系统,方便地对系统进行扩展和维护。

(3)支持文件系统的并发访问:VFS 可以为多个文件系统提供并发访问的支持,提高了系统的性能。

二、VFS 的原理与实现1.原理VFS 的核心思想是提供一个虚拟的文件系统接口,将多个实际的文件系统映射到这个虚拟接口上。

当应用程序通过 VFS 接口发起文件操作请求时,VFS 会将请求转换为相应的底层文件系统命令,并根据文件系统的类型和位置进行相应的处理。

2.实现VFS 的实现主要依赖于 Linux 内核中的 VFS 层(虚拟文件系统开关,Virtual Filesystem Switch)。

VFS 层负责管理文件系统的挂载、卸载和文件操作,具体实现包括以下几个方面:(1)文件系统驱动:为不同类型的文件系统提供相应的驱动程序,以便 VFS 能够与这些文件系统进行交互。

YAFFS文件系统移植笔记

YAFFS文件系统移植笔记

YAFFS文件系统移植笔记YAFFS文件系统移植笔记基于Linux2.6的YAFFS文件系统移植v1.0,2005-6-6一、YAFFS文件系统简介YAFFS,Yet Another Flash File System,是一种类似于JFFS/JFFS2的专门为Flash设计的嵌入式文件系统。

与JFFS相比,它减少了一些功能,因此速度更快、占用内存更少。

YAFFS和JFFS都提供了写均衡,垃圾收集等底层操作。

它们的不同之处在于:(1)、JFFS是一种日志文件系统,通过日志机制保证文件系统的稳定性。

YAFFS仅仅借鉴了日志系统的思想,不提供日志机能,所以稳定性不如JAFFS,但是资源占用少。

(2)、JFFS中使用多级链表管理需要回收的脏块,并且使用系统生成伪随机变量决定要回收的块,通过这种方法能提供较好的写均衡,在YAFFS中是从头到尾对块搜索,所以在垃圾收集上JFFS的速度慢,但是能延长NAND的寿命。

(3)、JFFS支持文件压缩,适合存储容量较小的系统;YAFFS不支持压缩,更适合存储容量大的系统。

YAFFS还带有NAND芯片驱动,并为嵌入式系统提供了直接访问文件系统的API,用户可以不使用Linux中的MTD和VFS,直接对文件进行操作。

NAND Flash大多采用MTD+YAFFS的模式。

MTD ( Memory T echnology Devices,内存技术设备)是对Flash操作的接口,提供了一系列的标准函数,将硬件驱动设计和系统程序设计分开。

二、YAFFS文件系统的移植yaffs代码可以从下载(yaffs代码包括yaffs_ecc.c,yaffs_fileem.c,yaffs_fs.c,yaffs_guts.c,yaffs_mtdif.c,yaffs_ramem.c。

)表一 Yaffs文件系统源代码相关文件及功能描述文件名功能yaffs_ecc.c ECC校验算法yaffs_fileem.c 测试flashyaffs_fs.c 文件系统接口函数yaffs_guts.c Yaffs文件系统算法yaffs_mtdif.c NAND函数yaffs_ramem.c Ramdisk实现1.内核中没有YAFFS,所以需要自己建立YAFFS目录,并把下载的YAFFS代码复制到该目录下面。

Linux的YAFFS文件系统实现机制分析

Linux的YAFFS文件系统实现机制分析

核心结构在内存中的建立—Mount过程 第一步:逐块扫描所有块状态,取得“need scanning”状态 的块的tag中的sequenceNumber,按sequenceNumber值的从 大到小给块排序放来自blockIndex[]表中。
第二步:开始倒序扫描,把所有的yaffs_Object及其之间的 关联架构在RAM中建立起来。同时建立文件的地址映射关 系Tnode结构。 第三步:建立页、块状态信息表 块分配状态信息 : struct yaffs_BlockInfo; 页状态信息: yaffs_Device 提供一个32位的位图chunkBits[ ] ,每一位都代表着Flash上的一个chunk的状态
过Scan来重新建立Object。这个时候,上面所讲
sequenceNumber及ishrink日志的作用就是还原到最新 的状态。
Linux下YAFFS文件系统的读写操作
存储空间的回收,即YAFFS的垃圾回收策略:
YAFFS的垃圾回收策略为了兼顾损耗平均和减小系统 开销的目的,结合贪心算法的高效性和随机选择的平 均性,保留2到3个块用于垃圾块收集。当没有足够的 干净块的时候,脏块(只包含丢弃数据)将会按分配 顺序最早(sequenceNumber最小)的,将被擦除成干 净块。如果没有脏块,那些特别脏的块(含有丢弃数 据特别多的块)也会被垃圾块回收算法选中。

Thank you!
YAFFS超级块操作: struct yaffs_super_ops YAFFS索引节点操作: struct yaffs_dir_inode_operations struct yaffs_symlink_inode_operation struct yaffs_file_inode_operations YAFFS文件操作: struct yaffs_dir_operations

Yaffs文件系统简介

Yaffs文件系统简介

Yaffs⽂件系统简介1 简介1.1 应⽤场合Yaffs(Yet Another Flash File System)⽂件系统是专门针对NAND闪存设计的嵌⼊式⽂件系统,⽬前有YAFFS和YAFFS2两个版本,两个版本的主要区别之⼀在于YAFFS2能够更好的⽀持⼤容量的NAND FLASH芯⽚。

1.2 Yaffs⽂件系统数据在NAND上的存储⽅式Yaffs对⽂件系统上的所有内容(⽐如正常⽂件,⽬录,链接,设备⽂件等等)都统⼀当作⽂件来处理,每个⽂件都有⼀个页⾯专门存放⽂件头,⽂件头保存了⽂件的模式、所有者id、组id、长度、⽂件名、Parent Object ID等信息。

因为需要在⼀页内放下这些内容,所以对⽂件名的长度,符号链接对象的路径名等长度都有限制。

前⾯说到对于NAND FLASH上的每⼀页数据,都有额外的空间⽤来存储附加信息,通常NAND驱动只使⽤了这些空间的⼀部分,Yaffs正是利⽤了这部分空间中剩余的部分来存储⽂件系统相关的内容。

以512+16B为⼀个PAGE的NAND FLASH芯⽚为例,Yaffs⽂件系统数据的存储布局如下所⽰:0..511数据区域512..515YAFFS TAG516Data status byte517Block status byte 坏块标志位518..519YAFFS TAG520..522后256字节数据的ECC校验结果523..524YAFFS TAG525..527前256字节数据的ECC校验结果可以看到在这⾥YAFFS⼀共使⽤了8个BYTE⽤来存放⽂件系统相关的信息(yaffs_Tags)。

这8个Byte的具体使⽤情况按顺序如下:Bits Content20ChunkID,该page在⼀个⽂件内的索引号,所以⽂件⼤⼩被限制在2^20 PAGE 即512Mb2 2 bits serial number10ByteCount 该page内的有效字节数18ObjectID 对象ID号,⽤来唯⼀标⽰⼀个⽂件12Ecc, Yaffs_Tags本⾝的ECC校验和2Unused其中Serial Number在⽂件系统创建时都为0,以后每次写具有同⼀ObjectID和ChunkID的page的时候都加⼀,因为Yaffs在更新⼀个PAGE的时候总是在⼀个新的物理Page上写⼊数据,再将原先的物理Page删除,所以该serial number可以在断电等特殊情况下,当新的page已经写⼊但⽼的page还没有被删除的时候⽤来识别正确的Page,保证数据的正确性。

Yaffs功能说明

Yaffs功能说明

Yaffs功能说明1 背景2 发牌3 Yaffs 和 Yaffs 直接接⼝有哪些?4 为什么使⽤ Yaffs 吗?5 源代码和 Yaffs 资源6 系统要求7 如何与实时操作系统/Embedded 系统集成 Yaffs7.1 源⽂件7.2 整合POSIX应⽤程序接⼝7.3 RTO集成接⼝8 Yaffs NAND模型Yaffs1 8.1 NAND模型注意事项Yaffs2 8.2 NAND模型9 NAND配置和访问接⼝9.1 常见配置项 (Yaffs1 和 Yaffs2)9.2 共同访问函数 (Yaffs1 和 Yaffs2)9.3 Yaffs1 访问函数9.4 Yaffs2 访问函数10 使⽤POSIX⽂件系统接⼝10.1 向 Windows POSIX差异-喜欢接⼝10.2 基本概念10.3 错误代码10.4 链接——硬种 (不是符号链接)10.5 符号链接10.6 基于句柄的⽂件处理10.7 更改⽂件⼤⼩10.8 获取/设置有关⽂件的信息10.9 更改⽬录结构和名称10.10 搜索⽬录10.11 装载控制10.12 其他11 ⽰例: yaffs_readdir() 和 yaffs_stat()1 背景本⽂档的⽬的是描述接⼝的Yaffs 直接接⼝(YDI) 以及提供⾜够的信息,以允许Yaffs 初步评价。

这份⽂件试图把重点放在重要的系统集成商的问题没有得到Yaffs 是如何⼯作的太详细。

其他⽂件提供Yaffs 的⼯作原理进⾏深⼊的讨论。

2 发牌Yaffs 最初被⽤于Linux 下GNU公共许可证(GPL) 发布。

很快就查明,Yaffs 将他们应⽤的理想选择,但是却不能使⽤GPL的各种嵌⼊式开发⼈员在其系统中基于代码的。

Aleph ⼀有替代的发牌安排,以⽀持此类应⽤程序。

3 Yaffs 和 Yaffs 直接接⼝有哪些?Yaffs 代表尚未另⼀个Flash ⽂件系统。

Yaffs 是第⼀个⽂件为设计的系统,从地上起来,nand 闪存存储。

yaffs2文件系统实现原理分析_带书签

yaffs2文件系统实现原理分析_带书签

1 概述YAFFS (Yet Another Flash File System )文件系统是专门针对NAND flash 设计的嵌入式文件系统,目前有YAFFS 和Y AFFS2两个版本,两个版本的主要区别之一在于Y AFFS2 能够更好的支持大容量的NAND flash 芯片。

YAFFS 文件系统有些类似于JFFS/JFFS2文件系统,与之不同的是JFFS/JFFS2文件系统最初是针对NOR flash 的应用场合设计的,而NORflash 和NAND flash 本质上有较大的区别,尽管JFFS/JFFS2文件系统也能应用于NANDflash ,但由于它在内存占用和启动时间方面针对NOR 的特性做了一些取舍,所以YAFFS2对NAND flash 来说通常才是最优的选择方案。

2 相关概念分析YAFFS2之前,把NAND flash 相关概念介绍下:NAND flash 由块(block)组成,块又由页(page)构成,擦除时以块为单位,读写时以页为单位,页又包含数据区和空闲区(OOB,Out-Of-Band),而Page 在YAFFS2中被称为Chunk ,其中的数据区用来存放实际的数据,OOB 用来存放附加信息实现NAND flash 的管理。

以T8000 AXMPFUA 单板使用的NANDflash 为例,每块Block: 128 pages ,每页Page: (8K + 448) bytes ,数据区为8K ,OOB 为448bytes ,如图1所示:Plane :4096blocks128 pages(8K+448)bytes图1 NAND flash 物理结构3 数据结构struct yaffs_dev 是YAFFS2文件系统最核心的数据结构,表示Y AFFS2文件系统的超级块,它建立了整个文件系统的层次结构,并衔接VFS 层和MTD 层,与struct super_block 、struct mtd_info 的关系如图2所示:图2 yaffs_dev与super_block、mtd_info层次关系下面围绕struct yaffs_dev这个最核心的数据结构开始,分段介绍它的含义,进而引出其他重要的数据结构:■param:存储文件系统重要的一些参数,以及与MTD层的接口函数□inband_tags:标志位,默认为0,即采用OOB(out of band)方式存储tags,可以通过挂载时指定inband-tags选项改变默认值□total_bytes_per_chunk:每个chunk总的字节数□chunks_per_block:每个block总的chunk数□spare_bytes_per_chunk:每个chunk包含OOB块的字节数□start_block:第一个可以使用的block□end_block:最后一个可以使用的block□n_reserved_blocks:为GC保留的block阈值□n_caches:缓冲区的个数,YAFFS2为减少数据的碎片以及提高性能为每个文件的写入提供了cache□no_tags_ecc:标志位,默认为0,即tags中包括ECC纠错信息,可以通过内核配置改变默认值,CONFIG_YAFFS_DISABLE_TAGS_ECC□is_yaffs2:标志位,默认为0,即Y AFFS,在挂载的过程中会根据识别的mtd->writesize自动转换成YAFFS2□refresh_period:刷新周期,刷新目的主要找出最旧的处于YAFFS_BLOCK_STATE_FULL状态的block,供GC作为gc_block使用□skip_checkpt_rd:标志位,默认为0,支持读取checkpoint,提高挂载速度的一个功能可以通过挂载时指定挂载选项no-checkpoint-read、no-checkpoint修改默认值□skip_checkpt_wr:标志位,默认为0,支持写入checkpoint,提高挂载速度的一个功能可以通过挂载时指定挂载选项no-checkpoint-write、no-checkpoint修改默认值□write_chunk_tags_fn:函数指针,在挂载的文件系统的时候会被初始,NANDflash写入接口函数:param->write_chunk_tags_fn = nandmtd2_write_chunk_tags;□read_chunk_tags_fn:函数指针,在挂载的文件系统的时候会被初始,NANDflash读取接口函数:param->write_chunk_tags_fn = nandmtd2_write_chunk_tags;□erase_fn:函数指针,在挂载的文件系统的时候会被初始,NAND flash擦除block接口函数:param->erase_fn = nandmtd_erase_block;□wide_tnodes_disabled:标志位,默认值为0,采用动态位宽,通过内核配置修改可采用静态位宽CONFIG_YAFFS_DISABLE_WIDE_TNODES■os_context:指向yaffs_linux_context结构指针,该结构存储Y AFFS2运行环境,如下:□context_list:通过该字段加入到yaffs_context_list全局链表中□dev:指向Y AFFS2文件系统超级块的指针□super:指向VFS层超级块的指针□bg_thread:Y AFFS2后台垃圾回收线程的指针□bg_running:启动和停止垃圾回收线程的标志位,1:启动,0:停止□gross_lock:互斥锁,保护整个超级块关键字段的互斥访问,粒度比较大□spare_buffer:OOB块的缓冲区□search_contexts:通过该字段把所有Directory Search Context组成链表□yaffs_mtd_put_super:卸载文件系统时被调用来清理super_block□readdir_process:解决使用NFS死锁问题加入的□mount_id:每个NAND flash分区挂载YAFFS2都分配不同的ID号■driver_context:指向mtd_info结构指针,mtd_info是MTD子系统核心的数据结构,主要是对底层硬件驱动进行封装,这里不再介绍■data_bytes_per_chunk:每个chunk总的字节数,和前面提到的total_bytes_per_chunk一样■chunk_grp_bits :采用静态位宽时超过tnode_width宽度之后的位数,采用动态位宽值恒为0■chunk_grp_size:由chunk_grp_bits转化而来的大小■tnode_width:采用静态位宽默认是16,采用动态位宽是由整个NAND flash中chunk数目计算得到■tnode_mask:位宽的mask,主要用于快速获取chunk id号■tnode_size:YAFFS_NTNODES_LEVEL0节点所占用的内存大小,单位:byte■chunk_shift:主要用来计算logical chunk index以及logical chunk offset■chunk_div:作用同chunk_shift,主要用于chunk大小不是2次幂的情况■chunk_mask:作用同chunk_shift,组合起来计算logical chunk offset■is_mounted:标志位,文件系统挂载时被置位Checkpoint是为提高挂载速度而引入的功能,作用同JFFS2的EBS,以空间来换取时间,卸载时通过在NAND flash上保存文件系统超级块快照,挂载时获取快照信息可以快速还原系统的状态。

yaffs checkpoint机制

yaffs checkpoint机制

yaffs checkpoint机制YAFFS检查点机制YAFFS(Yet Another Flash File System)是一种专为闪存设备设计的文件系统。

它的检查点机制是确保数据完整性和可靠性的关键组成部分。

本文将介绍YAFFS的检查点机制及其工作原理。

检查点是指将当前状态保存到闪存中的操作。

在闪存设备中,数据存储在不可擦除的存储单元中,因此更新数据时需要先将旧数据复制到新的存储位置,再写入新数据。

这种操作被称为擦除-写入操作。

然而,如果在擦除-写入操作中断或出现错误,可能会导致数据丢失或损坏。

为了解决这个问题,YAFFS引入了检查点机制。

YAFFS的检查点机制通过将元数据和数据分开存储来确保数据的完整性。

元数据是描述文件系统结构和文件属性的信息,而数据是文件中实际存储的内容。

在YAFFS中,元数据被组织成树状结构,称为元数据树(MTree)。

每个节点包含元数据的副本,并记录了子节点的位置。

在进行擦除-写入操作之前,YAFFS首先将元数据复制到新的存储位置。

这样,即使在写入新数据时发生错误,原始的元数据仍然可用。

一旦新数据被成功写入,YAFFS会更新元数据,指向新的数据位置。

这个过程确保了数据的完整性,即使在擦除-写入操作中断或出现错误的情况下。

YAFFS的检查点机制还具有可恢复性的特点。

当系统重启或发生其他故障时,YAFFS能够从最近的检查点恢复。

它会使用元数据树中的信息来恢复文件系统的状态,并检查数据的一致性。

如果发现数据损坏或丢失,YAFFS会尝试从其他副本中恢复数据。

检查点机制的实现需要考虑到性能和空间的折衷。

在YAFFS中,检查点的频率和存储空间的使用是可以配置的。

较频繁的检查点可以提供更好的数据可靠性,但会增加系统开销和存储空间的使用。

因此,根据具体的应用需求,可以根据需要调整检查点机制的配置。

YAFFS的检查点机制是确保数据完整性和可靠性的重要机制。

通过将元数据和数据分开存储,并使用元数据树来记录文件系统的状态,YAFFS能够在擦除-写入操作中断或发生错误时保护数据。

linux文件读写浅析

linux文件读写浅析

linux文件读写浅析在《linux内核虚拟文件系统浅析》这篇文章中,我们看到文件是如何被打开、文件的读写是如何被触发的。

对一个已打开的文件fd进行read/write系统调用时,内核中该文件所对应的file结构的f_op->read/f_op->write被调用。

本文将顺着这条路走下去,大致看看普通磁盘文件的读写是怎样实现的。

linux内核响应一个块设备文件读写的层次结构如图(摘自ULK3):1、VFS,虚拟文件系统。

之前我们已经看到f_op->read/f_op->write如何被调用,这就是VFS干的事(参见:《linux内核虚拟文件系统浅析》);2、Disk Caches,磁盘高速缓存。

将磁盘上的数据缓存在内存中,加速文件的读写。

实际上,在一般情况下,read/write是只跟缓存打交道的。

(当然,存在特殊情况。

下面会说到。

)read就直接从缓存读数据。

如果要读的数据还不在缓存中,则触发一次读盘操作,然后等待磁盘上的数据被更新到磁盘高速缓存中;write也是直接写到缓存里去,然后就不用管了。

后续内核会负责将数据写回磁盘。

为了实现这样的缓存,每个文件的inode内嵌了一个address_space结构,通过inode->i_mapping来访问。

address_space结构中维护了一棵radix树,用于磁盘高速缓存的内存页面就挂在这棵树上。

而既然磁盘高速缓存是跟文件的inode关联上的,则打开这个文件的每个进程都共用同一份缓存。

radix树的具体实现细节这里可以不用关心,可以把它理解成一个数组。

数组中的每个元素就是一个页面,文件的内容就顺序存放在这些页面中。

于是,通过要读写的文件pos,可以换算得到要读写的是第几页(pos是以字节为单位,只需要除以每个页的字节数即可)。

inode被载入内存的时候,对应的磁盘高速缓存是空的(radix树上没有页面)。

随着文件的读写,磁盘上的数据被载入内存,相应的内存页被挂到radix树的相应位置上。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Y affs通过VFS层的读写Mournjust(sev7ncolor@)在看过dreamice的《yaffs文件系统分析》之后,总是感到意犹未尽,还不够深入,所以先结合自己了解的一些知识继续写下去。

Y affs文件系统最终是通过VFS层接口被调用的,所以yaffs必须给VFS层提供相应的接口。

VFS提供的标准接口结构是inode和dentry结构,也就是说不管最终yaffs是如何实现的,提供给VFS层的必须是inode和dentry结构。

在yaffs中,函数yaffs_fill_inode_from_obj用于根据yaffs的结构体yaffs_obj来填充inode 结构体,以便于VFS层使用。

static void yaffs_fill_inode_from_obj(struct inode *inode,struct yaffs_obj *obj){....switch (obj->yst_mode & S_IFMT) {default: /* fifo, device or socket */init_special_inode(inode, obj->yst_mode,old_decode_dev(obj->yst_rdev));break;case S_IFREG: /* file */inode->i_op = &yaffs_file_inode_operations;inode->i_fop = &yaffs_file_operations;inode->i_mapping->a_ops = &yaffs_file_address_operations;break;case S_IFDIR: /* directory */inode->i_op = &yaffs_dir_inode_operations;inode->i_fop = &yaffs_dir_operations;break;case S_IFLNK: /* symlink */inode->i_op = &yaffs_symlink_inode_operations;break;}....}其中obj->yst_mode 用于表示yaffs_obj指代的object是具体文件、目录、symlink,以及hardlink等等。

对于不同类型的object,显然处理的方法是不一样。

首先需要关注的是关于VFS的缓冲页的操作结构体:static struct address_space_operations yaffs_file_address_operations = {.readpage = yaffs_readpage,.writepage = yaffs_writepage,#if (Y AFFS_USE_WRITE_BEGIN_END > 0).write_begin = yaffs_write_begin,.write_end = yaffs_write_end,#else.prepare_write = yaffs_prepare_write,.commit_write = yaffs_commit_write,#endif};因为内核版本的更新,原版本的prepare_write和commit_write函数被write_begin和write_end函数所代替,这儿为了保持yaffs的可移植性,采用了一个条件编译。

其中write_begin函数主要调用grab_cache_page_write_begin在radix树里面查找要被写的page,如果不存在则创建一个。

如果被写入的设备是一个块设备的话,调用__block_prepare_write为这个page准备一组buffer_head结构,用于描述组成这个page的数据块。

write_end主要用于将被写入的page标记为脏,后台进程pdflush会寻找这些脏页,并将数据写入设备中去。

如果被写入的设备是块设备的话,还需要将相应的buffer-head标记为脏。

static int yaffs_write_begin(struct file *filp, struct address_space *mapping,loff_t pos, unsigned len, unsigned flags,struct page **pagep, void **fsdata){struct page *pg = NULL;pgoff_t index = pos >> PAGE_CACHE_SHIFT;int ret = 0;int space_held = 0;/* Get a page */pg = grab_cache_page_write_begin(mapping, index, flags);首先根据文件内部偏移量算出所处的page位置index,然后根据index从文件的struct address_space中获得page。

当然如果不存在该page的话,内核也会为它分配一个page用于该段的缓存。

space_held = yaffs_hold_space(filp);接着调用yaffs_hold_space(filp);来判断flash内部是否存在足够的空间用于写操作。

这就是不同类型的文件系统相差别的地方。

可能存在下面的几种情况:(1)往文件中添加数据,但是设备中已经没有空间存放多余的数据了。

这种情况不仅仅在flash设备上存在,在块设备,磁盘也是存在的,是一种比较普遍的现象。

(2)NANDFLASH比较特殊,在每一次写入之前必须擦除。

这是由于NANDFLASH的特性决定的。

文件系统采用block-mapping的机制来进行回避,即将更新的数据写入一个新页中,然后将保存旧数据的旧页标记为脏,便于后面垃圾回收。

那么就是说在不增加任何数据量的修改过程中,也需要一个空闲页(这儿的页指flash的页)来进行数据更新。

会不会因为没有空闲页而导致更新失败呢?这个计算空闲空间的过程稍显复杂。

除了考虑flash中的空闲页之外,还需要考虑flash 中的脏页(不能因为是脏页就不算了,脏页可以通过garbage collection回收利用的)。

除了上面两点之外还需要考虑那些保存在缓冲区中尚未写入flash中的数据,虽然没有写进去,但是它也算是预先占有了空间。

n_free = dev->n_free_chunks;n_free += dev->n_deleted_files;/* Now count and subtract the number of dirty chunks in the cache. */for (n_dirty_caches = 0, i = 0; i < dev->param.n_caches; i++) {if (dev->cache[i].dirty)n_dirty_caches++;n_free -= n_dirty_caches;n_free_chunks记录着设备中空闲的chunk数目,n_deleted_files记录着设备中等待被删除的文件。

然后通过一个for循环来便来yaffs文件系统的缓冲区,看是否有缓冲区是脏的。

(即仍未写入设备中)。

blocks_for_checkpt = yaffs_calc_checkpt_blocks_required(dev);n_free -= (blocks_for_checkpt * dev->param.chunks_per_block);关于yaffs中的check pionter暂时还没弄清楚,呵呵=。

=if (!PageUptodate(pg))ret = yaffs_readpage_nolock(filp, pg);在写入数据之前(这儿的写入数据是指更新缓冲区中的数据),需要检查该页中的数据是否是最新,如果不是,需要将缓冲区中的数据从flash中更新。

虽然yaffs在设计上与VFS提供的接口完美的配合一起,但是yaffs的实现却取完全背离了VFS提供的缓冲页得原始初衷。

如果你在往yaffs的文件系统中拷贝数据的时候,通过top来观察pdflush线程组的资源使用情况,就会发现在往yaffs文件系统中拷贝数据的时候pdflush根本没有动静。

那是为什么呢?下面继续细细的研究一下yaffs的源码。

其实根本的原因在yaffs_write_end调用的函数yaffs_file_write上。

static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,loff_t * pos)该函数直接将保存在缓冲页中的数据写进了NANDFLASH中。

在这儿,缓冲页根本没有起到缓冲的效果,反而通过缓冲页的过渡降低了写入的数据。

但是没办法,这就是软件带来的消耗。

虽然yaffs没有使用内核提供的缓冲页机制,但是它也是带缓冲的,只不过这种缓冲是在文件系统内部实现的。

在文档中模仿情景分析,在介绍代码的过程中介绍各个数据结构、变量等等的含义。

/* Find a cached chunk */static struct yaffs_cache *yaffs_find_chunk_cache(const struct yaffs_obj *obj,int chunk_id){struct yaffs_dev *dev = obj->my_dev;int i;if (dev->param.n_caches < 1)return NULL;for (i = 0; i < dev->param.n_caches; i++) {if (dev->cache[i].object == obj &&dev->cache[i].chunk_id == chunk_id) {dev->cache_hits++;return &dev->cache[i];}}return NULL;}这个函数的代码比较简练,在yaffs设备的一个cache数组中,遍历的查找是否存在一个cache满足yaffs_obj和chunk_id方面的要求。

这个函数返回值的类型为struct yaffs_cache *,struct yaffs_cache 结构体定义在yaffs_guts.h中。

相关文档
最新文档