⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 046_fs_iobuf_c.html

📁 重读linux 2.4.2o所写的笔记
💻 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, &amp;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 &gt;&gt; sector_bits;<br>	while (size &gt; 0) {<br>		blocks = size &gt;&gt; sector_bits;<br>		if (blocks &gt; max_sectors) <font color=#3333ff>/*max_sectors:kiobuf一次最大64k*/</font><br>			blocks = max_sectors;<br>		if (blocks &gt; limit - blocknr) <font color=#3333ff>/*limit是blkdev上最大编号的扇区*/</font><br>			blocks = limit - blocknr;<br>		if (!blocks)<br>			break;<br><br>		iosize = blocks &lt;&lt; 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 &lt; blocks; i++) <br>			b[i] = blocknr++;<br>		<br>		err = <font color=#006600><b>brw_kiovec</b></font>(rw, 1, &amp;iobuf, dev, b, sector_size);<br>                <font color=#3333ff>/*将记录下来的page,分割成buffer entry,启动io并等待其io操作完成*/</font><br>		if (err &gt;= 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, &amp;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 + -