分类: LINUX
2011-11-05 22:05:12
传统的机械硬盘一般为3.5英寸硬盘,并由多个圆形蝶片组成,每个蝶片拥有独立的机械臂和磁头,每个堞片的圆形平面被划分了不同的同心圆,每一个同心圆称为一个磁道,位于最外面的道的周长最长称为外道,最里面的道称为内道,通常硬盘厂商会将圆形蝶片最靠里面的一些内道(速度较慢,影响性能)封装起来不用;道又被划分成不同的块单元称为扇区,每个道的周长不同,现代硬盘不同长度的道划分出来的扇区数也是不相同的,而磁头不工作的时候一般位于内道,如果追求响应时间,则数据可存储在硬盘的内道,如果追求大的吞吐量,则数据应存储在硬盘的外道;
机械硬盘的访问时间包括:寻道时间,旋转时间和传输时间;寻道时间指的是磁头在不同的磁道之间移动,通常耗时在ms级;旋转时间指的是磁头通过机械臂在本磁道移动定位至当前I/O请求的起始位置所花的时间,通常为us级;传输时间即进行实际数据读写的时间,通常为us级;而我们常说的硬盘转速实际上只直接影响旋转时间和传输时间。
SATA硬盘实现的是串行ATA协议,ATA下盘命令中记录有LBA(Logic Block Address)起始地址和扇区数;LBA地址实际上是一个ATA协议逻辑地址,硬盘的固件会解析收到的ATA命令,并将要访问的LBA地址映射至某个磁道中的某个物理块即扇区。操作系统暂可认为LBA地址就是硬盘的物理地址。
2 扇区、文件系统块、文件块和段
扇区、文件系统块、文件块和段的概念贯穿了整个块设备,需明确这些概念的真正含义。
扇区:硬盘的基本访问单位, SATA硬盘一般为512B;
文件系统块:例如用mkfs.ext2命令格式化硬盘时,可以选择文件系统的块大小,即将硬盘的扇区抽象成更大的逻辑单位,以提高读写性能;如1024B;此值必须为扇区的整数倍,且不能超过页面大小,且为2的幂;例如,4KB页面和512B扇区允许的块大小:512B, 1024B, 2048B, 4096B四个;文件系统块的大小即buffer_head结构代表的空间大小;属于同一个块的所有扇区在硬盘介质中一定是连续存储的(所谓连续存储即对应ATA命令中的LBA地址是连续的);一般来讲,如果存在很多小文件,则选用较小的块大小来节省空间,反之选用较大的块来提高性能;ULK3中又称作逻辑块;buffer_head中记录的b_blocknr便是此类块;
另外,直接针对设备文件进行读写时,内核将使用默认为4096B大小的块;
文件块:大小定义和文件系统块一样;只是相对于文件的一个偏移逻辑块,需要通过具体文件系统中的此文件对应的inode所记录的间接块信息,换算成对应的文件系统块;此做法是为了将一个文件的内容存于硬盘的不同位置,以提高访问速度;即一个文件的内容在硬盘是一般是不连续的;EXT2中,ext2_get_block()完成文件块到文件系统块的映射;
段:主要为了做scatter/gather DMA操作使用,同一个物理页面中的在硬盘存储介质上连续的多个块组成一个段;
物理内存地址连续且对应LBA地址也是连续的几个段会在块设备层被内核合并成一个大段称为物理段;
有些高级的DMA硬件设备拥有一个IO-MMU硬件单元,类似于内存页面的MMU,可以将物理内存地址不连续但LBA地址是连续的几个段,映射成DMA硬件所看到的总线地址连续的大段,这类大段称为硬件段;
通常遇到的都是物理段,本文件以物理段讲述;物理段是scatter/gather DMA操作中的基本单位,一次scatter/gather DMA操作中一般会包含几个物理段,几个物理段在一次DMA下盘ATA命令中就可以完成相应数据的传输。
由上可知,块通常包括多个扇区,段通常包括多个块,物理段通常包括多个段;段在内核中由结构struct bio_vec来描述,多个段的信息存放于struct bio结构中的bi_io_vec指针数组中,段数组在后续的块设备处理流程中会被合并成物理段,段结构定义如下:
struct bio_vec {
struct page *bv_page; // 段所在的物理页面结构,即bh->b_page
unsigned int bv_len; // 段的字节数,即bh->b_size
unsigned int bv_offset; // 段在bv_page页面中的偏移,即bh->b_data
};
另附一个ULK3中关于这几个概念的截图:
(段:segment; 物理段:physical segment; 硬件段:hardware segment)