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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值