我正在研究linux内核。目前仅适用于 v3.10.61,这只是概念验证。
我需要向硬件传递一些关于特定 WRITE\READ 操作中的数据类型的提示。例如读取 inode 位图或写入日志块或写入用户数据或其他...
我假设在驾驶员级别我可以bio struct
从到达request_queue struct
。
- 我用这个命令创建了 FS:
mkfs.ext4 -b 4096 -E lazy_itable_init=0,lazy_journal_init=0 -m 0 /dev/vda
- 我已经使用以下命令安装了它:
mount -o rw,nosuid,nodev,discard,noauto_da_alloc,data=ordered /dev/vda /mnt
- 添加断点
virtio_blk.c:377
并将跳过与日志相关的写入 - 执行这个dd命令:
dd if=/dev/urandom of=/mnt/foo2 bs=764 count=34
- 等待断点命中并将分析回写子系统下的回溯。
这是回溯:
#0 virtblk_request (q=0x87ab8000) at drivers/block/virtio_blk.c:377
#1 0x801c0b4c in __blk_run_queue_uncond (q=<optimized out>) at block/blk-core.c:312
#2 __blk_run_queue (q=0x87ab8000) at block/blk-core.c:329
#3 0x801c0c94 in queue_unplugged (q=0x87ab8000, depth=<optimized out>, from_schedule=<optimized out>) at block/blk-core.c:2920
#4 0x801c3a98 in blk_flush_plug_list (plug=<optimized out>, from_schedule=false) at block/blk-core.c:3030
#5 0x801c3d9c in blk_finish_plug (plug=0x8785fd8c) at block/blk-core.c:3037
#6 0x80091644 in generic_writepages (mapping=<optimized out>, wbc=0x8785fde0) at mm/page-writeback.c:1910
#7 0x80092a88 in do_writepages (mapping=<optimized out>, wbc=<optimized out>) at mm/page-writeback.c:1923
#8 0x800e7084 in __writeback_single_inode (inode=0x8740c290, wbc=0x8785fde0) at fs/fs-writeback.c:454
#9 0x800e7360 in writeback_sb_inodes (sb=0x87811000, wb=0x87ab81b0, work=0x8785fea4) at fs/fs-writeback.c:678
#10 0x800e757c in __writeback_inodes_wb (wb=0x1 <__vectors_start>, work=0x3ff) at fs/fs-writeback.c:723
#11 0x800e7760 in wb_writeback (wb=0x87ab81b0, work=0x8785fea4) at fs/fs-writeback.c:854
#12 0x800e838c in wb_check_old_data_flush (wb=<optimized out>) at fs/fs-writeback.c:969
#13 wb_do_writeback (wb=0x87ab81b0, force_wait=0) at fs/fs-writeback.c:1010
#14 0x800e848c in bdi_writeback_workfn (work=0x87ab81bc) at fs/fs-writeback.c:1040
#15 0x80039d34 in process_one_work (worker=0x87816180, work=0x87ab81bc) at kernel/workqueue.c:2189
#16 0x8003a40c in worker_thread (__worker=0x1 <__vectors_start>) at kernel/workqueue.c:2313
#17 0x8003f714 in kthread (_create=0x87845e20) at kernel/kthread.c:200
#18 0x8000dfb8 in ret_from_fork () at arch/arm/kernel/entry-common.S:91
好的,我们开始...在第 8 帧,我们还没有优化 inode 变量以进行检查:
p (*inode)->i_ino
$7 = 0
谁能解释一下这个 inode 是什么意思?在哪里可以找到有关此类 inode 的信息?如何跟踪写回操作的索引节点号?
答案1
免责声明:我还没有尝试过任何这些功能,并且正在处理文档和评论。我的观察可能是错误的!
我能看到的唯一使用i_ino
其中值的函数fs/writeback.c
是内部函数block_dump___mark_inode_dirty
,如果索引节点已被散列(并且尚未标记),它将标记为脏,并设置时间戳(用于将来的写回操作)。当前的索引节点列表要写回的似乎可以作为struct bdi_writeback *wb
给予 的列表 () 来使用wb_writeback()
。
正如您data=ordered
在挂载选项中使用的那样,我不认为会发生任何数据写回,因此不应将索引节点视为“脏”。根据ext4 文档:
data=ordered
(*)在将其元数据提交到日志之前,所有数据都将直接强制输出到主文件系统。
稍后描述 ext4 中写回的工作原理:
数据模式
- 回写模式
在
data=writeback
模式下,ext4 根本不记录数据。此模式提供与 XFS、JFS 和 ReiserFS 的默认模式类似的日志记录级别 - 元数据日志记录。崩溃+恢复可能会导致在崩溃前不久写入的文件中出现不正确的数据。此模式通常会提供最佳的 ext4 性能。
- 有序模式
在
data=ordered
模式下,ext4 仅正式记录元数据,但它在逻辑上将与数据更改相关的元数据信息与数据块分组到称为事务的单个单元中。当需要将新元数据写入磁盘时,首先写入关联的数据块。一般来说,此模式的执行速度比写回稍慢,但比日志模式快得多。
如果您想要跟踪 ext4 分区上的事件,您可能有兴趣了解 ext4-JBD2 接口如何工作fs/ext4/ext4_jbd2.c
以及include/trace/events/ext4.h
.