重读linux 2.4.2o所写的笔记

源代码在线查看: 046_fs_iobuf_c.html

软件大小: 521 K
上传用户: ilovexzhu
关键词: linux
下载地址: 免注册下载 普通下载 VIP

相关代码

				      												/* 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 */																				           
				  
				    
				    
				      
				        2008-1-3    kiobuf和raw设备的关系比较密切. raw设备十一个字符设备,单仅仅是字符设备而已.读写一个raw设备对应于一个block device.通过raw设备bind的块设备,使用另一种读写方式,没有copy to/form user的过程了,不像设备文件那样(block_dev.c). 其基本思路是把用户传进来的buf,强制调度到memory中,使之在读写的时候不会mm fault,同时收集这些页面的page的指针,并记录到kiobuf中. 然后,为每个page创建一个buffer entry,启动读写过程, 完成之后就可以释放kiobuf并返回了. 不在有copy过程了.   这些代码分布在iobuf.c buffer.c memory.c raw.c之中.但并不难理解.kiobuf本身注释很全面.struct kiobuf {	int		nr_pages;	/* Pages actually referenced */	int		array_len;	/* Space in the allocated lists */	int		offset;		/* Offset to start of valid data */	int		length;		/* Number of valid bytes of data */	/* Keep separate track of the physical addresses and page	 * structs involved.  If we do IO to a memory-mapped device	 * region, there won't necessarily be page structs defined for	 * every address. */	struct page **	maplist;	unsigned int	locked : 1;	/* If set, pages has been locked */		/* Always embed enough struct pages for 64k of IO */	struct page *	map_array[KIO_STATIC_PAGES];	/* Dynamic state for IO completion: */	atomic_t	io_count;	/* IOs still in progress */	int		errno;		/* Status of completed IO */	void		(*end_io) (struct kiobuf *); /* Completion callback */	wait_queue_head_t wait_queue;}我们从raw设备使用kiobuf的流程走一下吧.然后就不具体分析各个函数了.ssize_t	rw_raw_dev(int rw, struct file *filp, char *buf, 		   size_t size, loff_t *offp){	struct kiobuf * iobuf;	.....		/*	 * First, a few checks on device size limits 	 */        .......	/* 	 * We'll just use one kiobuf	 */	err = alloc_kiovec(1, &iobuf); /*分配kiobuf*/	if (err)		return err;	/*	 * Split the IO into KIO_MAX_SECTORS chunks, mapping and	 * unmapping the single kiobuf as we go to perform each chunk of	 * IO.  	 */	transferred = 0;	blocknr = *offp >> sector_bits;	while (size > 0) {		blocks = size >> sector_bits;		if (blocks > max_sectors) /*max_sectors:kiobuf一次最大64k*/			blocks = max_sectors;		if (blocks > limit - blocknr) /*limit是blkdev上最大编号的扇区*/			blocks = limit - blocknr;		if (!blocks)			break;		iosize = blocks << sector_bits;		err = map_user_kiobuf(rw, iobuf, (unsigned long) buf, iosize);                      /*以前分析过了:检查权限,将buf开始的长度为iosize涉及到的page调度到内存,并记录到kiobuf*/		if (err)			break;....		for (i=0; i < blocks; i++) 			b[i] = blocknr++;				err = brw_kiovec(rw, 1, &iobuf, dev, b, sector_size);                /*将记录下来的page,分割成buffer entry,启动io并等待其io操作完成*/		if (err >= 0) {			transferred += err;			size -= err;			buf += err;		}		unmap_kiobuf(iobuf); /* The unlock_kiobuf is implicit here */                /*释放记录下来的page(一般情况下就是减少引用计数)*/		if (err != iosize)			break;	}		free_kiovec(1, &iobuf); /*释放kiobuf本身*/	if (transferred) {		*offp += transferred;		return transferred;	}		return err;}具体的函数不再列出,分析buffer.c memory.c 的时候都有涉及. 这里的分析把以前的种种操作串起来,有个整体印象.
				      
				    
				    
				  
											

相关资源