f2fs学习笔记 - 9. f2fs 写文件

1.前言

本文主要介绍f2fs写入流程. 写入流程主要分为meta, data, node的写入,本文主要介绍data的写入流程。

2.总体流程

sys_write
	fdget
	file_pos_read
	vfs_write
	file_pos_write
  1. fdget是从当前进程的文件描述符表获取一个fd;

  2. file_pos_read获取文件描述符当前的读写位置

  3. vfs_write执行文件写入操作

  4. file_pos_write更新文件的写入位置

3.vfs_write

vfs_write
	rw_verify_area
		file->f_op->write (do_sync_write)
			generic_file_aio_write
				__generic_file_aio_write
					generic_segment_checks
						generic_write_checks
						generic_file_direct_write或generic_file_buffered_write
  1. sys_write系统调用会调用到vfs_write,进而调用到file->f_op->write,这个write回调是在创建文件时初始化为inode->i_fops->write, 对于f2fs就是do_sync_write,它会进一步调用generic_file_aio_write->__generic_file_aio_write

  2. __generic_file_aio_write通过generic_segment_checks来检查segment的数目和要写入数据的数目进行必要的检查,最终确定写入文件的位置和数据的数目;之后通过generic_write_checks进一步对写入文件的位置和数目进行检查

3.1 generic_file_direct_write

generic_file_direct_write
	filemap_write_and_wait_range(mapping, pos, pos + write_len - 1)
		do_writepages(mapping, &wbc)
			mapping->a_ops->writepages(mapping, wbc)
				generic_writepages(mapping, wbc)
					write_cache_pages(mapping, wbc, __writepage, mapping)

对于直写的情况将执行generic_file_direct_write,它调用writepages回调,对于f2fs为f2fs_write_data_pages,进而它会执行generic_writepages,对于每一page都将调用 __writepage,实际上调用了mapping->a_ops->writepage(page, wbc)回调,对于f2fs即为f2fs_write_data_page

3.1.1 f2fs_write_data_page

f2fs_write_data_page
	do_write_data_page(page)
		get_dnode_of_data(&dn, page->index, RDONLY_NODE)
		write_data_page(inode, page, &dn,old_blk_addr, &new_blk_addr);
			set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version)
			do_write_page(sbi, page, old_blkaddr,new_blkaddr, &sum, DATA)
				__add_sum_entry(sbi, type, sum, curseg->next_blkoff)
				__refresh_next_blkoff(sbi, curseg)
				refresh_sit_entry(sbi, old_blkaddr, *new_blkaddr)
				submit_write_page(sbi, page, *new_blkaddr, p_type)
					do_submit_bio(sbi, type, false)

get_dnode_of_data:通过page->index查找dnode(直接node)中对应的block地址,保存在dn->data_blkaddr中

write_data_page:old_blk_addr为当前要写入的block的地址,new_blk_addr为下一个要写入的block地址

set_summary:由于要写入数据,需要更新current segment的summary, 此处是构造新的segment summary entry.

do_write_page: 执行page写入操作。
__add_sum_entry:更新current segment中要写入block的summary entry
__refresh_next_blkoff: 更新current sgement的下一个block offset, 根据SSR(thread mode)和LFS模式有所不同;
refresh_sit_entry:
submit_write_page:通过调用do_submit_bio->submit_bio提交给block层

3.2 .generic_file_buffered_write

generic_file_buffered_write
	generic_perform_write(file, &i, pos)
		a_ops->write_begin
		iov_iter_copy_from_user_atomic
		a_ops->write_end
			f2fs_set_data_page_dirty

对于非直写的情况将调用generic_file_buffered_write。它将调用generic_perform_write(file, &i, pos)执行写入操作

f2fs_write_begin:a_ops->write_begin对应f2fs就是f2fs_write_begin。通过f2fs_write_begin确定了要写入的page对应的磁盘block地址。

iov_iter_copy_from_user_atomic:将用户空间数据拷贝到page;

a_ops->write_end->generic_write_end:当用户空间数据拷贝到page后,用作善后处理,标记页面为最新且是脏页,这样在sync时就会将这些页面写入磁盘
f2fs_set_data_page_dirty:在address space 中标记page为dirty

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
f2fs文件系统调用主要涉及以下几个组件和函数: 1. 文件系统类型定义:在f2fs文件系统中,通过定义一个file_system_type结构体来表示文件系统类型。其中包括了文件系统的名称、挂载函数、卸载函数等信息。在f2fs中,文件系统类型定义如下: static struct file_system_type f2fs_fs_type = { .owner = THIS_MODULE, .name = "f2fs", .mount = f2fs_mount, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; 2. 挂载函数:f2fs_mount函数是用来将块设备挂载成f2fs文件系统的函数。它是通过调用mount_bdev函数来实现的。具体的挂载过程包括了填充f2fs super block信息等操作。在f2fs中,挂载函数定义如下: static struct dentry *f2fs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { return mount_bdev(fs_type, flags, dev_name, data, f2fs_fill_super); } 3. 填充super block信息:f2fs_fill_super函数用来填充f2fs文件系统的super block信息。它会读取块设备上的super block数据,并将其解析为内存中的数据结构。在f2fs中,填充super block信息的函数定义如下: static int f2fs_fill_super(struct super_block *sb, void *data, int silent) { // 填充super block信息的具体实现 } 通过以上组件和函数,f2fs文件系统可以被调用和使用。当用户在用户空间执行mount操作时,会回调到文件系统类型中定义的mount函数,即f2fs_mount函数。在f2fs_mount函数中,会调用mount_bdev函数来实现具体的挂载过程,包括填充super block信息等操作。最终,f2fs文件系统就可以被成功挂载和使用。 #### 引用[.reference_title] - *1* [f2fs学习笔记 - 4. f2fs文件系统组件说明](https://blog.csdn.net/jasonactions/article/details/122417105)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [f2fs学习四: f2fs文件系统挂载](https://blog.csdn.net/guozhidixian/article/details/115498708)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值