📄 block_io_subsystem.html
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head> <title></title> <link rel="stylesheet" media="screen" type="text/css" href="./style.css" /> <link rel="stylesheet" media="screen" type="text/css" href="./design.css" /> <link rel="stylesheet" media="print" type="text/css" href="./print.css" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><a href=start.html>start</a></br><div class="toc"><div class="tocheader toctoggle" id="toc__header">Table of Contents</div><div id="toc__inside"><ul class="toc"><li class="clear"><ul class="toc"><li class="level2"><div class="li"><span class="li"><a href="#kernel_2.6_device_drivers_block_i_o_structure" class="toc">Kernel 2.6 Device Drivers, Block I/O structure</a></span></div><ul class="toc"><li class="level3"><div class="li"><span class="li"><a href="#key_elements_of_the_bio_structure" class="toc">Key elements of the bio structure</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#the_bio_vec_structure" class="toc">The BIO Vec Structure</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#bio_references" class="toc">BIO References</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#bio_example_use" class="toc">BIO Example Use</a></span></div></li></ul></li></ul></li></ul></div></div><h2><a name="kernel_2.6_device_drivers_block_i_o_structure" id="kernel_2.6_device_drivers_block_i_o_structure">Kernel 2.6 Device Drivers, Block I/O structure</a></h2><div class="level2"><p> The BIO structure provides a way to handle the different data delivery mechanisms required for some block driver I/O systems.</p><p>The BIO structure encapsulates the data structures to be written to or read from the device and the device specific access routines. Buffered IO requests to block devices use a generic <strong>request</strong> structure. Under 2.4 kernels this used a statically defined <strong>buffer head</strong> structure to define the data to be transferred.</p><p>In the 2.6 Driver model the <strong>buffer head</strong> structure has now been replaced by the <strong>optional</strong> BIO structure to allow more flexibility in defining the data and any transfer characteristics to the I/O device.</p></div><!-- SECTION [1-720] --><h3><a name="key_elements_of_the_bio_structure" id="key_elements_of_the_bio_structure">Key elements of the bio structure</a></h3><div class="level3"><p>This is the main unit of I/O for the block layer and lower layers (ie drivers and stacking drivers)</p><pre class="code c"> from linux/include/bio.<span class="me1">h</span> <span class="kw4">struct</span> bio <span class="br0">{</span> sector_t bi_sector; <span class="kw4">struct</span> bio *bi_next; <span class="coMULTI">/* request queue link */</span> <span class="kw4">struct</span> block_device *bi_bdev; <span class="kw4">unsigned</span> <span class="kw4">long</span> bi_flags; <span class="coMULTI">/* status, command, etc */</span> <span class="kw4">unsigned</span> <span class="kw4">long</span> bi_rw; <span class="coMULTI">/* bottom bits READ/WRITE, * top bits priority */</span> <span class="kw4">unsigned</span> <span class="kw4">short</span> bi_vcnt; <span class="coMULTI">/* how many bio_vec's */</span> <span class="kw4">unsigned</span> <span class="kw4">short</span> bi_idx; <span class="coMULTI">/* current index into bvl_vec */</span> <span class="coMULTI">/* Number of segments in this BIO after * physical address coalescing is performed. */</span> <span class="kw4">unsigned</span> <span class="kw4">short</span> bi_phys_segments; <span class="coMULTI">/* Number of segments after physical and DMA remapping * hardware coalescing is performed. */</span> <span class="kw4">unsigned</span> <span class="kw4">short</span> bi_hw_segments; <span class="kw4">unsigned</span> <span class="kw4">int</span> bi_size; <span class="coMULTI">/* residual I/O count */</span> <span class="kw4">unsigned</span> <span class="kw4">int</span> bi_max_vecs; <span class="coMULTI">/* max bvl_vecs we can hold */</span> <span class="kw4">struct</span> bio_vec *bi_io_vec; <span class="coMULTI">/* the actual vec list */</span> bio_end_io_t *bi_end_io; atomic_t bi_cnt; <span class="coMULTI">/* pin count */</span> <span class="kw4">void</span> *bi_private; bio_destructor_t *bi_destructor; <span class="coMULTI">/* destructor */</span> <span class="br0">}</span>;</pre></div><!-- SECTION [721-2277] --><h3><a name="the_bio_vec_structure" id="the_bio_vec_structure">The BIO Vec Structure</a></h3><div class="level3"><p>This is a list of data pages that are to be read from or written to the device.</p><p>A BIO service will process each page in the list according to the specific requirements of the device.</p><pre class="code c"> from linux/include/bio.<span class="me1">h</span> <span class="kw4">struct</span> bio_vec <span class="br0">{</span> <span class="kw4">struct</span> page *bv_page; <span class="kw4">unsigned</span> <span class="kw4">int</span> bv_len; <span class="kw4">unsigned</span> <span class="kw4">int</span> bv_offset; <span class="br0">}</span>;</pre></div><!-- SECTION [2278-2674] --><h3><a name="bio_references" id="bio_references">BIO References</a></h3><div class="level3"><p> Look in the following files for more details</p><pre class="code"> linux/include/bio.h Documentation/block/biodoc.txt</pre></div><!-- SECTION [2675-2827] --><h3><a name="bio_example_use" id="bio_example_use">BIO Example Use</a></h3><div class="level3"><p>This outline example is taken from the MTD flash driver. There are some special requirements for this driver due to the nature of flash devices.</p><p>Refer to the code in <strong>drivers/mtd/mtdblock.c</strong> driver for more details.</p><p>Setting up a list of BIO’s for data output </p><ul><li class="level1"><div class="li"> If the data starts in the middle of a block then read the old data and</div></li></ul><p>overwrite the end of the block with the new data.</p><ul><li class="level1"><div class="li"> If the data starts on a page boundary and fills the page then grab a page</div></li></ul><p>from the page cache</p><ul><li class="level1"><div class="li"> If the data starts on a page boundary and does not fill the page then</div></li></ul><p>read the old data and overwrite the start of the block with the new data.</p><ul><li class="level1"><div class="li"> grab a page</div></li></ul><p>As each page is created with the correct data it is added to the list of pages to be processed by the BIO.</p><pre class="code"> bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt);[...] bio_add_page(bio, page, PAGE_SIZE, 0);</pre><p>The data is written to the device using the submit_bio</p><pre class="code"> (in ll_rw_blk.c) function</pre><pre class="code c"> <span class="kw4">struct</span> completion event; init_completion<span class="br0">(</span>&event<span class="br0">)</span>; bio->bi_private = &event; bio->bi_end_io = bi_write_complete; submit_bio<span class="br0">(</span>WRITE_SYNC, bio<span class="br0">)</span>; wait_for_completion<span class="br0">(</span>&event<span class="br0">)</span>; <span class="br0">(</span> see bio_endio in bio.<span class="me1">c</span> <span class="br0">)</span> </pre><p> This in turn will call: </p><pre class="code c"> generic_make_request<span class="br0">(</span>bio<span class="br0">)</span>; <span class="co1">// function</span> <span class="br0">(</span> ll_rw_blk.<span class="me1">c</span> <span class="br0">)</span> </pre><p>This in turn will call the <strong>make_request_fn</strong> for the Device I/O Queue.</p><p> </p><pre class="code c"> <span class="kw4">int</span> ret; request_queue_t *q <span class="co1">// this gets the gendisk queue</span> q = bdev_get_queue<span class="br0">(</span>bio->bi_bdev<span class="br0">)</span>; <span class="br0">(</span> this is returns bdev->bd_disk->queue <span class="br0">)</span> <span class="kw1">do</span> <span class="br0">{</span> ret = q->make_request_fn<span class="br0">(</span>q, bio<span class="br0">)</span>; <span class="br0">(</span> see ll_rw_blk.<span class="me1">c</span> <span class="br0">)</span> <span class="br0">}</span> <span class="kw1">while</span><span class="br0">(</span>ret<span class="br0">)</span>; </pre></div><!-- SECTION [2828-] --></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -