📄 046_fs_iobuf_c.html
字号:
<html lang="zh-CN" xmlns:gdoc=""> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <style type="text/css">/* default css */table { font-size: 1em; line-height: inherit;}div, address, ol, ul, li, option, select { margin-top: 0px; margin-bottom: 0px;}p { margin: 0px;}body { margin: 0px; padding: 0px; font-family: Verdana, sans-serif; font-size: 10pt; background-color: #ffffff;}h6 { font-size: 10pt }h5 { font-size: 11pt }h4 { font-size: 12pt }h3 { font-size: 13pt }h2 { font-size: 14pt }h1 { font-size: 16pt }blockquote {padding: 10px; border: 1px #DDD dashed }a img {border: 0}div.google_header, div.google_footer { position: relative; margin-top: 1em; margin-bottom: 1em;}/* end default css */ /* default print css */ @media print { body { padding: 0; margin: 0; } div.google_header, div.google_footer { display: block; min-height: 0; border: none; } div.google_header { flow: static(header); } /* used to insert page numbers */ div.google_header::before, div.google_footer::before { position: absolute; top: 0; } div.google_footer { flow: static(footer); } /* always consider this element at the start of the doc */ div#google_footer { flow: static(footer, start); } span.google_pagenumber { content: counter(page); } span.google_pagecount { content: counter(pages); } } @page { @top { content: flow(header); } @bottom { content: flow(footer); } } /* end default print css */ /* custom css *//* end custom css */ /* ui edited css */ body { font-family: Verdana; font-size: 10.0pt; line-height: normal; background-color: #ffffff; } .documentBG { background-color: #ffffff; } /* end ui edited css */</style> </head> <body revision="dcbsxfpf_69dt28tjc6:53"> <div align=center>
<table align=center border=0 cellpadding=0 cellspacing=0 height=5716 width=800>
<tbody>
<tr>
<td height=5716 valign=top width=100%>
<pre>2008-1-3 <br> kiobuf和raw设备的关系比较密切. raw设备十一个字符设备,单仅仅是字符设备而已.读写一个raw设备对应于一个block device.通<br>过raw设备bind的块设备,使用另一种读写方式,没有copy to/form user的过程了,不像设备文件那样(block_dev.c).<br> 其基本思路是把用户传进来的buf,强制调度到memory中,使之在读写的时候不会mm fault,同时收集这些页面的page的指针,并记录到<br>kiobuf中. 然后,为每个page创建一个buffer entry,启动读写过程, 完成之后就可以释放kiobuf并返回了. 不在有copy过程了.<br> <br> 这些代码分布在iobuf.c buffer.c memory.c raw.c之中.但并不难理解.<br>kiobuf本身注释很全面.<br>struct <font color=#000066><b>kiobuf </b></font><br>{<br> int nr_pages; /* Pages actually referenced */<br> int array_len; /* Space in the allocated lists */<br> int offset; /* Offset to start of valid data */<br> int length; /* Number of valid bytes of data */<br><br> /* Keep separate track of the physical addresses and page<br> * structs involved. If we do IO to a memory-mapped device<br> * region, there won't necessarily be page structs defined for<br> * every address. */<br><br> struct page ** maplist;<br><br> unsigned int locked : 1; /* If set, pages has been locked */<br> <br> /* Always embed enough struct pages for 64k of IO */<br> struct page * map_array[KIO_STATIC_PAGES];<br><br> /* Dynamic state for IO completion: */<br> atomic_t io_count; /* IOs still in progress */<br> int errno; /* Status of completed IO */<br> void (*end_io) (struct kiobuf *); /* Completion callback */<br> wait_queue_head_t wait_queue;<br>}<br><br>我们从raw设备使用kiobuf的流程走一下吧.然后就不具体分析各个函数了.<br>ssize_t <font color=#000066><b>rw_raw_dev</b></font>(int rw, struct file *filp, char *<font color=#3333ff><b>buf</b></font>, <br> size_t size, loff_t *offp)<br>{<br> struct kiobuf * iobuf;<br> .....<br> <br> /*<br> * First, a few checks on device size limits <br> */<br> .......<br><br> /* <br> * We'll just use one kiobuf<br> */<br><br> err = <font color=#006600><b>alloc_kiovec</b></font>(1, &iobuf);<font color=#3333ff> /*分配kiobuf*/</font><br> if (err)<br> return err;<br><br> /*<br> * Split the IO into KIO_MAX_SECTORS chunks, mapping and<br> * unmapping the single kiobuf as we go to perform each chunk of<br> * IO. <br> */<br> transferred = 0;<br> blocknr = *offp >> sector_bits;<br> while (size > 0) {<br> blocks = size >> sector_bits;<br> if (blocks > max_sectors) <font color=#3333ff>/*max_sectors:kiobuf一次最大64k*/</font><br> blocks = max_sectors;<br> if (blocks > limit - blocknr) <font color=#3333ff>/*limit是blkdev上最大编号的扇区*/</font><br> blocks = limit - blocknr;<br> if (!blocks)<br> break;<br><br> iosize = blocks << sector_bits;<br><br> err = <font color=#006600><b>map_user_kiobuf</b></font>(rw, iobuf, (unsigned long) buf, iosize);<br> <font color=#3333ff> /*以前分析过了:检查权限,将buf开始的长度为iosize涉及到的page调度到内存,并记录到kiobuf*/</font><br> if (err)<br> break;<br>....<br> for (i=0; i < blocks; i++) <br> b[i] = blocknr++;<br> <br> err = <font color=#006600><b>brw_kiovec</b></font>(rw, 1, &iobuf, dev, b, sector_size);<br> <font color=#3333ff>/*将记录下来的page,分割成buffer entry,启动io并等待其io操作完成*/</font><br> if (err >= 0) {<br> transferred += err;<br> size -= err;<br> buf += err;<br> }<br><br> <font color=#006600><b>unmap_kiobuf</b></font>(iobuf); /* The unlock_kiobuf is implicit here */<br> <font color=#3333ff>/*释放记录下来的page(一般情况下就是减少引用计数)*/</font><br> if (err != iosize)<br> break;<br> }<br> <br> <font color=#006600><b>free_kiovec</b></font>(1, &iobuf); <font color=#3333ff>/*释放kiobuf本身*/</font><br><br> if (transferred) {<br> *offp += transferred;<br> return transferred;<br> }<br> <br> return err;<br>}<br><br>具体的函数不再列出,分析buffer.c memory.c 的时候都有涉及. 这里的分析把以前的种种操作串起来,有个整体印象.<br></pre>
</td>
</tr>
</tbody>
</table>
</div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -