- 论坛徽章:
- 0
|
回复 #9 Charlemagne 的帖子
不错不错,概念越讨论越清楚。
>> 裸设备raw lv即是直接与driver打交道
正确。
>> 单次I/O必须是512-byte 对齐的,所以传输大小至少是512字节的整数倍。
对于 LVM 来讲,这个限制是由于 LVM 在底层统一采用了 Block I/O 的读写方式。换句话说,不管你是通过字符设备还是块设备访问 LVM,最终都会以 Block I/O 的方式传递数据,而这种方式的确要求I/O到达LVM 时它的大小为 block size (512字节) 的整数倍。
但通过字符设备和块设备访问 LVM的本质区别在于:
1. 块设备虽然表面上可以接受‘不定长’的‘逻辑’请求(例如 dd bs=1),但它必须经过块缓存(block buffer)模块才能达到LVM I/O 模块,而块缓存I/O必然是以“一个” 512字节块进行的(不能大,也不能小)。所以,在LVM这一层发生的还是512字节的读写。当你写1字节的时候,块缓存模块必须先把当前的512字节从LV里读出来,更新一个字节以后再把整个512字节写回去。如果你读写1KB,块缓存必须把它分成两个512字节的请求发个LVM。所以在LVM层实际发生了两个512字节的读写。
2. 字符设备从定义上支持不定长存取。但由于 LVM 底层实现采用了block I/O 的方式,I/O 必须以 512字节 的整数倍进行,并且单个I/O 大小不能大于 LTG (缺省128KB)。由于不经过缓存模块的‘打包’,1字节的请求不能在到达LVM底层时变成512字节,所以LVM返回 EINVAL 的错。但4KB, 8KB 直到 128KB 的请求都会直接处理,不会被分拆成 512字节,这是和块设备的存取方式的本质区别。
>> 反而块设备是利用了系统缓存,可以支持变长I/O的,这正是使用额外缓存带来的灵活度。
如上说述,这个的“灵活度”可以说是一种假象。实际上字符设备才更灵活。
>> 块设备只是一个逻辑上的概念
块设备决定了它的I/O会被块缓存模块聚合或分拆成 512字节,这个逻辑概念对实际应用的影响是实实在在的。
个人认为,在6楼的描述,除了没有指出LVM Block I/O 这个 512字节整数倍的限制外,基本都是正确的。
特别是关于字符及块设备的定义,以及它们对应用的影响。
9 楼以为如何?欢迎继续讨论。 |
|