文件系统进阶
2018-05-17 18:02:49 37 举报
AI智能生成
克隆不点赞最没素质!!! 文件系统的基本数据结构和流程机制,xmind导入后,连线没了,悲催。
作者其他创作
大纲/内容
文件系统进阶
故事
时间线
一
有一个idea要存到优盘上
FAT32格式化优盘
每个bit都有了意义
layout
管理方法
把优盘插到linux系统上
linux系统抽象为块设备
块设备驱动创建块设备文件
/dev/block/sda/dev/block/sda1/dev/block/sda2
user
read
write
我们要告诉系统用什么文件系统的管理方法来处理优盘的字节
最终的呈现形式
目录+文件
fread
fwrite
块设备映射成目录
手动挂载
mount -t vfat /dev/block/sda1 /mnt/usb/sda1
内存中的分区管理数据结构
superblock
写文件操作三部曲
创建/打开文件
int fd = oepn(\"/mnt/usb/sda1/idea.txt\
路径上所有节点
inode缓存
struct inode+1
dentry缓存
struct dentry+1
还没有真正的文件产生
写入文件
被写入page
页缓存
page被刷新到磁盘
关闭文件
close(fd);
打开再欣赏一下
int fd = open(\"/mnt/usb/sda1.txt\
fd==>file==>path==>dentry==>inode==>stat
fd==>file==>address_space==>page==>memcpy
二
文件系统注册
vfat文件系统注册
module_init(init_vfat_fs)
static int __init init_vfat_fs(void){\treturn register_filesystem(&vfat_fs_type);}
fat module注册
module_init(init_fat_fs)
init_fat_fs
fat_init_inodecache
文件系统全局注册链表
struct file_system_type *file_systems
struct file_system_type * next
数据结构
进程上下文
struct task_struct
实例变量
current
成员
struct files_struct *files
struct fs_struct *fs
struct fs_struct
struct path root
struct path pwd
struct files_struct
unsigned int next_fd
struct fdtable __rcu *fdt
struct fdtable fdtab
struct file __rcu **fd;
struct file __rcu * fd_array[NR_OPEN_DEFAULT]
以int fd为下标
struct file
struct inode\t\t*f_inode
struct file_operations\t*f_op
struct address_space\t*f_mapping
struct path\t\tf_path
struct path
struct dentry *dentry;
内存管理
struct address_space
struct inode\t\t*host
当page是inode的page时,这个host就是inode,其他情况这里不讨论
struct address_space_operations *a_ops
struct radix_tree_root\tpage_tree
一个文件的所有page
磁盘映射
struct inode
struct super_block\t*i_sb
struct address_space\t*i_mapping
struct inode_operations\t*i_op
struct buffer_head
在内存中对应块设备上的block
常见大小2 sector
1KiB
struct buffer_head *b_this_page
每个page下的buffer构成单循环链表的next指针
struct page *b_page
struct page
struct address_space *mapping
operation
struct file_operations
fat_file_operations
.write_iter\t= generic_file_write_iter
struct address_space_operations
fat_aops
struct inode_operations
vfat_dir_inode_operations
for目录inode
.lookup\t\t= vfat_lookup
若返回值!=NULL,则dentry对应的inode会和dentry连接起来
fat_file_inode_operations
for文件inode
.getattr\t= fat_getattr
lookup
struct super_operations
fat_sops
.write_inode\t= fat_write_inode
其它文件系统相关
struct file_system_type
系统支持的文件系统的链表
struct hlist_head fs_supers
已挂载分区的superblock链表
struct super_block
struct file_system_type *s_type
struct super_operations\t*s_op
struct dentry
struct dentry_operations *d_op
struct inode *d_inode
调用流程
vfat_mount
vfat_fill_super
构造superblock
do_sys_open
int fd = get_unused_fd_flags(flags);
找到一个可能可用的int fd
struct file *filp = path_openat(...);
在路径上建立inode和dentry
fd_array[fd] = f
vfs_write
__vfs_write
new_sync_write
fat_file_operations.write_iter
generic_file_write_iter
__generic_file_write_iter
generic_perform_write
fat_aops.write_begin
iov_iter_copy_from_user_atomic
写入page
fat_aops.write_end
...
mark_inode_dirty(inode);
__block_commit_write
将一个page的脏block标记为脏
初始化bh
struct buffer_head bh = head = page_buffers(page);
循环体
mark_buffer_dirty(bh);
bh = bh->b_this_page;
终止条件
while (bh != head)
balance_dirty_pages_ratelimited
每写入一个page,就会平衡脏页数,脏页太多就会写到块设备一些
balance_dirty_pages
writeback_in_progress(wb)
看看后台写回是否在进行
wb_start_background_writeback(wb)
唤醒后台写回进程
generic_write_sync
vfs_fsync_range
fat_file_operations.fsync
fat_file_fsync
generic_file_fsync
__generic_file_fsync
sync_mapping_buffers
fsync_buffers_list
write_dirty_buffer
submit_bh
submit_bh_wbc
submit_bio
generic_make_request
发送bio请求给block device,会写入块设备
vfs_fstat
vfs_getattr
struct inode *inode = d_backing_inode(path->dentry);
fat_file_inode_operations.getattr
fat_getattr
generic_fillattr
vfs_read
__vfs_read
new_sync_read
fat_file_operations.read_iter
generic_file_read_iter
do_generic_file_read
copy_page_to_iter
机制
文件系统缓存
在内存中建立这些对象时,会在缓存中建立和释放
每个文件系统自己维护
FAT
fat_inode_cachep
kmem_cache_create(\"fat_inode_cache\
dcache_init
dentry_cache
缓存
dentry_hashtable
哈希查找表
buffer缓存/块缓存
buffer_init
bh_cachep
kmem_cache_create(\"buffer_head\
写回
改动page、buffer、inode
mark dirty
inode
__mark_inode_dirty
inode_io_list_move_locked
wb_wakeup_delayed
buffer
mark_buffer_dirty
__set_page_dirty
page
执行写回
wb_workfn
注册
当插入优盘时,会启动backing device初始化
bdi_init
INIT_LIST_HEAD(&bdi->bdi_list);
backing device info链表
cgwb_bdi_init
wb_init
INIT_LIST_HEAD(&wb->work_list);
注册写回work执行函数
流程
pages_written = wb_do_writeback(wb)
处理队列的work
wb_writeback
writeback_sb_inodes
__writeback_single_inode
do_writepages
struct address_space_operations xxx_aops.writepage
fat_writepage
block_write_full_page
__block_write_full_page
write_inode
如果这个inode没有脏页,就更新inode到磁盘
struct super_operations xxx_sops.write_inode
定时唤醒自己
0 条评论
回复 删除
下一页