很久以前 , 天还是蓝的 , 水也是绿的 , 庄稼是长在地里的 , 猪肉是可以放心吃的 , 耗子还是怕猫的 , 法庭是讲理的 , 上床是先结婚的 , 理发店是只管理发的 , 药是可以治病的 , 医生是救死扶伤的 , 拍电影是不需要陪导演睡觉的 , 照相是要穿衣服的 , 欠钱是要还的 , 孩子的爸爸是明确的 , 学校是不图挣钱的 , 白痴是不能当教授的 , 卖狗肉是不能挂羊头的 , 男就是男的女的就是女的 . 那时候 Block 层还是一部分附属于 drivers/ 目录下一部分附属于 fs/ 目录下的 .
但后来一切都变了 .2005 年秋天 ,Block 层搬出了 drivers/ 和 fs/ 目录 , 从 2.6.15 的内核开始 , 顶层目录下面有了一个叫做 block 的目录 , 内核目录结构变成了现在这个样子 :
localhost-1:/usr/src/linux-2.6.22.1 # ls
COPYING Documentation MAINTAINERS README arch crypto fs init kernel mm scripts sound CREDITS Kbuild Makefile REPORTING-BUGS block drivers include ipc lib net security usr
进入 block 目录 , 用旁光看一下 :
localhost:/usr/src/linux-2.6.22.1/block # ls
Kconfig Makefile blktrace.c deadline-iosched.c genhd.c ll_rw_blk.c scsi_ioctl.c
Kconfig.iosched as-iosched.c cfq-iosched.c elevator.c ioctl.c noop-iosched.c
用 wc 命令统计一下 :
localhost:/usr/src/linux-2.6.22.1/block # wc -l *
54 Kconfig
73 Kconfig.iosched
12 Makefile
1485 as-iosched.c
562 blktrace.c
2254 cfq-iosched.c
485 deadline-iosched.c
1160 elevator.c
831 genhd.c
304 ioctl.c
4117 ll_rw_blk.c
118 noop-iosched.c
654 scsi_ioctl.c
12109 total
一万二千多行 . 还好我们不用每个文件都去看 .
老规矩 , 先看一下 Makefile 和 Kconfig,
localhost:/usr/src/linux-2.6.22.1/block # cat Makefile
#
# Makefile for the kernel block layer
#
obj-$(CONFIG_BLOCK) := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
obj-$(CONFIG_IOSCHED_AS) += as-iosched.o
obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o
很显然 , 经常在地铁站里吆喝着说刘德华死了的那位卖报的哥们儿也知道 , 这里最重要的一个选项是 CONFIG_BLOCK, 而剩下几个我们看一下 Kconfig 以及 Kconfig.iosched 就知道 , 是和 IO 调度算法有关的 , 并不一定每种算法都要清楚 , 看其中一种就凑合了 .
那么整个 Block 子系统的入口在哪里呢 ? 一路走来的兄弟相信不难找到 , 在 block/genhd.c 中有这么一行 :
363 subsys_initcall(genhd_device_init);
所以很明显 ,genhd_device_init 将为我们掀开故事的大幕 .