专利名称:一种绕过Bio层访问磁盘驱动的存储接口的方法
技术领域:
本发明涉及计算机数据存储技术,特别涉及一种绕过Bio层访问磁盘驱动的存储 接口的方法。
背景技术:
目前常用的磁盘设备的输入输出(IO)接口包括小型计算机系统接口(SCSI, Small Computer System Interface),串行连接 SCSI 接口(SAS,SerialAttached SCSI)和 光纤通道(FC,Fiber Channel)。各种基于Linux操作系统的磁盘接口驱动程序都须要在 Linux块设备层进行注册,通过特定的IO接口来构造和提交IO请求。Linux 2. 6内核正式引入了 Bio结构,它是大多数块设备向底层提交IO请求的一 种通用描述。通过Bio层来访问磁盘设备的处理流程如图1所示,包括如下步骤步骤101 将应用程序提交的IO请求的信息提取出来,构造成Bio结构,Bio结构 中记录了 IO请求的访问地址和读写数据的长度。一般情况下,在Bio结构中,数据会以分 片的形式链接起来,其链首地址记录在Bio结构中。步骤102 将构造好的Bio结构提交到Linux通用块设备层,根据Bio结构中的请 求信息,构造通用的块设备IO请求,将这些块设备IO请求放到所访问磁盘的请求队列上。步骤103 =Linux块设备层通过一系列队列处理函数,将块设备IO请求通过固定的 IO接口提交给底层驱动程序。由于基于Linux操作系统的底层驱动都会向Linux通用块设 备层注册自己的接口,底层驱动的IO处理函数和块设备层固定的IO接口相衔接,从而顺利 接管IO请求的处理。步骤104 底层驱动程序将IO请求的信息重新封装成与接口协议相关的协议数据 单元,并向主机适配器(HBA)提交,最终到达磁盘。在上面所述的流程中,Bio层会使用多种调度算法对IO进行合并和排序。Linux 操作系统以页为单位来管理内存,bio结构也是在此基础之上,以页为单位来组织数据,IO 请求所需要的读取或者写入的数据,通常是以页为单位分片链接起来,Bio结构通常只记录 链首地址。Bio结构的引入,能够统一不同块设备的IO接口,正因为要兼顾多种块设备的兼 容性要求,通过Bio层的IO请求有着比较复杂的处理流程,给特定情况下的应用带来局限 性,同时也在一定程度上带来了性能的损失。
发明内容
本发明提供了一种绕过Bio层访问磁盘驱动的存储接口的方法,避免了 Bio层的 复杂处理流程,提高IO访问效率。本发明实施例提出的绕过Bio层访问磁盘驱动的存储接口的方法包括如下步骤建立设备模型,每个磁盘设备对应一个磁盘设备对象,并将应用程序发起的IO请 求封装成IO请求对象;
为每个磁盘设备对象建立两级队列等待队列和处理队列;等待队列用于依次接 收IO请求对象,在处理队列有空位的情况下,将IO请求对象从等待队列中转移到处理队 列;创建扫描线程,用于扫描所有磁盘设备对象的等待队列,若等待队列上有IO请求 对象,从处理队列中取出IO请求对象向底层提交,IO处理完毕后将该IO请求对象从处理 队列中移除。较佳地,所述将应用程序发起的IO请求封装成IO请求对象包括使用专用数据包记录IO请求的关键信息;利用所述专用数据包的信息,构造并填 充scsi_cmd结构;所述从处理队列中取出IO请求对象向底层提交包括使用所述SCSi_Cmd结构作 为传入参数,通过下层指定接口注册函数提交IO请求。较佳地,所述关键信息包括SCSI命令描述块,IO请求的数据传输方向,读写请求 的数据传输的DMA地址,数据传输长度和数据请求完成状态。较佳地,该方法进一步包括在底层驱动中增加一条分支路径接口注册函数;所述SCSi_Cmd结构记录动态内存存取DMA地址,页地址设为空;所述使用所述SCSi_Cmd结构作为传入参数,通过下层指定接口注册函数提交IO 请求包括判断所述SCSi_Cmd结构的页地址是否为空,若是,通过所述分支路径接口注册 函数提交IO请求。较佳地,所述从处理队列中取出IO请求对象向底层提交,IO处理完毕后将该IO请 求对象从处理队列中移除包括将中断完成函数指针记录到SCSi_Cmd结构中;比较返回命令的命令序列号,来判断该返回命令是否属于超时的无效返回,若是, 则结束处理;否则,记录SCSI命令完成状态信息,通过所述专用数据数据包向上层模块返 回,并且释放scsi_cmd命令资源;scsi_cmd的result字段记录了 IO完成的状态,根据IO完成的状态,调用相应的 函数来向上层返回请求处理结果;如果所述处理结果为命令正确完成,清除处理队列上的相应IO请求对象,从等待 队列中继续取新的IO请求对象转移到处理队列上;如果命令未能正确完成,将根据记录的 SCSI命令完成状态信息判断出错原因,进行命令重试。从以上技术方案可以看出,将应用程序发出的IO请求直接通过底层驱动的注册 接口向设备提交,避免了 Bio结构的使用也绕开了页分配和页地址的转换过程,从而绕开 了 Bio层的复杂处理流程,极大的提高了 IO效率。本发明提供的这种绕开Bio层访问磁盘 驱动的存储接口方法,使用精简的IO路径和资源分配方式,一方面缩短了 IO请求的处理时 间,另一方面,摆脱了 Linux操作系统的限制,通过更加灵活简洁的方式,设计并实现了通 用性和移植性更强的新型IO接口。
图1为本发明实施例提出的建立通用设备模型和请求队列的流程示意图;图2为等待队列和处理队列的关系示意 图3为本发明实施例提出的绕开Bio层进行IO处理的流程示意图。
具体实施例方式
在现有技术中,通过Linux系统Bio层的IO访问都须要将请求挂到块设备请求队 列上,在Linux系统中这些请求队列是所有块设备通用的,有着一系列既定的处理方法的 集合。但是在很多应用中,需要自行设计请求队列并以不同的方式对其进行队列管理,绕开 Bio层,针对不同的队列管理方式,自行构造请求队列,有利于解除这种局限性。为使本发明方案的技术特征及所达到的技术效果更加清楚,以下参照附图详细叙 述本发明的具体实施方式
。为了实现本发明的方法,需要先建立设备模型和请求队列,由于绕开Bio进行请 求,队列的管理流程更为简洁,避开了 Linux块设备层复杂的队列处理方式。图1为本发明实施例提出的建立通用设备模型和请求队列的流程示意图。该流程 中,定义两种新的数据结构分别称为磁盘设备对象(kdev,kaos_device)和IO请求对象 Gibuf,kaoS_buf),磁盘设备对象是每个磁盘设备的抽象,记录了该设备必要的信息;IO请 求对象则是对IO请求的抽象,记录了每个IO请求的必要信息。该流程包括如下步骤步骤101 建立设备模型,每个磁盘设备对应一个磁盘设备对象,并将应用程序发 起的IO请求封装成IO请求对象;步骤102 为每个磁盘设备对象建立两级队列等待队列和处理队列;等待队列用 于依次接收IO请求对象,在处理队列有空位的情况下,将IO请求对象从等待队列中转移到 处理队列。处理队列相当于是缓存池,用来从等待队列中取出IO请求对象缓存起来并向下 层接口提交。步骤103 创建扫描线程,用于扫描所有磁盘设备对象的等待队列,只要等待队列 上有IO请求对象,就从处理队列中取出IO请求对象向底层提交,IO处理完毕后将该IO请 求对象从处理队列中移除。图2为等待队列和处理队列的关系示意图。如图2所示,由于等待队列最多可以 接收8个IO请求对象,这样一来起到了流量限制的作用,当对处理队列中的IO请求对象完 成IO处理,并删除该IO请求对象后,才可以继续缓存等待队列的新的IO请求对象。图3是本发明实施例提出的绕开Bio层进行IO处理的流程示意图,包括如下步 骤步骤301 分配 sisi_cmd 结构。SCSi_Cmd结构是底层驱动和Linux块设备层衔接进行IO传输的信息载体,记录了 IO请求的相关信息。所述相关信息包括但不限于SCSI命令描述块(CDB),IO请求的数据 传输方向,读写请求的数据传输的DMA地址,数据传输长度,数据请求完成状态等。步骤302 根据IO请求对象中的IO信息,填充SCSi_Cmd结构。scsi_cmd结构中用来进行数据传输的结构称为聚散链表(sg list),由于绕开了 Bio层并且避免了页分配,在sg list的链表项中只需要记录动态内存存取(DMA)地址,页 地址设为空。步骤303 将准备好的SCSi_Cmd结构作为传入参数,提交到队列命令 (queuecommand)注册接口处。这里的queuecommand是一个函数指针,底层驱动会向这个指针注册各自的IO处理函数。步骤304 底层驱动的IO处理函数接管IO处理。步骤305 :10处理完毕后,调用自行设计的中断完成函数SCSi_d0ne来向上层模块 传递IO完成信息,并释放相关资源。步骤306 判断IO是否正确完成,若是,执行步骤307,否则执行步骤308。步骤307从处理队列中移除kbuf,处理下一个kbuf,返回步骤301 ;步骤308 返回错误信息给上层模块,由上层模块决定是进行IO重试还是放弃。自此,绕开Bio层的IO处理方式通过上下层明确的接口,顺利实现了精简路径的 IO处理。本发明提出的技术方案由于在关键的IO路径上绕开了 Linux既有的处理方式,在 数据请求封装,提交,管理等方面都使用了自行设计的处理模式,可以不受Linux操作系统 的限制,方便移植到各自操作系统中。本发明提供的方法,使得IO处理流程大大简化,应用 程序提交的IO经过一次封装,就可以直接提交到底层驱动的接口处,IO性能有很大提升。具体地,本发明的技术特点如下1、在Linux操作系统下,基于Bio层的IO处理有着比较复杂的流程,本发明的目 的在于绕开Bio层的复杂流程,利用自行设计的IO存储接口,精简处理过程,实现IO效率 提升;2、自行设计设备模型和队列管理方式,避免使用了 Linux块设备层队列处理的复 杂调度算法;3、重新封装IO信息,避免内存页的使用,直接通过DMA方式传输,避免了页地址向 DMA地址的转换。4、少量修改底层驱动,建立分支路径,一方面保证操作系统自身的基于Bio层的 IO操作能正常进行,一方面也能保证通过本发明中绕开Bio的存储接口的IO请求能正确提 交。极大提高了该存储接口的通用性。5、自行设计IO完成函数,顺利将改存储接口和上层模块连接,可以方便的一直到 各种应用中。以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精 神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本发明保护的范围之内。
权利要求
1.一种绕过BiO层访问磁盘驱动的存储接口的方法,其特征在于,包括如下步骤建立设备模型,每个磁盘设备对应一个磁盘设备对象,并将应用程序发起的IO请求封 装成IO请求对象;为每个磁盘设备对象建立两级队列等待队列和处理队列;等待队列用于依次接收IO 请求对象,在处理队列有空位的情况下,将IO请求对象从等待队列中转移到处理队列;创建扫描线程,用于扫描所有磁盘设备对象的等待队列,若等待队列上有IO请求对 象,从处理队列中取出IO请求对象向底层提交,IO处理完毕后将该IO请求对象从处理队 列中移除。
2.根据权利要求1所述的方法,其特征在于,所述将应用程序发起的IO请求封装成IO 请求对象包括使用专用数据包记录IO请求的关键信息;利用所述专用数据包的信息,构造并填充 scsi_cmd 结构;所述从处理队列中取出IO请求对象向底层提交包括使用所述scsi_cmd结构作为传 入参数,通过下层指定接口注册函数提交IO请求。
3.根据权利要求2所述的方法,其特征在于,所述关键信息包括SCSI命令描述块,IO 请求的数据传输方向,读写请求的数据传输的DMA地址,数据传输长度和数据请求完成状 态。
4.根据权利要求2所述的方法,其特征在于,该方法进一步包括在底层驱动中增加一 条分支路径接口注册函数;所述scsi_cmd结构记录动态内存存取DMA地址,页地址设为空;所述使用所述SCSi_Cmd结构作为传入参数,通过下层指定接口注册函数提交IO请求 包括判断所述scsi_cmd结构的页地址是否为空,若是,通过所述分支路径接口注册函数 提交IO请求。
5.根据权利要求2、3或4所述的方法,其特征在于,所述从处理队列中取出IO请求对 象向底层提交,IO处理完毕后将该IO请求对象从处理队列中移除包括将中断完成函数指针记录到scsi_cmd结构中;比较返回命令的命令序列号,来判断该返回命令是否属于超时的无效返回,若是,则结 束处理;否则,记录SCSI命令完成状态信息,通过所述专用数据数据包向上层模块返回,并 且释放scsi_cmd命令资源;scsi_cmd的result字段记录了 IO完成的状态,根据IO完成的状态,调用相应的函数 来向上层返回请求处理结果;如果所述处理结果为命令正确完成,清除处理队列上的相应IO请求对象,从等待队列 中继续取新的IO请求对象转移到处理队列上;如果命令未能正确完成,将根据记录的SCSI 命令完成状态信息判断出错原因,进行命令重试。
全文摘要
本发明提供了一种绕过Bio层访问磁盘驱动的存储接口的方法,包括如下步骤建立设备模型,每个磁盘设备对应一个磁盘设备对象,并将应用程序发起的IO请求封装成IO请求对象;为每个磁盘设备对象建立两级队列等待队列和处理队列;等待队列用于依次接收IO请求对象,在处理队列有空位的情况下,将IO请求对象从等待队列中转移到处理队列;创建扫描线程,用于扫描所有磁盘设备对象的等待队列,若等待队列上有IO请求对象,从处理队列中取出IO请求对象向底层提交,IO处理完毕后将该IO请求对象从处理队列中移除。
文档编号G06F13/16GK102073605SQ20101062182
公开日2011年5月25日 申请日期2010年12月27日 优先权日2010年12月27日
发明者饶国林 申请人:云海创想信息技术(北京)有限公司, 深圳市创新科信息技术有限公司