f2fs文件系统的页缓存
f2fs有三种inode,meta_inode,node_inode和普通的文件inode,前两种inode只存在于vfs层,且数量只有一个。meta_inode对应于SIT,NAT,SSA,checkpoint和super block这些文件系统元数据,node inode对应于main area的node segment的数据,普通文件inode读写的区域对应于main area的data segment。所以,所有的f2fs数据的读写都是通过vfs层的inode的。这些inode的保存在f2fs_sb_info中,在文件系统初始化时f2fs_fill_super生成。再看inode的初始化过程,在函数inode.c/f2fs_iget中:
struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
{struct f2fs_sb_info *sbi = F2FS_SB(sb);struct inode *inode;int ret = 0;inode = iget_locked(sb, ino);if (!inode)return ERR_PTR(-ENOMEM);if (!(inode->i_state & I_NEW)) {trace_f2fs_iget(inode);return inode;}if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi))goto make_now;ret = do_read_inode(inode);if (ret)goto bad_inode;
make_now:if (ino == F2FS_NODE_INO(sbi)) {inode->i_mapping->a_ops = &f2fs_node_aops;mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);} else if (ino == F2FS_META_INO(sbi)) {inode->i_mapping->a_ops = &f2fs_meta_aops;mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);} else if (S_ISREG(inode->i_mode)) {inode->i_op = &f2fs_file_inode_operations;inode->i_fop = &f2fs_file_operations;inode->i_mapping->a_ops = &f2fs_dblock_aops;} else if (S_ISDIR(inode->i_mode)) {inode->i_op = &f2fs_dir_inode_operations;inode->i_fop = &f2fs_dir_operations;inode->i_mapping->a_ops = &f2fs_dblock_aops;mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);} else if (S_ISLNK(inode->i_mode)) {inode->i_op = &f2fs_symlink_inode_operations;inode->i_mapping->a_ops = &f2fs_dblock_aops;} else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {inode->i_op = &f2fs_special_inode_operations;init_special_inode(inode, inode->i_mode, inode->i_rdev);} else {ret = -EIO;goto bad_inode;}unlock_new_inode(inode);trace_f2fs_iget(inode);return inode;bad_inode:iget_failed(inode);trace_f2fs_iget_exit(inode, ret);return ERR_PTR(ret);
}
初始化过程区别对待了meta_inode和node_inode,再看看它们的address_space_operation:
const struct address_space_operations f2fs_node_aops = {.writepage = f2fs_write_node_page,.writepages = f2fs_write_node_pages,.set_page_dirty = f2fs_set_node_page_dirty,.invalidatepage = f2fs_invalidate_node_page,.releasepage = f2fs_release_node_page,
};
const struct address_space_operations f2fs_meta_aops = {.writepage = f2fs_write_meta_page,.writepages = f2fs_write_meta_pages,.set_page_dirty = f2fs_set_meta_page_dirty,
};
也许大家会觉得奇怪,为什么只有writepage而没有readpage呢,那它们是怎么读磁盘上的数据呢?文件系统实现了两个函数node.c/get_node_page和checkpoint.c/get_meta_page,这两个函数的流程类似,都是首先使用grab_cache_page去获取特定位置的页,grab_cache_page首先会查找address_space的基数树,如果找到该页则返回,如果找不到,则从伙伴系统分配一个新的页;然后调用f2fs_readpage读取磁盘上该页的内容。
struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
{struct address_space *mapping = sbi->meta_inode->i_mapping;struct page *page;
repeat:page = grab_cache_page(mapping, index);if (!page) {cond_resched();goto repeat;}if (PageUptodate(page))goto out;if (f2fs_readpage(sbi, page, index, READ_SYNC))goto repeat;lock_page(page);if (page->mapping != mapping) {f2fs_put_page(page, 1);goto repeat;}
out:mark_page_accessed(page);return page;
}
get_meta_page的参数index,直接对应了该页在磁盘上的块地址,所以可以直接作为f2fs_readpage的参数。以读取SSA的一个实例看,如功能函数get_sum_page,该函数实现很简单,通过GET_SUM_BLOCK(sbi, segno)获取summary page的块地址,该宏展开为
#define GET_SUM_BLOCK(sbi, segno) \((sbi->sm_info->ssa_blkaddr) + segno)
sbi->sm_info->ssa_blkaddr是SSA区域的起始地址,segno是segment number,由于一个segment的summary存储在一个page上,因此直接相加就是块地址。
struct page *get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno)
{return get_meta_page(sbi, GET_SUM_BLOCK(sbi, segno));
}
而get_node_page稍稍有点不同:
struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid)
{struct address_space *mapping = sbi->node_inode->i_mapping;struct page *page;int err;
repeat:page = grab_cache_page(mapping, nid);if (!page)return ERR_PTR(-ENOMEM);err = read_node_page(page, READ_SYNC);if (err < 0)return ERR_PTR(err);else if (err == LOCKED_PAGE)goto got_it;lock_page(page);if (!PageUptodate(page)) {f2fs_put_page(page, 1);return ERR_PTR(-EIO);}if (page->mapping != mapping) {f2fs_put_page(page, 1);goto repeat;}
got_it:BUG_ON(nid != nid_of_node(page));mark_page_accessed(page);return page;
}
该函数的参数是node的number,在f2fs中,node number的实际块地址在NAT中存储,因此还需要读取NAT的数据,获得该node的块地址,这些工作在read_node_page中完成。
总的来说,f2fs通过这三种inode把它的全部数据都管理起来,不得不说这是非常巧妙的设计啊
f2fs文件系统的页缓存相关推荐
- 关闭linux系统中读写页缓存,Linux文件系统FAQ
Linux文件系统FAQ 2010年03月25日 最近实验室搞了一些列讲座,阿福师兄关于文件系统的讲座帮我弄清楚了一些以前不清楚的问题,以问答的形式对文件系统常见的问题进行了总结. Q: 文件系统如何 ...
- linux 更改ctime_Linux 的文件系统及文件缓存知识点整理
Linux的文件系统特点 文件系统要有严格的组织形式,使得文件能够以块为单位进行存储. 文件系统中也要有索引区,用来方便查找一个文件分成的多个块都存放在了什么位置. 如果文件系统中有的文件是热点文件, ...
- _Linux 的文件系统及文件缓存知识点整理
Linux的文件系统特点 文件系统要有严格的组织形式,使得文件能够以块为单位进行存储. 文件系统中也要有索引区,用来方便查找一个文件分成的多个块都存放在了什么位置. 如果文件系统中有的文件是热点文件, ...
- Linux的文件系统及文件缓存知识点整理
Table of Contents Linux的文件系统 文件系统的特点 ext系列的文件系统的格式 inode与块的存储 inode位图和块位图 文件系统的格式 目录的存储格式 Linux中的文件缓 ...
- F2FS文件系统架构与原理分析(五)——元数据组织及管理
from : http://blog.chinaunix.net/uid-28989651-id-3911126.html 1. 元数据区域 元数据区域包含以下几种元数据(参见博文:F2FS文件系统架 ...
- linux 页缓存 块缓存,页缓存和块缓存
页缓存和块缓存 独立的缓冲区–LRU块缓存 1.操作方式 为什么采用LRU? LRU代表最近最少使用(least recently used),指的是一种一般方法,可用于有效管理一个集合中最常使用的那 ...
- linux系统页面缓存,Linux 页缓存
(虚拟地址空间是相对磁盘空间到物理内存空间的映射而言来说的). 经内存映射的文件每次只读取一页内容,读取后的页保存在页缓存中,利用页缓存,可提高文件的访问速度.如图 10-6 所示,页缓存由 page ...
- linux文件系统的页高速缓存page cache中的核心数据结构address_space
address_space对象是文件系统中关于内存中页高速缓存的核心数据结构.这篇博客以address_space对象为切入点,分析文件系统的页高速缓存.(这里大部分都是从原作者那里复制过来的,外加上 ...
- vue如何实现单页缓存方案分析
实现全站的页面缓存,前进刷新,返回走缓存,并且能记住上一页的滚动位置,参考了很多技术实现,github上的导航组件实现的原理要么使用的keep-alive,要么参考了keep-alive的源码,但是只 ...
- linux系统页面缓存,Linux缓存机制之页缓存
内核采用一种通用的地址空间方案,来建立缓存数据与其来源之间的关联. 1) 内存中的页分配到每个地址空间.这些页的内容可以由用户进程或内核本身使用各式各样的方法操作.这些数据表示了缓存中的内容: 2) ...
最新文章
- c++返回值 注意事项
- 网站优化必知的五大发文注意事项
- python学习-使用制表符或者换行符来添加空白
- CF1594F-Ideal Farm【构造】
- linux suse11 nfs,suse11 nfsserver服务安装
- 飞秋下载2010正式版_飞秋下载
- Hive 元数据库表信息
- python计算N维数据的笛卡尔积
- 基于GTID Replication主从数据不一致操作
- 使用BetterZip结合自动操作工具和预设设置创建电影解压程序
- 淘宝最新签名算法分析(1)
- 卢卡奇总体性原则_读书笔记|卢卡奇物化与无产阶级意识无产阶级的立场(1)...
- vue3的语法使用总结api
- 山东大学计算机图形学实验(Opengl实现):Loop Subdivision算法对模型进行细分
- zebra扫码枪复位_条码扫描枪设置使用说明详解
- voip 客户端 android,基于Android平台的VoIP客户端开发与性能改进
- Android 11源码 修改系统App后进行编译
- IAP之boot实现
- AutoVue使用教程:如何在64位Linux上安装AutoVue
- 数据中心远程集中解决方案有哪些?