/* 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 的时候都有涉及. 这里的分析把以前的种种操作串起来,有个整体印象.